我希望我有时间调试这个问题&调查在写这个问题时出现的可能的答案,但我肯定会尽快这样做;)
关于我的实际问题:我试图沿着一个圆绘制曲线形状,但我不知道这是一个愚蠢的错误,还是因为需要象限处理而发出的叫喊( 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>
代码仍然是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>
话虽如此,我将尝试在我的一侧,但我打赌我必须做一些测试,然后才能弄清楚它(并知道为什么它会出错&如何修复它:)
祝所有S.O.的读者有一个非常美好和晴朗的日子;) +
-编辑--
一个快速的测试清楚了需要使用什么,但不清楚为什么它不工作-我希望它很快就会清楚( .currently它绘制五角图:/ ) ->我的问题实际上是关于什么(除了知道它在其他点上我的代码是错误的:
ctx.arc(100, 75, 50, (Math.PI*2/360)*<theAngle>, (Math.PI*2/360)*<theNextAngle>);
(是的,这对我来说是相当愚蠢的,但现在我知道^^ )
example attached below hosted on w3schools editor
下面的代码片段演示了它似乎“手动”地工作于笔划,但我还没有检查形状( ..)
<!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>
发布于 2017-05-29 23:55:37
您缺少的是函数ctx.arc的最后一个参数
ctx.arc(x,y,radius,startAngle, endAngle, direction);如果为true,则指示按逆时针方向绘制圆弧;如果为false,则按顺时针方向绘制。
因此,如果你从内弧线画到外弧线,你需要逆时针,然后顺时针。
例如
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++])
}<canvas id=canvas width= 400 height = 400></canvas>
发布于 2017-05-30 01:50:35
所以,正确的答案是..
(..)
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需要提醒的是,方向只是获得角度和方向的度数,而“诀窍”是在传递可选的nextAngle参数时记住切换参数顺序。因此,函数调用中需要的公式是:
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);使用笔划(),这将呈现:
<!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>
使用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>
谢谢大家,我希望这对其他人有帮助:)
https://stackoverflow.com/questions/44246209
复制相似问题