Udostępnij za pośrednictwem


Spin that graphic! Canvas rotate example

When I first wrote the reference docs for the canvas rotate method, I included a simple example. The problem was that it rotated an image from the upper left corner, not the center of the image. In answer to some feedback from a reader, I created a new and simplified example with a better graphic that rotates from the center. The main issue with using rotate() is to be sure your 0,0 origin is in the right place.

I've updated the reference content to talk about using the translate method to change the current origin on the canvas. The rotate method applies a rotation matrix to the canvas, using the current 0,0 position as the pivot point. To spin an object, you need to reorient the 0,0 point to the center of the object.

 

This example https://samples.msdn.microsoft.com/Workshop/samples/canvas/rotate.htm has several steps. Initially I set up a few global variables to get the canvas object and precalculate the center of the canvas.

The main part of the example is the draw function. I first use the translate method to move the 0,0 origin to the center of the canvas. Each time I redraw the canvas, I rotate the object by 1 degree. The rotate method accepts radians only, so I convert degrees with the formula radians = (degrees * Math.PI)/180;  I substitute a 1 for degrees in this algorithm, and pass it to the rotate method.

        // Translate our coordinates so 0,0 is in the center of the canvas
          ctx.translate(cW, cH);    

    // And rotate it 1 degree
          ctx.rotate((1 * Math.PI) / 180);

The rotating object is a five point star. The star is defined around an xy point that's set to 0,0 to match the origin I use for the rotate method. The star uses the lineTo method to draw lines from points plotted on two concentric circles. There are five points one radius for the tips of the star, and five at 1/2 that radius (inner part of the star).        

// Start shape, blue lines, yellow fill
          ctx.beginPath();                 

// Build the star hitting 10 points (11 to complete)
         for (var i = 11; i != 0; i--) {          
          var r = radius * (i % 2 + 1) / 2;  // Alternate between inside and outside points
      var curAngle = vertAngle * i;  // Calculate angle of the current point
          ctx.lineTo((r * Math.sin(curAngle)) + starCenter[0], (r * Math.cos(curAngle)) + starCenter[1]);
          }

I then set the strokeStyle, lineWidth, and fillStyle properties, and call the stroke and fill methods. This creates the star at the angle we wanted.

// Fill and stroke
          ctx.strokeStyle ="blue";
          ctx.lineWidth ="5"
          ctx.fillStyle ="yellow";
          ctx.stroke();
          ctx.fill();

 

Finally I reset the origin back to the upper left corner. This lets me call the draw() function again.

// Reset the translate so clearRect works correctly
          ctx.translate(-cW, -cH);

 

Now to rotate the star, we call the animate function. The animation is very simple. It first calls the draw() function to draw the graphic. Then, using the requestAnimationFrame method, it calls itself. The requestAnimationFrame method is an improvement over the traditional time slice method using setTimeout.

     animate(); // Start animating the star

// Animate calls the draw function every time the system lets it draw

function animate() {
     draw();

   // RequestAnimationFrame is a one shot function, needs to keep calling itself
      window.requestAnimationFrame(animate);
 }

 

That's pretty much it.