如何使用for循环在画布上绘制圆形中的曲线?

3
我想使用for循环在圆圈中绘制贝塞尔曲线。 目前,我已经能够将贝塞尔曲线放置在圆形模式下,但这些曲线不是曲线,它们只是直线,因为我无法正确更改控制杆,使这些曲线成为曲线。您可以在此处查看我的代码,请让我知道我的错误。
我还尝试将颜色填充到曲线中,但这也没有发生,我不知道原因。

<html>
    <body>
        <style>
            *{
                margin: 0px;
            }
            body{
                background-color: aqua;
            }
            canvas
            {
                background-color: white;
            }
        </style>
        <canvas id="mycanvas"></canvas>
        <script>
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
x = window.innerWidth/2;
y = window.innerHeight/2;
r = window.innerWidth;
theta = 0.1;

for(theta=0.1; theta<12.6; theta+=0.1) {
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.bezierCurveTo(x,y,x,y, x+ r * Math.cos(theta),y + r * Math.sin(theta));
    ctx.lineWidth = 1;
    ctx.strokeStyle = "black";
    ctx.stroke();
    ctx.closePath();
    ctx.fill();
}
            
for ( i=r/16; i < r; i=i+r/12 ) {
    ctx.beginPath();
    ctx.arc(x, y, i, 0, 2 * Math.PI, false);
    ctx.stroke();
}  

                
    
        </script>
    </body>
</html>


请注意:如果您设置 canvas { display: block; },您将不再获得那个小滚动条。 - gman
1个回答

0
如果您需要重复单个曲线,则最简单的方法是仅定义一次,而不是自己计算所有新点,只需使您的画布移动即可。
将您的画布视为可移动的纸张。您可以使用ctx.setTransformctx.rotatectx.translate等来“移动”这个画布,同时保持您的笔在同一位置。
这样,您可以定义一次路径,并在不同位置多次绘制它:

var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');

const angle = 0.1; // by which amount we rotate at each iteration

function draw() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  const cx = window.innerWidth/2;
  const cy = window.innerHeight/2;
  const rad = Math.max(cx, cy) * 2;
  // controls the position of all the control points,
  // you might want to set each manually instead
  const binding = rad/Math.PI;
  let theta = 0;

  // we move our canvas so its center is now coordinates 0,0
  ctx.setTransform(1, 0, 0, 1, cx, cy);
  // a single path declaration
  ctx.beginPath();
  for( theta; theta < Math.PI*4; theta += angle ) {
    ctx.rotate(angle); // apply the rotation
    ctx.moveTo(0, 0); // current center
    // always the same parameters for the bezier curve
    ctx.bezierCurveTo(0, -binding, rad, -binding, rad, 0);
  }
  // even these can be part of the same single path
  for ( i=rad/8; i < rad; i += rad/8 ) {
    ctx.moveTo(i, 0); // to avoid the segment from center
    ctx.arc(0, 0, i, 0, 2 * Math.PI, false);
  }
  // a single stroke of the whole path
  ctx.stroke();
  
  // to reset the coordinate 0,0 at top left corner
  ctx.setTransform(1,0,0,1,0,0);
}

draw();
onresize = draw;
root,body { background: white; margin: 0 }
canvas { display: block; }
<canvas id="mycanvas"></canvas>


感谢您的解决方案。 - user12956011
有没有办法在这些曲线之间填充颜色?我试图上色,但整个画布变黑了。@kaiido - user12956011
当然,您需要对代码进行一些重构,以便不再循环两次圆形,而是只旋转一次,然后在路径声明中绘制完整的形状:首先从中心到外部绘制曲线,然后旋转所需的厚度,跟踪到新的外部位置,返回到中心。 https://jsfiddle.net/9hzrobwc/ - Kaiido

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接