admin 管理员组

文章数量: 887021

android绘制3d字符串,Android

/**

* 使用camera实现3d效果的自定义控件

*/

public class Camera3DView extends View {

//存放bitmap资源文件id的集合

private List bitmapResourceIds;

//用于3d变换

private Camera camera;

//用于变换的矩阵

private Matrix matrix;

//view的宽高

private float viewWidth, viewHeight;

//是否绘制完毕

private boolean isDrawFinished = false;

public static final int VERTICAL = LinearLayout.VERTICAL;

public static final int HORIZONTAL = LinearLayout.HORIZONTAL;

//旋转方向

private int orientation = VERTICAL;

//旋转轴,所有旋转操作无外乎两个玩意,一个是旋转轴,一个是旋转角度

//VERTICAL时使用rotateY,HORIZONTAL时使用rotateX

private float rotatePivotX, rotatePivotY;

//旋转角度

private float degress;

//最大旋转角度

private float maxDegress = 90;

//当前图片索引

private int currentIndex;

//下个显示图片索引

private int nextIndex;

//上个显示图片索引

private int preIndex;

private Paint mPaint;

//是否前进

private boolean isForward = true;

private ValueAnimator valueAnimator;

private boolean isAnimatiorRunning;

public Camera3DView(Context context) {

this(context, null);

}

public Camera3DView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public Camera3DView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init() {

bitmapResourceIds = new ArrayList<>();

camera = new Camera();

matrix = new Matrix();

mPaint = new Paint();

isDrawFinished = false;

}

/**

* 添加图片

*

* @param resId

*/

public void addResId(int resId) {

bitmapResourceIds.add(resId);

if (isDrawFinished) {

invalidate();

}

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

viewWidth = w;

viewHeight = h;

isDrawFinished = true;

initBitmaps();

resetIndex();

}

private void initBitmaps() {

for (int i = 0; i < bitmapResourceIds.size(); i++) {

int resID = bitmapResourceIds.get(i);

getBitmapScale(resID, viewWidth, viewHeight);

}

}

/**

* 旋转一面后,调用重置索引

*/

public void resetIndex() {

int listSize = bitmapResourceIds.size();

if (isForward) {//前进或者向下

currentIndex++;

if (currentIndex > listSize - 1) {

currentIndex = 0;

}

} else {

currentIndex--;

if (currentIndex < 0)

currentIndex = listSize - 1;

}

nextIndex = currentIndex + 1;

preIndex = currentIndex - 1;

if (nextIndex > listSize - 1)

nextIndex = 0;//循环切换

if (preIndex < 0)

preIndex = listSize - 1;

this.degress = 0;

rotatePivotX = 0;

rotatePivotY = 0;

isForward = true;

invalidate();

}

public void setDegress(int degress) {

this.degress = degress;

//VERTICAL时使用rotateY,HORIZONTAL时使用rotateX

if (orientation == HORIZONTAL) {

//x方向旋转轴随degress的变大不断下移

rotatePivotX = degress / maxDegress * viewWidth;

} else {

//y方向旋转轴随degress的变大不断右移

rotatePivotY = degress / maxDegress * viewHeight;

}

//刷新

invalidate();

}

@Override

protected void onDraw(Canvas canvas) {

//VERTICAL时使用rotateY,HORIZONTAL时使用rotateX

if (orientation == VERTICAL) {

//如果是前进,则画当前图,后退则画上一张图,注释用的是前进情况

matrix.reset();

camera.save();

//旋转角度 0 - -maxDegress

camera.rotateX(-degress);

camera.getMatrix(matrix);

camera.restore();

//绕着图片top旋转

matrix.preTranslate(-viewWidth / 2f, 0);

//旋转轴向下平移,则图片也向下平移

matrix.postTranslate(viewWidth / 2f, rotatePivotY);

//如果是前进,则画当前图,后退则画上一张图,因为后退时,这里画的是动画下方出来的图片,而下方的图片是前一张图

canvas.drawBitmap(getBitmapScale(bitmapResourceIds.get(isForward ? currentIndex : preIndex), viewWidth, viewHeight),

matrix, mPaint);

//在处理下一张图片

matrix.reset();

camera.save();

//旋转角度 maxDegress - 0

camera.rotateX(maxDegress - degress);

camera.getMatrix(matrix);

camera.restore();

//绕着图片bottom旋转

matrix.preTranslate(-viewWidth / 2f, -viewHeight);

//旋转轴向下平移,则图片也向下平移

matrix.postTranslate(viewWidth / 2f, rotatePivotY);

//如果是前进,则画下一张图,后退则画当前图,后退时,这边代码画的是动画上方的图片,上方的图片是当前图片

canvas.drawBitmap(getBitmapScale(bitmapResourceIds.get(isForward ? nextIndex : currentIndex), viewWidth, viewHeight),

matrix, mPaint);

} else {

//如果是前进,则画当前图,后退则画上一张图,注释用的是前进情况

matrix.reset();

camera.save();

//旋转角度 0 - maxDegress

camera.rotateY(degress);

camera.getMatrix(matrix);

camera.restore();

//绕着图片left旋转

matrix.preTranslate(0, -viewHeight / 2);

//旋转轴向右平移,则图片也向右平移

matrix.postTranslate(rotatePivotX, viewHeight / 2);

//如果是前进,则画当前图,后退则画上一张图,因为后退时,这里画的是动画右方出来的图片,而右方的图片是前一张图

canvas.drawBitmap(getBitmapScale(bitmapResourceIds.get(isForward ? currentIndex : preIndex), viewWidth, viewHeight),

matrix, mPaint);

//在处理下一张图片

matrix.reset();

camera.save();

//旋转角度 -maxDegress - 0

camera.rotateY(-maxDegress + degress);

camera.getMatrix(matrix);

camera.restore();

//绕着图片right旋转

matrix.preTranslate(-viewWidth, -viewHeight / 2f);

//旋转轴向右平移,则图片也向右平移

matrix.postTranslate(rotatePivotX, viewHeight / 2f);

//如果是前进,则画下一张图,后退则画当前图,后退时,这边代码画的是动画左方的图片,左方的图片是当前图片

canvas.drawBitmap(getBitmapScale(bitmapResourceIds.get(isForward ? nextIndex : currentIndex), viewWidth, viewHeight),

matrix, mPaint);

}

}

/**

* 获取缩放图片

*

* @param resId

* @param width

* @param height

* @return

*/

private Bitmap getBitmapScale(int resId, float width, float height) {

if (ImageCache.getInstance().getBitmapFromMemCache(String.valueOf(resId)) != null) {

return ImageCache.getInstance().getBitmapFromMemCache(String.valueOf(resId));

}

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);

Bitmap bitmapDst = Bitmap.createScaledBitmap(bitmap, (int) width, (int) height, false);

bitmap.recycle();

ImageCache.getInstance().addBitmapToMemoryCache(String.valueOf(resId)

, bitmapDst);

return bitmapDst;

}

public void next() {

createAnimator();

if (!isAnimatiorRunning) {

isForward = true;

isAnimatiorRunning = true;

valueAnimator.start();

}

}

public void pre() {

createAnimator();

if (!isAnimatiorRunning) {

isForward = false;

isAnimatiorRunning = true;

valueAnimator.reverse();

}

}

private void createAnimator() {

if (valueAnimator == null) {

valueAnimator = ValueAnimator.ofFloat(0, 1f);

valueAnimator.setDuration(500);

valueAnimator.setInterpolator(new LinearInterpolator());

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

degress = maxDegress * animation.getAnimatedFraction();

setDegress((int) degress);

}

});

valueAnimator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

resetIndex();

isAnimatiorRunning = false;

}

});

}

}

public void setOrientation(int orientation) {

this.orientation = orientation;

}

}

本文标签: android绘制3d字符串 Android