zoukankan      html  css  js  c++  java
  • Android立体旋转动画实现与封装(支持以X、Y、Z三个轴为轴心旋转)

    本文主要介绍Android立体旋转动画,或者3D旋转,下图是我自己实现的一个界面

    立体旋转分为以下三种:

      1. 以X轴为轴心旋转

      2. 以Y轴为轴心旋转

      3. 以Z轴为轴心旋转--这种等价于android默认自带的旋转动画RotateAnimation

    实现立体旋转核心步骤:

      1. 继承系统Animation重写applyTransformation方法

        通过applyTransformation方法的回调参数 float interpolatedTime, Transformation t 来控制旋转动画

        interpolatedTime 用来计算旋转角度而 用来控制变换矩阵从而实现图像的旋转

      2. android.graphics.Camera控制旋转算法

        Camera可以对图像执行一些比较复杂的操作--旋转,绽放,与Matrix一起实现图像的倾斜

    核心代码封装:Rotate3dAnimation

    package rotateanim.example.com.androidrotateanim;
    
    import android.view.animation.Animation;
    import android.view.animation.Transformation;
    import android.graphics.Camera;
    import android.graphics.Matrix;
    
    /**
     * An animation that rotates the view on the X,Y,Z axis between two specified angles.
     * This animation also adds a translation on the Z axis (depth) to improve the effect.
     */
    public class Rotate3dAnimation extends Animation {
        public static final Byte ROTATE_X_AXIS = 0x00;
        public static final Byte ROTATE_Y_AXIS = 0x01;
        public static final Byte ROTATE_Z_AXIS = 0x02;
        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;
        private Byte mRotateAxis;  // 0:X轴  1:Y轴  2:Z轴
    
        /**创建3D旋转动画
         * @param fromDegrees the start angle of the 3D rotation
         * @param toDegrees the end angle of the 3D rotation
         * @param centerX the X center of the 3D rotation
         * @param centerY the Y center of the 3D rotation
         * @param depthZ the Z depth of the 3D rotation
         * @param rotateAxis the rotate axis of the 3D rotation
         * @param reverse true if the translation should be reversed, false otherwise
         */
        public Rotate3dAnimation(float fromDegrees, float toDegrees,
                float centerX, float centerY, float depthZ, Byte rotateAxis, boolean reverse) {
            mFromDegrees = fromDegrees;
            mToDegrees = toDegrees;
            mCenterX = centerX;
            mCenterY = centerY;
            mDepthZ = depthZ;
            mRotateAxis = rotateAxis;
            mReverse = reverse;
        }
    
        @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) {
                // z的偏移会越来越大。这就会形成这样一个效果,view从近到远
                camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
            } else {
                // z的偏移会越来越小。这就会形成这样一个效果,我们的View从一个很远的地方向我们移过来,越来越近,最终移到了我们的窗口上面
                camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
            }
            // 是给我们的View加上旋转效果,在移动的过程中,视图还会以XYZ轴为中心进行旋转。
            if (ROTATE_X_AXIS.equals(mRotateAxis)) {
                camera.rotateX(degrees);
            } else if (ROTATE_Y_AXIS.equals(mRotateAxis)) {
                camera.rotateY(degrees);
            } else {
                camera.rotateZ(degrees);
            }
    
            // 这个是将我们刚才定义的一系列变换应用到变换矩阵上面,调用完这句之后,我们就可以将camera的位置恢复了,以便下一次再使用。
            camera.getMatrix(matrix);
            // camera位置恢复
            camera.restore();
    
            // 下面两句是为了动画是以View中心为旋转点
            matrix.preTranslate(-centerX, -centerY);
            matrix.postTranslate(centerX, centerY);
        }
    }

    Rotate3dAnimation使用:跟普通动画使用没区别,设置给一个View对象,启动动画就搞定

    mRotateImgv就是需要旋转的View对象
    
    // 以X轴为轴心旋转
    private void rotateOnXCoordinate() {
        float centerX = mRotateImgv.getWidth() / 2.0f;
        float centerY = mRotateImgv.getHeight() / 2.0f;
        float depthZ = 0f;
        Rotate3dAnimation rotate3dAnimationX = new Rotate3dAnimation(0, 180, centerX, centerY, depthZ, Rotate3dAnimation.ROTATE_X_AXIS, true);
        rotate3dAnimationX.setDuration(1000);
        mRotateImgv.startAnimation(rotate3dAnimationX);
    }
    
    // 以X轴为轴心旋转
    private void rotateOnYCoordinate() {
        float centerX = mRotateImgv.getWidth() / 2.0f;
        float centerY = mRotateImgv.getHeight() / 2.0f;
        float centerZ = 0f;
    
        Rotate3dAnimation rotate3dAnimationX = new Rotate3dAnimation(0, 180, centerX, centerY, centerZ, Rotate3dAnimation.ROTATE_Y_AXIS, true);
        rotate3dAnimationX.setDuration(1000);
        mRotateImgv.startAnimation(rotate3dAnimationX);
    }
    
    // 以Z轴为轴心旋转---等价于普通平面旋转动画
    private void rotateAnimHorizon() {
        float centerX = mRotateImgv.getWidth() / 2.0f;
        float centerY = mRotateImgv.getHeight() / 2.0f;
        float centerZ = 0f;
    
        Rotate3dAnimation rotate3dAnimationX = new Rotate3dAnimation(180, 0, centerX, centerY, centerZ, Rotate3dAnimation.ROTATE_Z_AXIS, true);
        rotate3dAnimationX.setDuration(1000);
        mRotateImgv.startAnimation(rotate3dAnimationX);
    
        // 下面是使用android自带的旋转动画
        // RotateAnimation rotateAnimation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        // rotateAnimation.setDuration(1000);
        // mRotateImgv.startAnimation(rotateAnimation);
    }

     源码地址:https://github.com/PopFisher/AndroidRotateAnim

  • 相关阅读:
    【LVS 】NAT方式实现过程
    【 LVS 】类型及算法
    [ 总结 ] RHEL6/Centos6 使用OpenLDAP集中管理用户帐号
    [ 手记 ] 关于tomcat开机启动设置问题
    [ 总结 ] nginx 负载均衡 及 缓存
    Mac
    Swift
    Swift
    Cocoapods
    Swift
  • 原文地址:https://www.cnblogs.com/popfisher/p/5679847.html
Copyright © 2011-2022 走看看