简体   繁体   中英

Drawing a spiral on an HTML canvas using JavaScript

I have searched and haven't found anything really on how to draw spirals in canvas using JavaScript.

I thought it might be possible to do it with the bezier curve and if that didn't work use lineTo() , but that seemed a lot harder.

Also, to do that I'm guessing I would have to use trigonometry and graphing with polar coordinates and its been a while since I did that. If that is the case could you point me in the right direction on the math.

The Archimedean spiral is expressed as r=a+b(angle) . Convert that into x, y coordinate, it will be expressed as x=(a+b*angle)*cos(angle) , y=(a+b*angle)*sin(angle) . Then you can put angle in a for loop and do something like this:

for (i=0; i< 720; i++) {
  angle = 0.1 * i;
  x=(1+angle)*Math.cos(angle);
  y=(1+angle)*Math.sin(angle);
  context.lineTo(x, y);
}

Note the above assumes a = 1 and b = 1.

Here is a jsfiddle link: http://jsfiddle.net/jingshaochen/xJc7M/

This is a slightly-changed, javascript-ified version of a Java spiral I once borrowed from here

It uses lineTo() and its not all that hard.

<!DOCTYPE HTML>
<html><body>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #c3c3c3;"></canvas>
<script type="text/javascript">
    var c=document.getElementById("myCanvas");
    var cxt=c.getContext("2d");
    var centerX = 150;
    var centerY = 150;
    cxt.moveTo(centerX, centerY);

    var STEPS_PER_ROTATION = 60;
    var increment = 2*Math.PI/STEPS_PER_ROTATION;       
    var theta = increment;

    while( theta < 40*Math.PI) {
      var newX = centerX + theta * Math.cos(theta); 
      var newY = centerY + theta * Math.sin(theta); 
      cxt.lineTo(newX, newY);
      theta = theta + increment;
    }
    cxt.stroke();
</script></body></html>

Here's a function I wrote for drawing Archimedean spirals :

CanvasRenderingContext2D.prototype.drawArchimedeanSpiral =
    CanvasRenderingContext2D.prototype.drawArchimedeanSpiral ||
        function(centerX, centerY, stepCount, loopCount,
                 innerDistance, loopSpacing, rotation)
        {
            this.beginPath();

            var stepSize = 2 * Math.PI / stepCount,
                endAngle = 2 * Math.PI * loopCount,
                finished = false;

            for (var angle = 0; !finished; angle += stepSize) {
                // Ensure that the spiral finishes at the correct place,
                // avoiding any drift introduced by cumulative errors from
                // repeatedly adding floating point numbers.
                if (angle > endAngle) {
                    angle = endAngle;
                    finished = true;
                }

                var scalar = innerDistance + loopSpacing * angle,
                    rotatedAngle = angle + rotation,
                    x = centerX + scalar * Math.cos(rotatedAngle),
                    y = centerY + scalar * Math.sin(rotatedAngle);

                this.lineTo(x, y);
            }

            this.stroke();
        }

this is example of drawing spiral using function below:

spiral(ctx, {
  start: {//starting point of spiral
    x: 200, 
    y: 200
  },
  angle: 30 * (Math.PI / 180), //angle from starting point
  direction: false,
  radius: 100, //radius from starting point in direction of angle
  number: 3 // number of circles
});

spiral drawing code:

spiral = function(ctx,obj) {
  var center, eAngle, increment, newX, newY, progress, sAngle, tempTheta, theta;
  sAngle = Math.PI + obj.angle;
  eAngle = sAngle + Math.PI * 2 * obj.number;
  center = {
    x: obj.start.x + Math.cos(obj.angle) * obj.radius,
    y: obj.start.y + Math.sin(obj.angle) * obj.radius
  };
  increment = 2 * Math.PI / 60/*steps per rotation*/;
  theta = sAngle;
  ctx.beginPath();
  ctx.moveTo(center.x, center.y);
  while (theta <= eAngle + increment) {
    progress = (theta - sAngle) / (eAngle - sAngle);
    tempTheta = obj.direction ? theta : -1 * (theta - 2 * obj.angle);
    newX = obj.radius * Math.cos(tempTheta) * progress;
    newY = obj.radius * Math.sin(tempTheta) * progress;
    theta += increment;
    ctx.lineTo(center.x + newX, center.y + newY);
  }
  ctx.stroke();
};

there is a fine free tool that will help if you have illustrator ai2canvas

it will create all the curves to javascript in html canvas tag for you!

(if you are looking for archmedes spiral than you will first have to get it from coreldraw and copy that to illustrator, because the default spiral tool enlarges the angle with each point)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM