具有变焦和旋转的视差效果

时间:2013-12-23 16:45:12

标签: javascript html5 html5-canvas game-engine parallax

我目前正在试验我计划实施到我的HTML5-canvas游戏引擎的视差效果。 效果本身很容易实现,但是当你添加缩放和旋转时,事情变得有点复杂,至少对我而言。我的目标是实现这样的目标:Youtube video.

如您所见,您可以放大和缩小中心",并围绕它旋转并获得视差效果。

在我的引擎中,我希望有多个画布将成为我的视差图层,我将翻译它们。 我想出了类似的东西:

var parallax = {
    target: {
        x: Mouse.x,
        y: Mouse.y
    },
    offset: {
        x: -ctx.width / 2,
        y: -ctx.height / 2
    },
    factor: {
        x: 1,
        y: 1
    }
}

var angle = 0;
var zoomX = 1;
var zoomY = 1;

var loop = function(){
    ctx.canvas.width = ctx.canvas.width; //Clear the canvas.

    ctx.translate(parallax.target.x * parallax.factor.x, parallax.target.y * parallax.factor.y);
    ctx.rotate(angle);
    ctx.scale(zoomX, zoomY);
    ctx.translate((-parallax.target.x - parallax.offset.x) * parallax.factor.x, (-parallax.target.y - parallax.offset.y) * parallax.factor.y);

    Draw(); //Function that draws all the objects on the screen.
}

这是我脚本中非常小而简化的部分,但我希望能够完成我正在做的事情。对象" parallax"包含目标位置,偏移量(距目标的距离)以及决定画布相对于目标移动速度的因素。 ctx是在目标的相反方向上移动的画布。(在这个例子中,我只使用一个图层。)我使用鼠标作为"目标",但我也可以使用播放器,或具有x和y属性的其他一些对象。目标也是我旋转和缩放画布的点。

只要因子等于1,此方法就可以正常工作。如果是其他内容,整个事情突然停止正常工作,当我尝试缩放时,它会缩放到左上角,而不是目标。我还注意到,如果我缩小太多,画布不会以与目标相反的方式移动,而是朝同一方向移动。

所以我的问题是:通过缩放和旋转实现视差的正确方法是什么?

P.S。对我来说,重要的是我使用画布作为图层。

1 个答案:

答案 0 :(得分:0)

要准备下一个动画帧,您必须按照执行它们的相反顺序撤消任何先前的变换:

context.translate(x,y);
context.scale(sx,sy);
context.rotate(r);
// draw stuff
context.rotate(-r);
context.scale(-sx,-sy);
context.translate(-x,-y);

或者,您可以使用context.save / context.restore撤消之前的转换。

  • 调整当前帧的视差值
  • 使用context.save(),
  • 保存未转换的上下文状态
  • 进行转换(翻译,缩放,旋转等),
  • 绘制对象,就好像它们位于非转换空间中,在转换点使用[0,0]
  • 使用context.restore()/
  • 将您的上下文恢复为未转换状态

无论哪种方式都能正确地为您提供一个面向默认的画布,用于下一个动画帧。

您应用的确切视差效果取决于您自己的设计,但使用这些方法将使画布返回到正常的默认状态,供您设计。