javascript 在画布元素中旋转和移动图像?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4697041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 14:33:56  来源:igfitidea点击:

Rotating and moving an image in a canvas element?

javascripthtmlanimationcanvas

提问by mshafrir

I would like to move and rotate an image of a ball in a element. The ball is 68x68 and the canvas is 300x200. The ball moves along the x and y axis, flipping its x and y velocity when it hits a wall - all of this works. I just can't figure how to do rotation on top of the movement.

我想在元素中移动和旋转球的图像。球为 68x68,画布为 300x200。球沿着 x 和 y 轴移动,当它撞到墙上时会翻转它的 x 和 y 速度 - 所有这些都有效。我只是不知道如何在运动的顶部进行旋转。

My draw() function, which I call through window.setInterval every 30ms, looks something like this:

我每 30 毫秒通过 window.setInterval 调用一次 draw() 函数,看起来像这样:

  var draw = function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.save();
    ctx.rotate(ball_radians);
    ctx.drawImage(ball_img, x, y);
    ctx.restore();

    // calculate new x, y, and ball_radians
  }

This makes the ball fly around the screen, so clearly I'm doing something wrong. What am I missing?

这使得球在屏幕上飞来飞去,很明显我做错了什么。我错过了什么?

回答by Phrogz

  1. Translate the context to the point on the canvas that the object should rotate about.
  2. Rotate the context.
  3. Either:
    • Translate the context by the negative offset within the object for the center of rotation, and then draw the object at 0,0, or
    • Draw the image using the negative offset within the object for the center of rotation.
  1. 将上下文转换为画布上对象应围绕其旋转的点。
  2. 旋转上下文。
  3. 任何一个:
    • 通过旋转中心的对象内的负偏移量平移上下文,然后在 处绘制对象0,0,或
    • 使用对象内的负偏移作为旋转中心绘制图像。

e.g.

例如

ctx.save();
ctx.translate( canvasLocX, canvasLocY );
ctx.rotate( ballRotationInRadians );
ctx.drawImage( ball_img, -ballCenterX, -ballCenterY );
ctx.restore();

Note that if you need absolute speed, instead of saving and restoring the canvas (handling many properties that you didn't change) you can just undo your work:

请注意,如果您需要绝对速度,而不是保存和恢复画布(处理许多您没有更改的属性),您只需撤消您的工作:

ctx.translate( canvasLocX, canvasLocY );
ctx.rotate( ballRotationInRadians );
ctx.drawImage( ball_img, -ballCenterX, -ballCenterY );
ctx.rotate( -ballRotationInRadians );
ctx.translate( -canvasLocX, -canvasLocY );

The previous bit of premature optimization has been blindly parroted from someone else; I have not personally benchmarked to verify that it is correct.

之前的一些过早优化是别人盲目模仿的;我没有亲自进行基准测试来验证它是否正确。

Edit: I've added a mocked up working example of this here: http://phrogz.net/tmp/canvas_beachball.html

编辑:我在这里添加了一个模拟的工作示例:http: //phrogz.net/tmp/canvas_beachball.html