我在画一个中心X,Y为0,0的图。当渲染的时候,我用translate重新定位,然后使用scale使图形填充画布(例如,将所有内容缩放50%)。我注意到,无论你调用scale然后翻译,还是翻译然后scale,这都很重要,我不能完全理解它。这是一个问题,因为一切并不总是适合,但我的心理模型是不完整的,所以有一个艰难的时间修复它。有人能解释一下为什么音阶和翻译调用的顺序很重要吗?
jexiocij1#
让我们在300 x300的画布上绘制一个网格:http://jsfiddle.net/simonsarris/4uaZy/
这个就行了没什么特别的一条红线表示原点的位置,它穿过(0,0)并延伸得非常非常远,所以当我们平移它时,我们会看到一些东西。这里的原点是左上角,红线在(0,0)处相交。
**下面的所有转换都发生在我们绘制网格之前,所以我们将移动网格。**这可以让你确切地看到器官发生了什么。
因此,让我们将画布平移100,100,向下+向右移动:
http://jsfiddle.net/simonsarris/4uaZy/1/我们已经平移了原点,也就是红色X的中心位置。原点现在是100,100。现在我们先平移然后缩放。请注意,原点与上一个图像的位置相同,所有内容都是两倍大。
http://jsfiddle.net/simonsarris/4uaZy/2/好吧。原始值还是100100。但一切都是由2。原点改变了,然后所有东西都膨胀起来。现在让我们反过来看看它们。这一次,我们首先扩展,所以从一开始一切都是胖的:
http://jsfiddle.net/simonsarris/4uaZy/3/一切都是2。原点位于0,0,即其起点。现在我们做一个缩放,然后做一个平移。
http://jsfiddle.net/simonsarris/4uaZy/4/我们仍然平移了100,100,但是原点已经移动了200,200个真实的像素。把这个和之前的两张图片比较一下。这是因为 * 缩放后发生的所有事情都必须缩放 *,包括其他变换。因此,在缩放的画布上按(100,100)变换会导致画布移动200,200。这里要记住的是,更改变换会影响绘制(或变换)事物的方式!)从此。如果缩放x2,然后平移,则平移将为x2如果你想从数学上了解每一步发生了什么,我建议你看看这里的代码:https://github.com/simonsarris/Canvas-tutorials/blob/master/transform.js这模拟了canvas完成的整个转换过程,并让您看到之前的转换如何修改之后的转换。
23c0lvtd2#
缩放和旋转是相对于原点完成的,因此如果您的变换具有平移,例如,那么这将使顺序变得重要。这里有一个很好的阅读:Why Transformation Order Is Significant
lo8azlld3#
基于Simon Sarris的精彩回答,我想解释一下我个人认为最令人困惑的地方,那就是HTML规范中的示例:转换必须以相反的顺序执行。例如,如果将宽度加倍的缩放变换应用于画布,接着是将绘制操作旋转四分之一圈的旋转变换,然后在画布上绘制宽度为高度两倍的矩形,则实际结果将是正方形。从一个40 x20的矩形开始:
https://jsfiddle.net/mhsmith/p6nLo9d4/2/显然,加上ctx.scale(2, 1)使其为80 x20。
ctx.scale(2, 1)
https://jsfiddle.net/mhsmith/p6nLo9d4/4/您可能认为添加四分之一圈旋转(ctx.rotate(Math.PI / 2))会将矩形旋转为20 x80。但实际上,它把它变成了一个正方形!
ctx.rotate(Math.PI / 2)
https://jsfiddle.net/mhsmith/p6nLo9d4/5/这是因为旋转受比例的影响。为了使其可视化,下面是上面3个图像在原点周围有一个圆圈的样子:
https://jsfiddle.net/mhsmith/p6nLo9d4/8/scale将圆变成椭圆,随后的rotate围绕该椭圆的边缘,而不是围绕原始圆。所以当X轴从向右旋转到向下时,它会被压缩2倍。当Y轴从指向下旋转到指向左时,它会扩展2倍。最终结果是80 x20的矩形变成了40 x40的正方形。有两种方法来思考一系列的转换:1.想象它们发生在 * 轴 * 上,按照它们在代码中出现的顺序,每一步都是根据前一步产生的轴来测量的;或1.想象它们发生在 * 图像 * 上,与它们在代码中出现的顺序相反,每一步都是根据原始轴测量的。这个答案和西蒙·萨里斯的答案都是用第一种方式写的。HTML规范是以第二种方式编写的,我认为这更容易可视化。
scale
rotate
3条答案
按热度按时间jexiocij1#
让我们在300 x300的画布上绘制一个网格:
http://jsfiddle.net/simonsarris/4uaZy/
这个就行了没什么特别的一条红线表示原点的位置,它穿过(0,0)并延伸得非常非常远,所以当我们平移它时,我们会看到一些东西。这里的原点是左上角,红线在(0,0)处相交。
**下面的所有转换都发生在我们绘制网格之前,所以我们将移动网格。**这可以让你确切地看到器官发生了什么。
因此,让我们将画布平移100,100,向下+向右移动:
http://jsfiddle.net/simonsarris/4uaZy/1/
我们已经平移了原点,也就是红色X的中心位置。原点现在是100,100。
现在我们先平移然后缩放。请注意,原点与上一个图像的位置相同,所有内容都是两倍大。
http://jsfiddle.net/simonsarris/4uaZy/2/
好吧。原始值还是100100。但一切都是由2。原点改变了,然后所有东西都膨胀起来。
现在让我们反过来看看它们。这一次,我们首先扩展,所以从一开始一切都是胖的:
http://jsfiddle.net/simonsarris/4uaZy/3/
一切都是2。原点位于0,0,即其起点。
现在我们做一个缩放,然后做一个平移。
http://jsfiddle.net/simonsarris/4uaZy/4/
我们仍然平移了100,100,但是原点已经移动了200,200个真实的像素。把这个和之前的两张图片比较一下。
这是因为 * 缩放后发生的所有事情都必须缩放 *,包括其他变换。因此,在缩放的画布上按(100,100)变换会导致画布移动200,200。
这里要记住的是,更改变换会影响绘制(或变换)事物的方式!)从此。如果缩放x2,然后平移,则平移将为x2
如果你想从数学上了解每一步发生了什么,我建议你看看这里的代码:
https://github.com/simonsarris/Canvas-tutorials/blob/master/transform.js
这模拟了canvas完成的整个转换过程,并让您看到之前的转换如何修改之后的转换。
23c0lvtd2#
缩放和旋转是相对于原点完成的,因此如果您的变换具有平移,例如,那么这将使顺序变得重要。
这里有一个很好的阅读:Why Transformation Order Is Significant
lo8azlld3#
基于Simon Sarris的精彩回答,我想解释一下我个人认为最令人困惑的地方,那就是HTML规范中的示例:
转换必须以相反的顺序执行。
例如,如果将宽度加倍的缩放变换应用于画布,接着是将绘制操作旋转四分之一圈的旋转变换,然后在画布上绘制宽度为高度两倍的矩形,则实际结果将是正方形。
从一个40 x20的矩形开始:
https://jsfiddle.net/mhsmith/p6nLo9d4/2/
显然,加上
ctx.scale(2, 1)
使其为80 x20。https://jsfiddle.net/mhsmith/p6nLo9d4/4/
您可能认为添加四分之一圈旋转(
ctx.rotate(Math.PI / 2)
)会将矩形旋转为20 x80。但实际上,它把它变成了一个正方形!https://jsfiddle.net/mhsmith/p6nLo9d4/5/
这是因为旋转受比例的影响。为了使其可视化,下面是上面3个图像在原点周围有一个圆圈的样子:
https://jsfiddle.net/mhsmith/p6nLo9d4/8/
scale
将圆变成椭圆,随后的rotate
围绕该椭圆的边缘,而不是围绕原始圆。所以当X轴从向右旋转到向下时,它会被压缩2倍。当Y轴从指向下旋转到指向左时,它会扩展2倍。最终结果是80 x20的矩形变成了40 x40的正方形。有两种方法来思考一系列的转换:
1.想象它们发生在 * 轴 * 上,按照它们在代码中出现的顺序,每一步都是根据前一步产生的轴来测量的;或
1.想象它们发生在 * 图像 * 上,与它们在代码中出现的顺序相反,每一步都是根据原始轴测量的。
这个答案和西蒙·萨里斯的答案都是用第一种方式写的。HTML规范是以第二种方式编写的,我认为这更容易可视化。