Gallery 绕Y轴旋转特效

1、Camera 可以实现3D平移、旋转等特效:

2、它并不是以Galley视图所在坐标系,而是在其自身的坐标系

3、例如,其绕Y轴旋转,实际是在matrix 对应视图的左边旋转;平移也是同样。

 

package com.view;

import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;

/**
 *  
 * */
public class GalleryFlow extends Gallery
{

    private Camera mCamera = new Camera();
    private int mMaxRotationAngle = 45;
    private int mMaxZoom = -120;
    private int mCoveflowCenter;
    private float mMaxDistance;
    private float mMaxZ = 100.0f;
    private float mMaxY = -40.0f;
    private float mMaxX = 60.0f;

    public GalleryFlow(Context context)
    {
        super(context);
        this.setStaticTransformationsEnabled(true);
        mMaxDistance = context.getResources().getDisplayMetrics().widthPixels >> 1;
        // Trace.Log("----------mMaxDistance------"+mMaxDistance);
    }

    public GalleryFlow(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.setStaticTransformationsEnabled(true);
        mMaxDistance = context.getResources().getDisplayMetrics().widthPixels >> 1;
        // Trace.Log("----------mMaxDistance------"+mMaxDistance);
    }

    public GalleryFlow(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        this.setStaticTransformationsEnabled(true);
        mMaxDistance = context.getResources().getDisplayMetrics().widthPixels >> 1;
        // Trace.Log("----------mMaxDistance------"+mMaxDistance);
    }

    public int getMaxRotationAngle()
    {
        return mMaxRotationAngle;
    }

    public void setMaxRotationAngle(int maxRotationAngle)
    {
        mMaxRotationAngle = maxRotationAngle;
    }

    public int getMaxZoom()
    {
        return mMaxZoom;
    }

    public void setMaxZoom(int maxZoom)
    {
        mMaxZoom = maxZoom;
    }

    private int getCenterOfCoverflow()
    {
        return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft();
    }

    private static int getCenterOfView(View view)
    {
        return view.getLeft() + view.getWidth() / 2;
    }

    protected boolean getChildStaticTransformation(View child, Transformation t)
    {
        final int childCenter = getCenterOfView(child);
        final int childWidth = child.getWidth();
        int rotationAngle = 0;
        t.clear();
        t.setTransformationType(Transformation.TYPE_MATRIX);
        if (childCenter == mCoveflowCenter)
        {
            transformImageBitmap((ImageView) child, t, 0);
        }
        else
        {
            rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
            if (Math.abs(rotationAngle) > mMaxRotationAngle * 4)
            {
                rotationAngle = 0;
            }
            transformImageBitmap((ImageView) child, t, rotationAngle);
        }
        return true;
    }

    private void transformImageBitmap(ImageView child, Transformation t, int rotationAngle)
    {
        mCamera.save();
        final int MAX_MARGIN = 100;//设置最大间距
        final Matrix imageMatrix = t.getMatrix();
        final int imageWidth = child.getWidth();
        float childCenter = getCenterOfView(child);
        float fromCenter = (mCoveflowCenter - childCenter);

        int margin = -(int) (MAX_MARGIN * fromCenter / imageWidth);//更具离中点的距离计算间距
        
        if (rotationAngle < 0)
        {
            mCamera.translate(margin, 0, 0);
            mCamera.rotateY(-rotationAngle);
        }
        else if (rotationAngle > 0)
        {
            double pi = 3.14f * rotationAngle / 180f;
            int dz = (int) (imageWidth * Math.sin(pi));//需要向里(Z轴正方向)移动,以达到所需特效
            int dx = (int) (imageWidth - imageWidth * Math.cos(pi)) + margin;//需要左移,保持间距
            mCamera.translate(dx, 0, dz);
            mCamera.rotateY(-rotationAngle);
        }
        else
        {
            mCamera.rotateY(0);
        }         
        mCamera.getMatrix(imageMatrix);        
        mCamera.restore();
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        mCoveflowCenter = getCenterOfCoverflow();
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

 

 

另一个新的动画效果:

    private void transformImageBitmap(View child, Transformation t, int rotationAngle)
    {
        mCamera.save();
        final int MAX_MARGIN = 100;
        final Matrix imageMatrix = t.getMatrix();
        final int width = child.getWidth();
        final int height = child.getHeight();
        float childCenter = getCenterOfView(child);
        int fromCenter = (int) (mCoveflowCenter - childCenter);

        int marginX = (MAX_MARGIN * fromCenter / width);
        int marginZ = (fromCenter / 2);
        int dx = marginX;
        int dz = Math.abs(marginZ); 

        mCamera.translate(dx, 0, dz);
        mCamera.rotateY(rotationAngle);

        mCamera.getMatrix(imageMatrix);
    //先将图片中心移动到原点,然后用Camera处理 ,最后还原;(默认图片左下角在原点)
       //将图片中心移动到Y轴,使得Camera处理绕Y轴旋转时,即绕图片中心竖直方向旋转。(默认绕左边旋转)
       // 将图片中心移动到原点,使得视点、原点、图片中心在同一直线。图片向里翻转时,上下端型变对称。(默认上端平直,下端倾斜)
        imageMatrix.preTranslate(-(width / 2), -(height / 2));
        imageMatrix.postTranslate((width / 2), (height / 2));
        mCamera.restore();
    }

 

 第一个动画的优化:

private void transformImageBitmap(View child, Transformation t, int rotationAngle)
    {
        mCamera.save();
        final int MAX_MARGIN = 0;
        final Matrix imageMatrix = t.getMatrix();
        final int width = child.getWidth();
        final int height = child.getHeight();
        float childCenter = getCenterOfView(child);
        float fromCenter = (mCoveflowCenter - childCenter);

        int margin = -(int) (MAX_MARGIN * fromCenter / width);
        int marginZ = (int) (fromCenter  *0.5);        
        int dz = Math.abs(marginZ); 
        mCamera.translate(margin, 0, dz);
        mCamera.rotateY(-rotationAngle);
 
        mCamera.getMatrix(imageMatrix);        
        imageMatrix.preTranslate(-(width / 2), -(height / 2));
        imageMatrix.postTranslate((width / 2), (height / 2));        
        mCamera.restore();
    }

 

posted @ 2012-12-21 11:10  lipeil  阅读(1755)  评论(0编辑  收藏  举报