如果画布上已经有绘制内容,如何根据鼠标旋转画布?

3

我目前有一个画布,上面有一个元素,我使用自定义函数和onload函数进行绘制。我想知道如何通过跟随鼠标360度旋转这个画布,就像转动车轮一样。代码如下:

<!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>

有人知道如何做到这一点吗?我尝试了多个不同的函数,但它们似乎都无法实现任何功能。非常感谢您的帮助。

编辑过,但有轻微问题。

<!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
你尝试过什么?你遇到了哪些错误或问题? - John Ellmore
1
可能是如何旋转HTML5画布的现有内容?的重复问题。 - Koby Douek
1
我尝试设置一些简单的东西,比如循环来在点击时旋转画布等,但似乎 onclick 没有被注册,因为当我尝试时它没有做任何事情。 - Cormanno
@JohnEllmore 我也尝试过将其保存为图像然后旋转,但仍然无效。 - Cormanno
1个回答

2

您需要创建一个鼠标移动监听器和一个动画循环。

在动画循环中获取鼠标位置,并使用Math.atan2(来获取从中心画布到鼠标的方向。

然后使用ctx.setTransform设置变换以缩放和定位设计的旋转中心,然后使用ctx.rotate将变换旋转以沿计算出的角度指向。

有关更多详细信息,请参见代码片段。

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>


非常感谢,但只有一个问题。当我尝试实现代码时,似乎我得到了带边框的画布,但里面什么也没有。 - Cormanno
我已经将我的代码片段添加了进去,你能告诉我实现代码的问题在哪里吗? - Cormanno
没事了,原来只是我的类命名问题。再次非常感谢你。 - Cormanno

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