How to rotate a canvas by following mouse if the canvas already has something drawn on it

Viewed 2101

I currently have a canvas that has an element drawn on it that I draw using a custom function and the onload function I would like to know how to be able to rotate this canvas around by following the mouse 360 degrees like turning a wheel. The code is as follows

<!DOCTYPE html>
<html>
    
    <head>
        <title>Help</title>   
    </head>
    <body>
       
        <canvas id="MyCanvas" width="500" height="500"></canvas>
        <script>
            var ctx = document.getElementById("MyCanvas").getContext("2d");
                ctx.translate(250,250);
            function draw(){  
                ctx.arc(0,0,100,0,Math.PI*2,false);  // x, y, radius, start angle, end angle, false/true  
                ctx.stroke();
                ctx.beginPath();
                ctx.moveTo(-100,0);
                ctx.lineTo(100,0);
                ctx.moveTo(100,0);
                ctx.lineTo(60,-80);
                ctx.moveTo(60,-80);
                ctx.lineTo(-100,0);
                ctx.stroke();
            } 
            window.onload=draw;
        </script>
        
    </body>
</html>

Does anyone know how this would be possible I have tried multiple different functions. however, they do not seem to be able to do anything. help will be very appreciated.

Edited but with slight issue

<!DOCTYPE html>
<html>
    
    <head>
        <title>Help</title>   
    </head>
    
    <style>
    canvas{
         border: 2px solid black;
        }
    </style>
    
    <body>
       
        <canvas id="Canvas" height="300"></canvas>
        
        <script>
            const ctx = canvas.getContext("2d");
            
            const mouse = { x: 0, y: 0 };
            function mouseEvents(e) {
              const bounds = canvas.getBoundingClientRect();
              mouse.x = e.pageX - bounds.left - scrollX;
              mouse.y = e.pageY - bounds.top - scrollY;
            }
            document.addEventListener("mousemove", mouseEvents);

            
            function drawRotated(x, y, angle) {
              ctx.setTransform(1, 0, 0, 1, x, y);
              ctx.rotate(angle);
              ctx.beginPath();
              ctx.arc(0, 0, 100, 0, Math.PI * 2);
              ctx.moveTo(-100, 0);
              ctx.lineTo(100, 0);
              ctx.lineTo(60, -80);
              ctx.closePath();
              ctx.stroke();
            }

            
            function update(timer) {
              ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transform
              ctx.clearRect(0, 0, 300, 300);

              
              var angle = Math.atan2(mouse.y - 150, mouse.x - 150);

              
              drawRotated(150, 150, angle);
              requestAnimationFrame(update);
            }
            requestAnimationFrame(update);
        </script>
        
    </body>
</html>

1 Answers

You need to create a mouse move listener, and an animation loop.

In the animation loop get the mouse position and use Math.atan2( to get the direction from the center canvas to the mouse.

Then set the transform with ctx.setTransform to scale and position the designs rotation center, and then use ctx.rotate to rotate the transform to point along the angle computed.

See snippet for more details

const ctx = canvas.getContext("2d");
// create mouse event listener
const mouse = { x: 0, y: 0 };
function mouseEvents(e) {
  const bounds = canvas.getBoundingClientRect();
  mouse.x = e.pageX - bounds.left - scrollX;
  mouse.y = e.pageY - bounds.top - scrollY;
}
document.addEventListener("mousemove", mouseEvents);

// draw design at x,y and rotated by angle
function drawRotated(x, y, angle) {
  ctx.setTransform(1, 0, 0, 1, x, y);
  ctx.rotate(angle);
  ctx.beginPath();
  ctx.arc(0, 0, 100, 0, Math.PI * 2);
  ctx.moveTo(-100, 0);
  ctx.lineTo(100, 0);
  ctx.lineTo(60, -80);
  ctx.closePath();
  ctx.stroke();
}

// render loop called 60 times a second
function update(timer) {
  ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transform
  ctx.clearRect(0, 0, 300, 300);

  // get angle from center to mouse
  var angle = Math.atan2(mouse.y - 150, mouse.x - 150);

  // draw rotated design
  drawRotated(150, 150, angle);
  requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas {
  border: 2px solid black;
}
<canvas id="canvas" height=300></canvas>

Related