【问题标题】:image and canvas rotation图像和画布旋转
【发布时间】:2016-11-18 15:33:34
【问题描述】:

我正在尝试旋转图像并使用箭头键在画布上移动它。计划是让左右键控制图像的旋转,上下键控制移动——有点像坦克!

我可以成功地围绕中心点旋转图像并将其放回画布中应位于的位置,但是一旦将其旋转 45 度,我希望向上键将其向右移动,旋转 180 度和向上键将其在画布下移动等。目前,我可以使用左/右键旋转图像,但上/下键始终在画布上/下。

我是否需要将画布坐标旋转与图像相同的量?

这是我目前所拥有的,并且在我的绘图功能中......

ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.translate(T1.x + base_image.width/2, T1.y + base_image.height/2);

ctx.rotate(rotation * Math.PI/180);

ctx.translate(-(T1.x + base_image.width/2), -(T1.y + base_image.height/2));
ctx.drawImage(base_image, T1.x, T1.y);

ctx.stroke();
ctx.restore()

T1.xT1.y 是图像的 x 和 y 坐标。

谢谢!

【问题讨论】:

  • 我不知道这是否是您要找的东西,但不久前我破解了示例,我这样做了:codepen.io/Zack_90/pen/amJvkJ?editors=1010
  • 谢谢,但遗憾的是没有。我需要向上按钮来随图像一起旋转。

标签: javascript html5-canvas


【解决方案1】:

终于明白了!解决方案是将旋转和移动分开,而不是尝试全部使用ctx.translate

在我每 100 Hz 调用一次的绘图函数中:

ctx.save();
ctx.translate(T1.x + base_image.width/2, T1.y + base_image.height/2);
ctx.rotate(rotation*Math.PI/180);
ctx.drawImage(base_image, -base_image.width/2, -base_image.height/2);
ctx.restore();
ctx.stroke();

左键例如是:

rotation = rotation - 5;
Draw();

向上键例如是:

var radians = (rotation*Math.PI/180)
T1.x += 4*Math.cos(radians);
T1.y += 4*Math.sin(radians);
Draw();

注意:为此,我必须将绘图中图像的默认方向更改 45 度。

【讨论】:

    【解决方案2】:

    在 Edge、Chrome 和 Firefox 上绘制旋转、均匀缩放的图像的最快方法是

    // When the image has loaded add the center offsets
    image.onload = function(){
       // … your code 
       this.centerX = -this.width/2;
       this.centerY = -this.height/2;
    }
    
    // When rendering
    // x,y position of image center
    // scale the uniform scale
    // rotate angle in radians starting at 0 and + clockwise
    var xdx = Math.cos(rotate) * scale;
    var xdy = Math.sin(rotate) * scale;
    ctx.setTransform(xdx, xdy, -xdy, xdx, x, y);
    ctx.drawImage(image,image.centerX,image.centerY)
    

    上面的方法加上额外的 sin 和 cos 以及两个乘法在 Chrome 上明显更快,在 Firefox 上稍微快一些,我忘记了 Edge 上的边距,但它比下一个最快的方法更快:

    ctx.setTransform(scale, 0, 0, scale, x, y);
    ctx.rotate(rotate);
    ctx.drawImage(image, image.centerX, image.centerY);
    

    虽然我将保留画布变换状态,但您可以继续使用这两种方法,而无需重置画布状态。完成所有渲染后,要恢复当前变换,请使用

    ctx.setTransform(1, 0, 0, 1, 0, 0);     
    

    为了节省一点时间,每次将度数转换为弧度时,请创建一个const DEG2RAD = Math.PI/180;。然后,您可以使用var radians = degrees*DEG2RAD; 进行转换或输入const D2R = Math.PI/180; 或致电const oneDeg = Math.PI/180; 进行保存。

    【讨论】:

      猜你喜欢
      • 2015-10-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 2017-09-26
      相关资源
      最近更新 更多