画布图像的缩放、旋转和绘制

3

针对一个游戏项目,我使用它们的属性(如文件名、位置、比例和旋转)来绘制图像。

这是进行绘制的部分:

this.context.save();
this.context.translate(item.position.x, item.position.y);
if (item.rotation > 0) {
    this.context.rotate(item.rotation * (Math.PI / 180));
}
if (item.scale.x !== 1 || item.scale.y !== 1) {
    this.context.scale(item.scale.x, item.scale.y);
}
var width = item.imageSize.width * item.scale.x;
var height = item.imageSize.height * item.scale.y;
this.context.drawImage(this.assets.image[item.fileName], -(width / 2), -(height / 2), width, height);
this.context.restore();

(不要在意奇怪的位置,这不重要)

这个方法很好用,但是有一件事情我不太明白:

旋转和缩放可以通过两种不同的方式实现:先缩放再旋转,或者先旋转再缩放。从逻辑上讲,人们会认为先缩放再旋转是正确的,但是出于某些原因,只有先旋转再缩放才能得到正确的结果。

那么,哪种方法才是正确的呢?


哇,很酷!我本来以为这种转换不会受到顺序的影响... - Lukas
2个回答

2
你的对象的起点在哪里?x / y是左上角吗?如果是,那可能会导致问题。
演示缩放旋转 Demo Scaling Then Rotating
ctx.translate(box.x, box.y);
ctx.scale(2,2);
ctx.rotate(box.angle);

演示:旋转后缩放

ctx.translate(box.x, box.y);
ctx.rotate(box.angle);
ctx.scale(2,2);

如果你注意到这两个演示无论我何时进行缩放和旋转都能正常工作。然而,我的起点(翻译到哪里)在盒子的中心。

回答你的问题(或者试图回答),没有正确或错误的方法,你可以先进行缩放或者先进行旋转,这只是个人偏好的问题。

如果你等比例地缩放x和y,那么它们的结果相同,但如果你以不同的比例缩放x和y,则结果不同... 请参见http://jsfiddle.net/sekhk/3/和http://jsfiddle.net/sekhk/4/。 - Lukas
@Lukas 说得好,不过我认为那是常识所以我没有提到,但那很可能是他的问题。 - Loktar
参数,无法编辑上面的评论,意思是常识而不是常识...那听起来有点无礼。 - Loktar

1

“正确的方法”实际上取决于您想要做什么。对于您来说,似乎旋转然后缩放会得到您期望的结果。

这里有一个演示旋转和缩放顺序不同的例子:http://jsfiddle.net/HYbC7/3/

对我来说出乎意料的是,当您先缩放再旋转时。如果您使用scale(x, y)其中xy不相等,然后旋转,则沿x轴的旋转将与沿y轴的旋转不同,并且结果网格将被扭曲。


这是由于画布与翻译等操作的工作方式有关。想象一下一个橡皮正方形,你只能从北边和南边拉,所以如果你在拉它时没有旋转它,它只会看起来高一点,但是如果你旋转它然后再拉它,你可能会以一个角度抓住它的两侧,这将使它看起来歪斜。缩放始终从x-y轴工作,因此如果您先旋转,然后按不均匀的比例缩放,您将获得奇怪的扭曲效果。 - Loktar

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