【问题标题】:How to draw curves in circle in canvas using for loop?如何使用for循环在画布中绘制圆形曲线?
【发布时间】:2020-02-26 16:54:21
【问题描述】:

我想使用 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; },您将停止滚动

标签: javascript html for-loop canvas html5-canvas


【解决方案1】:

如果您需要重复一条曲线,那么最简单的方法是只定义一次,而不是自己计算所有新点,只需让画布移动即可。

将您的画布想象成一张可移动的纸。您可以使用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; }
&lt;canvas id="mycanvas"&gt;&lt;/canvas&gt;

【讨论】:

  • 感谢您的解决方案。
  • 有没有办法在这些曲线之间填充颜色?我试着上色,但整个画布都变黑了。 @kaiido
  • 当然,您需要对代码进行一些重构,这样您就不必在圆上循环两次,而是只旋转一次,然后在路径声明中绘制完整的形状:首先从中心向外,然后旋转你想要的厚度,将线描到新的外部位置,拉回到中心。 jsfiddle.net/9hzrobwc
猜你喜欢
  • 1970-01-01
  • 2019-09-16
  • 2013-05-13
  • 1970-01-01
  • 1970-01-01
  • 2014-04-29
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多