1 概述
接上篇文章,我们把android 动画剩下的一些知识点说清楚。其实android 动画博大精深,一些绚丽的效果,需要我们在平时工作中不断的去摸索,这里只能简单说的这里了。以后如果有时间我还会在补充说android 动画的。本文会讲到android 中的Matrix,以及配合Camera() (注意这里是Camera 不是指相机),来实现一些炫酷3D动画效果。前半部分文们会将一些关于矩阵变化的基础知识,这里有同学会头疼了,大学学的线型代数都还给老师了吧,哈哈,没关系,这里用到的都是线代当中最基础的变换,如果你这也忘了的话,没关系把你课本找出来吧。
2 Matrix 的数学原理
android 当中Matrix 结构如下
这里不着急我们一点一点的说Matix 的基础变换可以分为4种 1 平移变换(Translate) 2 旋转变换(Rotate)3 Scale 缩放,4 Skew 错切变换。对于矩阵操作我android 提高了pre()前乘 post() 后乘,set设置矩阵中的值,以为矩阵是不满足交换律的所有有前乘后乘之分也就是所谓的左乘右乘。所有的变换都是相对于中心点来说的,如果不指定中心点的话,默认点为(0,0);基础知识点就先说那么多,随着深入用到什么知识点我们在补充,以防一些同学,看了一眼就头大。
1 平移
假设一个点有(x0 y0)点x方向上移动了▽x , y方向移动了▽y 那么移动后坐标可以表示称(x0+▽x,y0+▽x)那么这种关系用矩阵乘法可以表示为
x = x0+▽x; y=y0+▽用矩阵表示为
2 旋转变换
假设点➡️(x0,y0) 转动& 到(x ,y)
用矩阵可表示为
即:
3 绕某一点转动情况为
做矩阵变化后为
过程大体可以分3部分
1很显然就是将(x0,y0)移动到坐标原点后的坐标。
2而就是将平移后的x0yo 逆时针转动&度了。
3而就是将转动后的坐标移动重新平移回去。
所以扰某一点转动分3步 :第一 将坐标原点定动该点,二将点转动,3将坐标原点移动回原地。
缩放比较好理解了
x = k1*x0 y = k1*y0 矩阵表示为:
另外矩阵还有错切变换 对称变换,不说了以后用到自己查资料吧,矩阵就说到这吧。
下面用代码来实现上述变换过程:
我们可以发现其实网上有很多关于对图像做变换的例子 为要是继续写图像变换的话也太美创意了,好吧 为这里就用matrix 自定义为们常见的几种动画变换。
闲话不多说上代码。
3自定义动画
1 平移动画
新建类MyAnimation继承Animation 自定义动画 需要重写两个方法:1 initialize() 2 applyTransformation() 第一个方法主要做一些初始化的操作 2动画变换主要的applyTransformation 中实现。里面有两个回调参数,interpolatedTime (范围是0-1)是指动画进行的百分百。第二个就是我们需要操作的对象了 Matrix matrix = t.getMatrix(); 这里的到的矩阵就是我们操作的对象了。
实现就简单了代码上
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { Matrix matrix = t.getMatrix(); matrix.postTranslate(TranslationX*interpolatedTime,TranslationY*interpolatedTime); }ok 简单平移动画就实现了,使用的话就简单了代码上
button = findViewById(R.id.btn_start); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int measuredWidth = mgirl.getMeasuredWidth(); int measuredHeight = mgirl.getMeasuredHeight(); Log.e("measuredWidth","measuredWidth: "+measuredWidth); Log.e("measuredHeight","measuredHeight: "+measuredHeight); myTranslatonAnimation.setTranslationX(measuredWidth); myTranslatonAnimation.setTranslationY(measuredHeight); mgirl.startAnimation(myTranslatonAnimation); } }); mgirl = (ImageView) findViewById(R.id.iv_girl); myTranslatonAnimation = new MyTranslatonAnimation(); myTranslatonAnimation.setDuration(2000); myTranslatonAnimation.setFillAfter(true);
2 旋转动画
不多说了上代码
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { Matrix matrix = t.getMatrix(); //的到变换矩阵 matrix.preTranslate(-TranslationX/2,-TranslationY/2);//将矩阵原点平移到旋转中心 matrix.postRotate(360*interpolatedTime); //转动 matrix.postTranslate(TranslationX/2,TranslationY/2); //将矩阵旋转中心平移到原点 }
注释写的很清楚了。
3 缩放动画
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { Matrix matrix = t.getMatrix(); //的到变换矩阵 matrix.preScale(1*(interpolatedTime+1),1*(interpolatedTime+1)); }就是那么简单,这里主要是抛砖引玉,如果你掌握了更为复杂的矩阵变化就可以做出一些特别的动画效果了,抓紧动手试试吧。
下面我们就介绍今天的另外一个主角 Camera,并用它实现一个简单的3d旋转动画
在实现之前要讲的就是观察点,肯不同博客用不同叫法,什么意思呢?学工科朋友都不陌生,一个物理我们为了表现它的外貌特征有时候会,画主视图
俯视图等待,所谓视图就是观察点不同,为了在手机屏幕实现3d效果,我们必须对一个物理不断的变化它的观察点,营造出来,3d效果。设置观察点的方法为:camera.setTranslate(x,y,z) 三个参数表示它的空间坐标。
好吧 其实很简单 为直接上代码 注释写的很清楚。
private float mFromdegree; private float mToFromdegree; private float mCenterX, mCenterY; private Camera mCamera; public void setmFromdegree(float mFromdegree) { this.mFromdegree = mFromdegree; } public void setmToFromdegree(float mToFromdegree) { this.mToFromdegree = mToFromdegree; } public void setmCenterX(float mCenterX) { this.mCenterX = mCenterX; } public void setmCenterY(float mCenterY) { this.mCenterY = mCenterY; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { Matrix matrix = t.getMatrix(); mCamera.save();//初始化Camera float degree = mFromdegree+(mToFromdegree-mFromdegree)*interpolatedTime; //计算绕Y轴转动的角度 if(degree<90){ mCamera.translate(0,0,500*interpolatedTime); //移动观察点主要实现近大远小的效果 }else { mCamera.translate(0,0,500*(1-interpolatedTime)); } mCamera.rotateY(degree); //转动 mCamera.getMatrix(matrix); //获取矩阵 mCamera.restore(); //色释放资源 matrix.preTranslate(-mCenterX/2,-mCenterY/2); //讲转动中心移动到原点 matrix.postTranslate(mCenterX/2,mCenterY/2); //将转动中心移动回去 }使用代码
@Override public void onClick(View v) { int measuredWidth = mgirl.getMeasuredWidth(); int measuredHeight = mgirl.getMeasuredHeight(); Log.e("measuredWidth","measuredWidth: "+measuredWidth); Log.e("measuredHeight","measuredHeight: "+measuredHeight); myTranslatonAnimation.setmCenterX(measuredWidth); myTranslatonAnimation.setmFromdegree(0); myTranslatonAnimation.setmToFromdegree(180); myTranslatonAnimation.setmCenterY(measuredHeight); mgirl.startAnimation(myTranslatonAnimation); } }); mgirl = (ImageView) findViewById(R.id.iv_girl); myTranslatonAnimation = new MyTranslatonAnimation(); myTranslatonAnimation.setDuration(2000); myTranslatonAnimation.setFillAfter(true);
其实通过对观察点的变化还可以做出更加立体的3d 效果,一般那么绚烂的3d 动画也是这么实现的,只是矩阵操作比较复杂,由此可见学好矩阵变化还是非常重要的。
android 动画就先写到这里吧,不足之处欢迎大家给予意见。