今天兴趣来潮,撸了一个动画特效,我把他应用在登录的界面,当然也可以用在其他地方,先来预览一下我的特效吧
1. 在build.gradle里面配置如下
dependencies { compile 'com.jzp:rotate3D:1.0.0' }2. 生成一个Rotate3D对象
Rotate3D anim = new Rotate3D.Builder(this) .bindParentView(parent_ll) .bindPositiveView(account_login_ll) .bindNegativeView(account_phone_ll) .create();这里面必须要设置的参数是bindParentView,bindPositiveView,bindNegativeView,这些分别是父类View,正面View,以及旋转后的反面View,有提供可选参数 - setDuration 设置动画时间 - setDepthZ 设置Z轴深度 可选参数未设置的话就使用默认的 3. 启动动画
anim.transform();由于android提供的动画 alpha(淡入淡出),translate(位移),scale(缩放大小),rotate(旋转),这些都是平面上的动画,那想要做3D立体的动画,我们就需要从写animation,3D立体动画用到android的Camera库,Camera提供了三种旋转方法: - rotateX() - rotateY() - rotateX() 调用这三种方法,传入旋转角度参数,即可实现视图沿着坐标轴旋转的功能。
实现的核心代码
public class Rotate3dAnimation extends Animation { private final float mFromDegrees; private final float mToDegrees; private final float mCenterX; private final float mCenterY; private final float mDepthZ; private final boolean mReverse; private Camera mCamera; float scale = 1; // 像素密度 /** * 创建一个绕 y 轴旋转的3D动画效果,旋转过程中具有深度调节,可以指定旋转中心。 * * @param context 上下文,用于获取像素密度 * @param fromDegrees 起始时角度 * @param toDegrees 结束时角度 * @param centerX 旋转中心x坐标 * @param centerY 旋转中心y坐标 * @param depthZ 最远到达的z轴坐标 * @param reverse true 表示由从0到depthZ,false相反 */ public Rotate3dAnimation(Context context, float fromDegrees, float toDegrees, float centerX, float centerY, float depthZ, boolean reverse) { mFromDegrees = fromDegrees; mToDegrees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthZ = depthZ; mReverse = reverse; // 获取手机像素密度 (即dp与px的比例) scale = context.getResources().getDisplayMetrics().density; } @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) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); camera.save(); // 调节深度 if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } // 绕y轴旋转 camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); // 修正失真 float[] mValues = new float[9]; matrix.getValues(mValues); //获取数值 mValues[6] = mValues[6] / scale; //数值修正 mValues[7] = mValues[7] / scale; //数值修正 matrix.setValues(mValues); //重新赋值 // 调节中心点,旋转中心默认是坐标原点,对于图片来说就是左上角位置。 matrix.preTranslate(-centerX, -centerY); // 使用pre将旋转中心移动到和Camera位置相同 matrix.postTranslate(centerX, centerY); // 使用post将图片(View)移动到原来的位置 } }代码中的作用我都有写注释,所以在这里就不多解释了,有的时候,我们看一些特效觉得做起来一定很麻烦,其实只要你掌握其实现原理,并不是很难,所以给大家一句忠告,多读源码,对技术的提升很有帮助。
参考文献:http://www.jianshu.com/p/153d9f31288d 我是根据这篇博客进行封装的,谢谢亦枫大神的分享
