我希望我有时间调试这个&调查在撰写此问题时弹出的可能答案,但我确实会尽快这样做;)
根据我的实际问题: 我试图沿着圆圈绘制弯曲的形状,但是我无法弄清楚这是一个愚蠢的错误还是需要象限处理的呐喊(nb:我对那些人来说很陌生) ; p)
据我所知,代码似乎可以正常工作。对于单个形状来说很好,但是当从循环中运行以构建形状时它会变得混乱:/
适用于一种形状的代码(&可能只在此位置;))
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas2" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var graphValues = [1, 2, 3, 4, 5];
var c = document.getElementById("myCanvas2");
var ctx = c.getContext("2d");
// setup circle
// now onto drawing lines & stuff on a circle
var inner_radius = 20;
var radius = 80;
var point_size = 4;
var center_x = c.width/2;
var center_y = c.height/2;
var font_size = "20px";
// draw the circle
function drawCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, radius, 0, 2 * Math.PI);
ctx.stroke();
}
drawCircle();
// draw the inner circle
function drawInnerCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, inner_radius, 0, 2 * Math.PI);
ctx.stroke();
}
drawInnerCircle();
var horiStep360 = 360/graphValues.length-1; // way A
var step360 = 0;
// another helper to draw lines from the outer part of the circle to the center
function drawCurvedSection(angle){
var nextAngle = angle + horiStep360;
var innerCircle_start_x = center_x + inner_radius * Math.cos(-angle*Math.PI/180) * 1;
var innerCircle_start_y = center_y + inner_radius * Math.sin(-angle*Math.PI/180) * 1;
var innerCircle_end_x = center_x + inner_radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var innerCircle_end_y = center_y + inner_radius * Math.sin(-nextAngle*Math.PI/180) * 1;
var outerCircle_start_x = center_x + radius * Math.cos(-angle*Math.PI/180) * 1;
var outerCircle_start_y = center_y + radius * Math.sin(-angle*Math.PI/180) * 1;
var outerCircle_end_x = center_x + radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var outerCircle_end_y = center_y + radius * Math.sin(-nextAngle*Math.PI/180) * 1;
ctx.beginPath();
ctx.arc(center_x, center_y, inner_radius, angle, nextAngle);
ctx.arc(center_x, center_y, radius, angle, nextAngle);
ctx.closePath();
ctx.strokeStyle = 'blue';
ctx.stroke();
// TODO: fill with random/diff color
}
//step360 = 0; // reset before reuse
/*
graphValues.forEach(function(val){
//drawPoint( 180 - step360, 1, val); // way A reverse ( draw counterclockwise )
//drawPoint( step360, 1, val); // way A
drawCurvedSection(step360);
step360 += horiStep360;
});
*/
//drawCurvedSection(step360);
var nextAngle = step360 + horiStep360;
ctx.beginPath();
//ctx.arc(center_x, center_y, inner_radius, -step360, Math.PI-nextAngle); // PAIR A - original
ctx.arc(center_x, center_y, inner_radius, nextAngle*Math.PI/180, step360, true);
ctx.arc(center_x, center_y, radius, -step360, Math.PI-nextAngle); // PAIR A
// randomized color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
</script>
</body>
</html>
&#13;
仍然是wip的代码:/ ..
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas2" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var graphValues = [1, 2, 3, 4, 5];
var c = document.getElementById("myCanvas2");
var ctx = c.getContext("2d");
// setup circle
// now onto drawing lines & stuff on a circle
var inner_radius = 20;
var radius = 80;
var point_size = 4;
var center_x = c.width/2;
var center_y = c.height/2;
var font_size = "20px";
// draw the circle
function drawCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, radius, 0, 2 * Math.PI);
ctx.stroke();
}
drawCircle();
// draw the inner circle
function drawInnerCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, inner_radius, 0, 2 * Math.PI);
ctx.stroke();
}
drawInnerCircle();
var horiStep360 = 360/graphValues.length-1; // way A
var step360 = 0;
// another helper to draw lines from the outer part of the circle to the center
function drawCurvedSection(angle){
var nextAngle = angle + horiStep360;
/*
var innerCircle_start_x = center_x + inner_radius * Math.cos(-angle*Math.PI/180) * 1;
var innerCircle_start_y = center_y + inner_radius * Math.sin(-angle*Math.PI/180) * 1;
var innerCircle_end_x = center_x + inner_radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var innerCircle_end_y = center_y + inner_radius * Math.sin(-nextAngle*Math.PI/180) * 1;
var outerCircle_start_x = center_x + radius * Math.cos(-angle*Math.PI/180) * 1;
var outerCircle_start_y = center_y + radius * Math.sin(-angle*Math.PI/180) * 1;
var outerCircle_end_x = center_x + radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var outerCircle_end_y = center_y + radius * Math.sin(-nextAngle*Math.PI/180) * 1;
*/
ctx.beginPath();
/*
ctx.arc(center_x, center_y, inner_radius, angle, nextAngle);
ctx.arc(center_x, center_y, radius, angle, nextAngle);
*/
ctx.arc(center_x, center_y, inner_radius, -step360, -Math.PI-nextAngle, true); // false :/
ctx.arc(center_x, center_y, radius, -step360, Math.PI-nextAngle); // good ?
ctx.closePath();
//ctx.strokeStyle = 'blue';
//ctx.stroke();
// TODO: fill with random/diff color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
}
//step360 = 0; // reset before reuse
graphValues.forEach(function(val){
//drawPoint( 180 - step360, 1, val); // way A reverse ( draw counterclockwise )
//drawPoint( step360, 1, val); // way A
drawCurvedSection(step360);
step360 += horiStep360;
});
//drawCurvedSection(step360);
/*
var nextAngle = step360 + horiStep360;
ctx.beginPath();
//ctx.arc(center_x, center_y, inner_radius, -step360, Math.PI-nextAngle); // PAIR A - original
ctx.arc(center_x, center_y, inner_radius, nextAngle*Math.PI/180, step360, true);
ctx.arc(center_x, center_y, radius, -step360, Math.PI-nextAngle); // PAIR A
// randomized color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
*/
</script>
</body>
</html>
&#13;
话虽如此,我会尝试一下,但我敢打赌,在弄清楚之前我必须做一些测试(并知道它为什么会出现故障以及如何解决它:))
祝所有S.O.读者非常好看&amp;晴天 ;) +
- 编辑 -
快速测试清楚地说明需要使用什么但不知道为什么它不起作用 - 我希望它很快就会清楚(目前它会画出五角形:/) - &GT;我的问题实际上是什么(除了知道我的代码在其他一些方面是错误的:
ctx.arc(100, 75, 50, (Math.PI*2/360)*<theAngle>, (Math.PI*2/360)*<theNextAngle>);
(是的,那对我来说很愚蠢,但现在我知道^^)
example attached below hosted on w3schools editor
以下代码段表明它似乎可以正常工作&#34;对于抚摸,但我还没有检查形状(..)
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(100, 75, 50, (Math.PI*2/360)*0, (Math.PI*2/360)*72);
ctx.strokeStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.stroke();
ctx.beginPath();
ctx.arc(100, 75, 50, (Math.PI*2/360)*72, (Math.PI*2/360)*144);
ctx.strokeStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.stroke();
ctx.beginPath();
ctx.arc(100, 75, 50, (Math.PI*2/360)*144, (Math.PI*2/360)*216);
ctx.strokeStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.stroke();
ctx.beginPath();
ctx.arc(100, 75, 50, (Math.PI*2/360)*216, (Math.PI*2/360)*288);
ctx.strokeStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.stroke();
ctx.beginPath();
ctx.arc(100, 75, 50, (Math.PI*2/360)*288, (Math.PI*2/360)*360);
ctx.strokeStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.stroke();
</script>
</body>
</html>
&#13;
答案 0 :(得分:0)
你缺少的是函数ctx.arc
的最后一个参数ctx.arc(x,y,radius,startAngle, endAngle, direction);
方向如果为true则告诉弧线逆时针绘制,否则顺时针方向错误绘制。
因此,如果你从内弧到外面画,你需要逆时针然后顺时针方向。
例如
const ctx = canvas.getContext("2d");
const cols = [
"hsl(0,100%,50%)",
"hsl(40,100%,50%)",
"hsl(70,100%,50%)",
"hsl(100,100%,50%)",
"hsl(150,100%,50%)",
"hsl(250,100%,50%)",
];
var startAng = 0;
var endAng = 1;
var innerRad = 50;
var outerRad = 100;
ctx.lineWidth = 3;
ctx.lineJoin = "round";
ctx.strokeStyle = "black";
function drawSlice(x,y,start,end,innerRad,outerRad,col){
ctx.fillStyle = col;
ctx.beginPath();
ctx.arc(x,y,innerRad,end,start,true);
ctx.arc(x,y,outerRad,start,end,false);
ctx.closePath(); // to close path for stroke command
ctx.fill();
ctx.stroke();
}
var count = 0;
for(var i = 0; count < cols.length; i += 1){
drawSlice(200,200,i,i+0.9,innerRad,outerRad,cols[count++])
}
&#13;
<canvas id=canvas width= 400 height = 400></canvas>
&#13;
答案 1 :(得分:0)
所以,正确答案是......
(..)
ctx.arc(center_x, center_y, inner_radius, (Math.PI*2/360)*nextAngle, (Math.PI*2/360)*angle, true);
ctx.arc(center_x, center_y, radius, (Math.PI*2/360)*angle, (Math.PI*2/360)*nextAngle, false);
(..)
- 编辑 -
为了更清楚地澄清,我忘记在使用它们之前将度数转换为弧度:/
var deg = angle; // angle in °
var rads = Math.PI/180*deg; // simpler yet same as (Math.PI*2/360)*deg
提醒一下,(Math.PI*2/360)*angleDegree
只是获得角度和角度的度数。下一个角色,而诀窍&#39;是记住在传递可选方向参数时切换参数顺序。
因此,函数调用中所需的公式为:
ctx.arc(x, y, rad, (Math.PI*2/360)*2ndAngle, (Math.PI*2/360)*1stangle, true);
ctx.arc(x, y, outRad, (Math.PI*2/360)*1stangle, (Math.PI*2/360)*2ndAngle, false);
使用stroke(),这将呈现:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas2" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var graphValues = [1, 2, 3, 4, 5];
var c = document.getElementById("myCanvas2");
var ctx = c.getContext("2d");
// setup circle
// now onto drawing lines & stuff on a circle
var inner_radius = 20;
var radius = 80;
var point_size = 4;
var center_x = c.width/2;
var center_y = c.height/2;
var font_size = "20px";
// draw the circle
function drawCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, radius, 0, 2 * Math.PI);
ctx.stroke();
}
//drawCircle();
// draw the inner circle
function drawInnerCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, inner_radius, 0, 2 * Math.PI);
ctx.stroke();
}
//drawInnerCircle();
//var horiStep360 = 360/graphValues.length-1; // made it work when testing single one ?!
var horiStep360 = 360/graphValues.length; // to gett ful 36° per item
// for 5 values:
// 0° -> 72°
// 72° -> 144°
// 144° -> 216°
// 216° -> 288°
// 288° -> 360°
var step360 = 0;
// another helper to draw lines from the outer part of the circle to the center
function drawCurvedSection(angle){
var nextAngle = angle + horiStep360;
console.log('current angle: ' + angle + '° & next angle: ' + nextAngle + '°');
/*
var innerCircle_start_x = center_x + inner_radius * Math.cos(-angle*Math.PI/180) * 1;
var innerCircle_start_y = center_y + inner_radius * Math.sin(-angle*Math.PI/180) * 1;
var innerCircle_end_x = center_x + inner_radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var innerCircle_end_y = center_y + inner_radius * Math.sin(-nextAngle*Math.PI/180) * 1;
var outerCircle_start_x = center_x + radius * Math.cos(-angle*Math.PI/180) * 1;
var outerCircle_start_y = center_y + radius * Math.sin(-angle*Math.PI/180) * 1;
var outerCircle_end_x = center_x + radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var outerCircle_end_y = center_y + radius * Math.sin(-nextAngle*Math.PI/180) * 1;
*/
ctx.beginPath();
//ctx.arc(center_x, center_y, inner_radius, angle, nextAngle);
//ctx.arc(center_x, center_y, radius, angle, nextAngle);
//ctx.arc(center_x, center_y, inner_radius, -step360, -Math.PI-nextAngle, true); // false
//ctx.arc(center_x, center_y, radius, -step360, Math.PI-nextAngle); // good ?
//ctx.arc(center_x, center_y, inner_radius, -angle, -nextAngle, true); // false
//ctx.arc(center_x, center_y, radius, -angle, -nextAngle); // good ?
// debug
//ctx.arc(center_x, center_y, inner_radius, angle*Math.PI*2/180, nextAngle*Math.PI*2/180, true);
//ctx.arc(center_x, center_y, radius, angle*Math.PI*2/180, nextAngle*Math.PI*2/180, false);
// R: invert the angle & nextAngle AS WELL AS set optional direction parameter !!! -> WORKS !!!!
ctx.arc(center_x, center_y, inner_radius, (Math.PI*2/360)*nextAngle, (Math.PI*2/360)*angle, true);
ctx.arc(center_x, center_y, radius, (Math.PI*2/360)*angle, (Math.PI*2/360)*nextAngle, false);
ctx.closePath();
//ctx.strokeStyle = 'blue';
ctx.strokeStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.stroke();
// TODO: fill with random/diff color
//ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
//ctx.fill();
}
//step360 = 0; // reset before reuse
graphValues.forEach(function(val){
//drawPoint( 180 - step360, 1, val); // way A reverse ( draw counterclockwise )
//drawPoint( step360, 1, val); // way A
drawCurvedSection(step360);
step360 += horiStep360;
});
//drawCurvedSection(step360); - to be called manually to step through & see where/why glitch begins
function debugDrawCurvedSection(){
drawCurvedSection(step360);
step360 += horiStep360;
}
//debugDrawCurvedSection(); // ok ..
//debugDrawCurvedSection(); // fucked up
//debugDrawCurvedSection();
/*
var nextAngle = step360 + horiStep360;
ctx.beginPath();
//ctx.arc(center_x, center_y, inner_radius, -step360, Math.PI-nextAngle); // PAIR A - original
ctx.arc(center_x, center_y, inner_radius, nextAngle*Math.PI/180, step360, true);
ctx.arc(center_x, center_y, radius, -step360, Math.PI-nextAngle); // PAIR A
// randomized color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
*/
// manual tests
/*
ctx.beginPath();
ctx.arc(center_x, center_y, inner_radius, 0, 2, true);
ctx.arc(center_x, center_y, radius, 0, 2, false);
// randomized color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
*/
</script>
</body>
</html>
&#13;
使用fill(),这将呈现:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas2" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var graphValues = [1, 2, 3, 4, 5];
var c = document.getElementById("myCanvas2");
var ctx = c.getContext("2d");
// setup circle
// now onto drawing lines & stuff on a circle
var inner_radius = 20;
var radius = 80;
var point_size = 4;
var center_x = c.width/2;
var center_y = c.height/2;
var font_size = "20px";
// draw the circle
function drawCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, radius, 0, 2 * Math.PI);
ctx.stroke();
}
//drawCircle();
// draw the inner circle
function drawInnerCircle(){
ctx.beginPath();
ctx.arc(center_x, center_y, inner_radius, 0, 2 * Math.PI);
ctx.stroke();
}
//drawInnerCircle();
//var horiStep360 = 360/graphValues.length-1; // made it work when testing single one ?!
var horiStep360 = 360/graphValues.length; // to gett ful 36° per item
// for 5 values:
// 0° -> 72°
// 72° -> 144°
// 144° -> 216°
// 216° -> 288°
// 288° -> 360°
var step360 = 0;
// another helper to draw lines from the outer part of the circle to the center
function drawCurvedSection(angle){
var nextAngle = angle + horiStep360;
console.log('current angle: ' + angle + '° & next angle: ' + nextAngle + '°');
/*
var innerCircle_start_x = center_x + inner_radius * Math.cos(-angle*Math.PI/180) * 1;
var innerCircle_start_y = center_y + inner_radius * Math.sin(-angle*Math.PI/180) * 1;
var innerCircle_end_x = center_x + inner_radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var innerCircle_end_y = center_y + inner_radius * Math.sin(-nextAngle*Math.PI/180) * 1;
var outerCircle_start_x = center_x + radius * Math.cos(-angle*Math.PI/180) * 1;
var outerCircle_start_y = center_y + radius * Math.sin(-angle*Math.PI/180) * 1;
var outerCircle_end_x = center_x + radius * Math.cos(-nextAngle*Math.PI/180) * 1;
var outerCircle_end_y = center_y + radius * Math.sin(-nextAngle*Math.PI/180) * 1;
*/
ctx.beginPath();
//ctx.arc(center_x, center_y, inner_radius, angle, nextAngle);
//ctx.arc(center_x, center_y, radius, angle, nextAngle);
//ctx.arc(center_x, center_y, inner_radius, -step360, -Math.PI-nextAngle, true); // false
//ctx.arc(center_x, center_y, radius, -step360, Math.PI-nextAngle); // good ?
//ctx.arc(center_x, center_y, inner_radius, -angle, -nextAngle, true); // false
//ctx.arc(center_x, center_y, radius, -angle, -nextAngle); // good ?
// debug
//ctx.arc(center_x, center_y, inner_radius, angle*Math.PI*2/180, nextAngle*Math.PI*2/180, true);
//ctx.arc(center_x, center_y, radius, angle*Math.PI*2/180, nextAngle*Math.PI*2/180, false);
// R: invert the angle & nextAngle AS WELL AS set optional direction parameter !!! -> WORKS !!!!
ctx.arc(center_x, center_y, inner_radius, (Math.PI*2/360)*nextAngle, (Math.PI*2/360)*angle, true);
ctx.arc(center_x, center_y, radius, (Math.PI*2/360)*angle, (Math.PI*2/360)*nextAngle, false);
ctx.closePath();
//ctx.strokeStyle = 'blue';
//ctx.strokeStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
//ctx.stroke();
// TODO: fill with random/diff color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
}
//step360 = 0; // reset before reuse
graphValues.forEach(function(val){
//drawPoint( 180 - step360, 1, val); // way A reverse ( draw counterclockwise )
//drawPoint( step360, 1, val); // way A
drawCurvedSection(step360);
step360 += horiStep360;
});
//drawCurvedSection(step360); - to be called manually to step through & see where/why glitch begins
function debugDrawCurvedSection(){
drawCurvedSection(step360);
step360 += horiStep360;
}
//debugDrawCurvedSection(); // ok ..
//debugDrawCurvedSection(); // fucked up
//debugDrawCurvedSection();
/*
var nextAngle = step360 + horiStep360;
ctx.beginPath();
//ctx.arc(center_x, center_y, inner_radius, -step360, Math.PI-nextAngle); // PAIR A - original
ctx.arc(center_x, center_y, inner_radius, nextAngle*Math.PI/180, step360, true);
ctx.arc(center_x, center_y, radius, -step360, Math.PI-nextAngle); // PAIR A
// randomized color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
*/
// manual tests
/*
ctx.beginPath();
ctx.arc(center_x, center_y, inner_radius, 0, 2, true);
ctx.arc(center_x, center_y, radius, 0, 2, false);
// randomized color
ctx.fillStyle = '#' + ("000000" + Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
ctx.fill();
*/
</script>
</body>
</html>
&#13;
谢谢大家,我希望这有助于其他人:)