拉斐尔(Raphael)变换动画不起作用 [英] Raphael transform animation not behaving

查看:89
本文介绍了拉斐尔(Raphael)变换动画不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Raphael(和Snap.svg,执行相同的操作)中进行动画变换.

I'm doing an animated transform in Raphael (and Snap.svg, which does the same).

如果将旋转应用于基本元素,则它会按照我的预期正常旋转.但是,如果我已经应用了先前的变换(即使其为t0,0或r0),则该元素似乎会缩小并向上缩放,好像它总是必须适合其先前的边界框之类.

If I apply a rotation to a basic element, it rotates normally as I would expect. However, if I already have a previous transform applied (even if its t0,0 or r0), the element seems to scale down and back up, as though it always has to fit in its previous bounding box or something.

这是示例小提琴

var r1 = s.rect(0,0,100,100,20,20).attr({ fill: "red", opacity: "0.8", stroke: "black", strokeWidth: "2" }); 
r1.transform('t0,0'); // any transform leads to shrink on rotate...
r1.animate({ transform: 'r90,50,50' }, 2000);


var r2 = s.rect(150,0,100,100,20,20).attr({ fill: "blue", opacity: "0.8", stroke: "black", strokeWidth: "2" });
r2.animate({ transform: 'r90,200,50' }, 2000);

关于发生的事情,动画转换中是否缺少一些明显的东西?

Is there something obvious I'm missing on animated transforms as to what is happening ?

推荐答案

要弄清这里发生的事情,您需要了解几件事.

There are a couple different things you need to understand to figure out what's going on here.

首先,您的动画转换是替换您的原始转换,而不是添加到原始转换.如果在动画中包含原始变换指令,则可以避免缩小效果:

The first is that your animating transform is replacing your original transform, not adding on to it. If you include the original transform instruction in the animation, you avoid the shrinking effect:

var r1 = s.rect(0,0,100,100,20,20)
        .attr({ fill: "red", opacity: "0.8", stroke: "black", strokeWidth: "2" }); 
r1.transform('t0,0'); 
    // any transform leads to shrink on rotate...
r1.animate({ transform: 't0,0r90,50,50' }, 5000); 
    //unless you repeat that transform in the animation instructions

http://jsfiddle.net/96D8t/3/

如果原始变换是围绕同一中心旋转,则还可以避免缩小效果:

You can also avoid the shrinking effect if your original transformation is a rotation around the same center:

var r1 = s.rect(0,0,100,100,20,20)
        .attr({ fill: "red", opacity: "0.8", stroke: "black", strokeWidth: "2" }); 
r1.transform('r0,50,50'); // no shrinking this time...
r1.animate({ transform: 'r90,50,50' }, 2000);

http://jsfiddle.net/96D8t/4/

但是为什么它会有所作为,看到0,0的平移或0的旋转实际上并没有改变图形?当您要求程序在两种不同类型的转换之间进行转换时,这是程序计算中间值的方式的一种副作用.

But why should it make a difference, seeing as a translation of 0,0 or a rotation of 0 doesn't actually change the graphic? It's a side effect of the way the program calculates in-between values when you ask it to convert between two different types of transformations.

Snap/Raphael会将您的两个不同的转换转换为矩阵转换,然后在矩阵中的每个值之间进行插值(计算中间值).

Snap/Raphael are converting your two different transformations into matrix transformations, and then interpolating (calculating intermediate values) between each value in the matrix.

2D图形转换可以通过以下形式的矩阵来表示

A 2D graphical transformation can be represented by a matrix of the form

a   c   e
b   d   f

(这是标准字母)

您可以将矩阵的两行视为确定最终x和y值的两个代数公式,其中行中的第一个数字乘以原始x值,第二个数字乘以原始y值,第三个数字乘以常数1:

You can think of the two rows of the matrix as two algebra formulas for determining the final x and y value, where the first number in the row is multiplied by the original x value, the second number is multiplied by the original y value, and the third number is multiplied by a constant 1:

newX = a*oldX + c*oldY + e;
newY = b*oldX + d*oldY + f;

像t0,0一样做空变换的矩阵是

The matrix for a do-nothing transformation like t0,0 is

1   0   0
0   1   0

实际上是内部表示为具有命名值的对象,例如

Which is actually represented internally as an object with named values, like

{a:1,  c:0,  e:0,
 b:0,  d:1,  f:0}

无论哪种方式,它只是说newX是oldX的1倍,而newY是oldY的1倍.

Either way, it just says that the newX is 1 times the oldX, and the newY is 1 times the oldY.

r90,50,50命令的矩阵为:

The matrix for your r90,50,50 command is:

0   -1   100
1    0   0

也就是说,如果您的旧点是(50,100),则公式为

I.e., if your old point is (50,100), the formulas are

newX = 0*50 -1*100 + 100*1 = 0
newY = 1*50 + 0*100 + 0    = 50

如预期的那样,点(50,100)绕点(50,50)旋转了90度,变为(0,50).

The point (50,100) gets rotated 90degrees around the point (50,50) to become (0,50), just as expected.

当您尝试进行转换时,它开始变得意外

Where it starts getting unexpected is when you try to transform

1   0   0
0   1   0

0   -1   100
1    0   0

如果将矩阵中的每个数字从起始值转换为结束值,则中间点将为

If you transform each number in the matrix from the start value to the end value, the half-way point would be

0.5   -0.5   50
0.5    0.5   0

这是将矩形缩小一半 并将其围绕(50,50)旋转45度的矩阵.

Which works out as the matrix for scaling the rectangle down by half and rotating it 45degrees around (50,50).

所有这些可能超出了您所需要知道的数学范围,但是我希望它可以帮助您理解正在发生的事情.

All of that might be more math than you needed to know, but I hope it helps make sense of what's going on.

无论如何,简单的解决方案是确保始终在动画前后匹配变换的类型,以便程序可以插值原始值,而不是矩阵值.

Regardless, the easy solution is to make sure that you always match up the types of transforms before and after the animation, so that the program can interpolate the original values, instead of the matrix values.

这篇关于拉斐尔(Raphael)变换动画不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆