Android 3D旋转动画库

作者: 代码君_Coder | 来源:发表于2017-09-01 15:13 被阅读399次

    今天兴趣来潮,撸了一个动画特效,我把他应用在登录的界面,当然也可以用在其他地方,先来预览一下我的特效吧

    预览.gif

    使用方法

    1. 在build.gradle里面配置如下
    dependencies {
      compile 'com.jzp:rotate3D:1.0.0'
    }
    
    1. 生成一个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轴深度
      可选参数未设置的话就使用默认的
    1. 启动动画
       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 我是根据这篇博客进行封装的,谢谢亦枫大神的分享

    Github源码下载:3D旋转动画库

    相关文章

      网友评论

        本文标题:Android 3D旋转动画库

        本文链接:https://www.haomeiwen.com/subject/akxkjxtx.html