我目前正在试验我计划实施到我的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。对我来说,重要的是我使用画布作为图层。
答案 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
撤消之前的转换。
无论哪种方式都能正确地为您提供一个面向默认的画布,用于下一个动画帧。
您应用的确切视差效果取决于您自己的设计,但使用这些方法将使画布返回到正常的默认状态,供您设计。