Javascript 画布图像缩放、旋转、绘制

Javascript 画布图像缩放、旋转、绘制,javascript,canvas,Javascript,Canvas,对于游戏项目,我使用图像的属性(如文件名、位置、比例和旋转)绘制图像 以下是绘制图纸的零件: 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

对于游戏项目,我使用图像的属性(如文件名、位置、比例和旋转)绘制图像

以下是绘制图纸的零件:

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();
(不要介意奇怪的定位,这并不重要)

这很好,但有一件事我不明白:

旋转和缩放可以通过两种不同的方式完成:先缩放然后旋转,或者其他方式。从逻辑上讲,人们会认为先缩放然后旋转是正确的,但出于某种原因,只有在我先旋转然后缩放时,它才能正确工作


正确的方法是什么?

对象的原点在哪里?x/y是左上角吗?如果是这样的话,这可能会导致问题

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);

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
不相等,然后旋转,那么沿x轴的旋转将不同于沿y轴的旋转,并且生成的网格将倾斜。

哇,时髦!我认为顺序对这类变换并不重要…如果你平均缩放x和y,那么它们的结果是相同的,但如果你以不同的方式缩放x和y。。。看到并@Lukas很好的观点,但是我只是把这当作常识,所以我没有提及,但这很可能是他的问题。Arg,不能编辑上述评论,意思是常识而不是常识。。这有点粗鲁。这是因为canvas是如何与翻译等工作的。想象一个橡皮方块,你只能从北向南拉动,所以如果你拉动它时它没有旋转,它看起来会更高一些,但是如果你转动它然后拉动它,你可以抓住它的侧面,角度会使它看起来倾斜。缩放总是从x-y轴开始,所以如果你先旋转,然后缩放不均匀的量,你会得到奇怪的倾斜。