首页 > 代码库 > 【转】2D动画:view的Matrix
【转】2D动画:view的Matrix
转载地址:http://blog.csdn.net/flowingflying
上学习的小例子是从左上角进行扩展动画,如果我们需要在中心进行扩展,相关的代码如下:
public class ViewAnimation1 extends Animation{
private float centerX,centerY;
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
centerX = width/2.0f;
centerY = height/2.0f;
setDuration(2500);
setFillAfter(true);
setInterpolator(new LinearInterpolator());
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final Matrix matrix = t.getMatrix();
Log.v("WEI","orignal matrix " + matrix);
matrix.setScale(interpolatedTime, interpolatedTime);
matrix.preTranslate(-lastPointX, -lastPointX);
matrix.postTranslate(centerX, centerY);
Log.v("WEI"," target matrix " + matrix);
}
}
矩阵
这里动画代码较之一开始的小例子有些令人困惑,需要先弄明白Matrix。从Android的reference和例子的LogCat跟踪,我们知道Matrix是一个3×3的矩阵,具体为:
而通过getMatrix()获得的是View没有发生动画变化的矩阵,即单位矩阵:
赋值操作
setScale()、setXXX()表示直接设置矩阵。执行matrix.setScale(interpolatedTime,interpolatedTime)后就获得下左图的view,我们需要进一步将移动位置,移动到下右图。
setXXX()相当于赋值操作。赋值的操作有以下:
matrix.reset() :设置为单位矩阵
matrix.setScale() :如上左图,以(0,0)为支点进行缩放
matrix.setTranslate()
matrix.setRotate()
matrix.setSkew()
乘操作:前乘和后乘
如果我们在setScale()后,进行setTranslate()操作,等于进行了两次赋值,最终值是后面的赋值,也就是前面setScale()无效。我们将看到的是整个view的移动,没有缩放效果。为此需要使用preXXX()和postXXX()的操作。在数学上是矩阵的计算,pre表示在作为前面的参数乘以一个矩阵,即M’=M*other,M为前乘;post表示作为后面参数乘一个矩阵M’=other*M,M为后乘,而set表示设置矩阵M=other。在图像处理上,pre表示先进行某个图像处理,接着是set的图像处理,最后是post的图像处理。
要实现目标效果,我们也可以通过下面的方法:
final Matrix matrix = t.getMatrix();
matrix.setScale(interpolatedTime, interpolatedTime);
matrix.postTranslate(centerX*(1-interpolatedTime), centerY*(1-interpolatedTime));
在图像处理上,先进行缩放,如左图,然后平移到右图位置。在数学上,也很容易证明
如果通过下面的方式:
final Matrix matrix = t.getMatrix();
matrix.setScale(interpolatedTime, interpolatedTime);
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
在图像上,先将图像移动(-centerX,-centerY),相当将中心点方在(0,0)的位置上,然后缩放,最后将中心点移动到(centerX,centerY),如图所示:
在数学上也和容易证明:
或者
Matrix运算真是神奇,事实上,layout动画也是通过Matrix类来实现的。
矩阵计算
Matrix类还提供了直接矩阵计算方式。Matrix a=new Matrix()相当于创建一个单位矩阵。
a.set(b),就是赋值a = b;
a.preConCat(b),相当于前乘,即 a=a×b;
a.postConCat(b),相当于前乘,即 a=b×a;
c.setConcat(a,b),相当于c=a×b;
对于例子,我们可以设置3个矩阵,分别表示3种图形效果;
Matrix m1 = new Matrix();
m1.setScale(interpolatedTime, interpolatedTime);
Matrix m2 = new Matrix();
m2.setTranslate(-centerX, -centerY);
Matrix m3 = new Matrix();
m3.setTranslate(centerX, centerY);
要实现同样的例子效果,可以:
//matrix = m1
matrix.preConcat(m2); //matrix = matrix * m2 = m1 * m2;
matrix.postConcat(m3); //matrix = m3 * matrix = m 3 * (m1* m2) = m3 * m1 *m2;
或者
// matrix = m1 * m2;
matrix.setConcat(m3, matrix); //matrix = m3 * matrix = m3* (m1* m2) = m3 * m1 * m2;