在HTML5中,我想将转换功能实现为canvas元素,因此用户可以translate
(移动),scale
(放大/缩小)和rotate
canvas元素。每个这样的变换都可以用不同的变换原点来完成。
第一次转型很容易:
function transform(el, value, origin) {
el.style.Transform = value;
el.style.MozTransform = value;
el.style.msTransform = value;
el.style.OTransform = value;
el.style.webkitTransform = value;
el.style.TransformOrigin = origin;
el.style.MozTransformOrigin = origin;
el.style.msTransformOrigin = origin;
el.style.OTransformOrigin = origin;
el.style.webkitTransformOrigin = origin;
}
transform(myCanvas, 'translate('+ dx +'px, ' + dy + 'px) ' +
'scale(' + zoom + ', ' + zoom + ') ' +
'rotate(' + angle + 'deg)',
cx + 'px ' + cy + 'px');
用户将移动或缩放或旋转元素,而不是一次性所有内容,因此某些转换参数将保持默认(dx = 0,dy = 0,zoom = 1,angle = 0)
在这样的转换之后,如果用户想要进行另一次转换(和另一个转换,另一个......),我如何将(dx1,dy1,zoom1,angle1,cx1,cy1)与(dx2,dy2,zoom2,angle2,cx2,cy2)以获得可以在以后与新的转换参数组合的最终值?我无法将另一个转换附加到transform
参数,因为tranform-origin
可能不同。是否有一个公式如何将转换与不同的变换原点组合?
答案 0 :(得分:8)
您不必学习矩阵数学。根据{{3}}
- 从身份矩阵开始。
- 通过计算的'transform-origin'的X,Y和Z值进行翻译。
- 依次乘以'transform'属性中的每个变换函数
- 通过'transform-origin'
的否定计算的X,Y和Z值进行翻译 醇>
换句话说,transform-origin: A; transform: B
与transform: translate(-A) B translate(A)
相同。 (转换从右到左适用,所以你想要发生的第一件事就在最后。)
所以使用上面的规则来消除transform-origin
,现在你只需要连接的简单转换。
示例:
transform-origin: 5px 5px; transform: translate(10px, 40px)
transform-origin: 25px 30px; transform: scale(2)
transform-origin: 10px 10px; transform: rotate(30deg)
变为
transform: translate(-5px, -5px) translate(10px, 40px) translate(5px, 5px)
transform: translate(-25px, -30px) scale(2) translate(25px, 30px)
transform: translate(-10px, -10px) rotate(30deg) translate(10px, 10px)
现在你可以将它们结合起来,因为它们都同意原点(即没有原点)
transform: translate(-5px, -5px) translate(10px, 40px) translate(5px, 5px) translate(-25px, -30px) scale(2) translate(25px, 30px) translate(-10px, -10px) rotate(30deg) translate(10px, 10px)
当然,如果你想要
,你可以折叠连续的翻译 transform: translate(-15px, 10px) scale(2) translate(15px, 20px) rotate(30deg) translate(10px, 10px)
或者你可以挖出你的数学教科书和the CSS Transform specification。
修改:转换适用于从右到左。
答案 1 :(得分:1)
你必须处理矩阵变换。
每个线性操作都可以用3x3矩阵和3x1矢量表示,您可以在平面上应用它。如果 p 是一个点, M 是矩阵而 q 是另一个矩阵,则每个线性变换都可以表示为 Mp + q < / em>的
如果你有一个2d点,那么它的向量将是[ x; Ÿ; 1 ](垂直向量),而矩阵可以有多种形式。
对于翻译,矩阵只是单位矩阵。向量 q 是翻译向量。
对于缩放, M 就像
[a 0 0]
M = [0 b 0]
[0 0 1]
其中 a 和 b 分别是 x 和 y 的缩放系数。向量 q 为空。
对于旋转,比如角度 a ,你会得到
[cos(a) -sin(a) 0]
M = [sin(a) cos(a) 0]
[ 0 0 1]
和 q 再次为空。
也存在倾斜的矩阵。因此,如果必须应用三个连续变换,则必须应用这些线性变换。你的问题是你必须处理起源,所以你必须从 p 中减去向量 o ,而不是应用 M ,再次添加 q 然后再添加 o 。
假设你有这些转换( M1,q1,o1 )和( M2,q2,o2 )。当你申请第一个时,你得到了
p1 = M1 * (p - o1) + q1 + o1
然后你必须应用第二个转换:
p2 = M2 * (p1 - o2) + q2 + o2
最后你会得到:
p2 = M2 * (M1 * (p - o1) + q1 + o1 - o2) + q2 + o2
以及最终的第三个( M3,q3,o3 )。
一团糟?看起来像。但是如果你知道矩阵是什么样子的话,可以简单地解决一些问题。现在,进行数学计算,并将其应用于transform: matrix(a, b, c, d, tx, ty)
。