2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > android 烟花动画效果图 Android烟花效果(SurfaceView实现)

android 烟花动画效果图 Android烟花效果(SurfaceView实现)

时间:2020-11-05 18:33:37

相关推荐

android 烟花动画效果图 Android烟花效果(SurfaceView实现)

/** * 直播页面点赞特效,采用SurfaceView绘制 * 与普通控件使用方法类似,点赞是只需要调用startBomb()即可 */

public class BombView extends SurfaceView implements SurfaceHolder.Callback {

private static final int MAX_BUBBLE_COUNT = 90;

private SurfaceHolder mHolder;

private DrawTask mDrawTask; // 绘制UI的线程

private Paint mPaint; // 绘制需要使用的画刷

private FuseView mFuseView; // 引导的view

private boolean mIsDismiss = false; //是否处于消失阶段

private int mWidth; // 控件的宽度

private int mHeight; // 控件的高度

private int mBombX; // 旋转的中心X

private int mBombY; // 旋转的中心Y

private int dx = 0; // 引导view在坐抛物线运动时在x轴的增量

private Bitmap[] mDrawables; // 存放需要展示的图

private int[] mDrawableResIDs; // 存放需要展示的图

private List mBubbles = Collections.synchronizedList(new LinkedList()); // 用于存放点赞信息

private Random mRandom = new Random(); // 用于产生随机数

public BombView(Context context, AttributeSet attrs) {

super(context, attrs);

mHolder = getHolder();

mHolder.addCallback(this);

mHolder.setKeepScreenOn(true);

mHolder.setFormat(PixelFormat.TRANSPARENT);

mPaint = new Paint();

mDrawableResIDs = new int[] {

R.drawable.praise_eight,

R.drawable.praise_one,

R.drawable.praise_third,

R.drawable.praise_two,

R.drawable.praise_five,

R.drawable.praise_four,

R.drawable.praise_seven,

R.drawable.praise_six,

};

mDrawables = new Bitmap[mDrawableResIDs.length];

}

@Override

protected void onDraw(final Canvas canvas) {

if (canvas != null) {

canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); // 清空界面

if (mFuseView == null) {

return;

}

if (mFuseView.y+mFuseView.bitmap.getHeight()/2 > mBombY) {

mPaint.setAlpha(255);

if (mFuseView.x+mFuseView.bitmap.getWidth()/2 > mWidth/2) { // 抛物线

mFuseView.scale = dx*1.5f/mWidth + 1f;

canvas.save();

mFuseView.x = mWidth*7/8 - dx;

mFuseView.y = (int) getY(dx);

canvas.scale(mFuseView.scale, mFuseView.scale, mFuseView.x+mFuseView.bitmap.getWidth()/2, mFuseView.y+mFuseView.bitmap.getHeight()/2);

canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint);

canvas.restore();

dx += dip2px(4);

} else { // 直线上升

canvas.save();

canvas.scale(mFuseView.scale, mFuseView.scale, mFuseView.x+mFuseView.bitmap.getWidth()/2, mFuseView.y+mFuseView.bitmap.getHeight()/2);

canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint);

canvas.restore();

mFuseView.y -= dip2px(5);

}

postDelayed(mDrawTask, 5);

} else {

if (!mIsDismiss) {

mIsDismiss = mBubbles.size() > 0 && mBubbles.get(0).top < mWidth*9/20;

}

for (int i=mBubbles.size()-1; i>=0; i--) { // 绘制气泡

drawBubble(canvas, mBubbles.get(i));

}

// 大爱心放大消失

mFuseView.x = mBombX - mFuseView.bitmap.getWidth()/2;

mFuseView.y = mBombY - mFuseView.bitmap.getHeight()/2;

mFuseView.scale += 0.2;

mFuseView.alpha = (int)((5-mFuseView.scale)*85);// ps:85 = 255/3 根据缩放倍数来计算透明度

if (mFuseView.alpha > 0) {

mPaint.setAlpha(mFuseView.alpha);

canvas.save();

canvas.scale(mFuseView.scale, mFuseView.scale, mBombX, mBombY);

canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint);

canvas.restore();

}

if (mBubbles.size() > 0) {

postDelayed(mDrawTask, 10);

} else {

release();

}

}

}

}

private void drawBubble(Canvas canvas, Bubble bubble) {

if (bubble.top + bubble.bitmap.getHeight()/2 > mWidth/2) {

bubble.top = bubble.top - dip2px(2);

return;

}

if (mIsDismiss) {

bubble.alpha -= 12;

if (bubble.alpha < 0) {

mBubbles.remove(bubble);

return;

}

}

bubble.top -= dip2px(0.5f);

if (bubble.scale < 1.2f) {

bubble.scale += 0.015f;

}

mPaint.setAlpha(bubble.alpha);

canvas.save();

canvas.scale(bubble.scale, bubble.scale, bubble.left+bubble.bitmap.getWidth()/2, bubble.top+bubble.bitmap.getHeight()/2);

canvas.rotate(bubble.rotate, mBombX, mBombY);

canvas.drawBitmap(bubble.bitmap, bubble.left, bubble.top, mPaint);

canvas.restore();

}

/** * 开始绘制爆炸彩蛋,如果上一个效果还没结束,则不处理新的 */

public void startBomb() {

if (mFuseView != null) {

return;

}

initFuseView();

generateBubble(MAX_BUBBLE_COUNT);

dx = 0;

mIsDismiss = false;

post(mDrawTask);

}

/** * 初始化引导 */

private void initFuseView() {

mFuseView = new FuseView();

mFuseView.x = mWidth*7/8;

mFuseView.y = mHeight*17/20;

mFuseView.bitmap = BitmapUtil.readBitmap(getResources(), R.drawable.praise_five);

}

/** * 添加点赞,会对传入的个数进行处理 *@param count */

private void generateBubble(int count) {

for (int i = 0; i < count; i++) {

Bubble bubble = new Bubble();

bubble.bitmap = getRandBitmap();

bubble.alpha = 155 + mRandom.nextInt(100);

bubble.scale = 0.6f + mRandom.nextFloat()*0.4f;

// bubble.rotate = mRandom.nextInt(360);

bubble.rotate = 360*i/count; // 由于绘制时还需要缩放,不然可以使用增量旋转,即不用每次都restore

if (bubble.rotate > 180) { // 反向旋转

bubble.rotate = bubble.rotate - 360;

}

bubble.left = mWidth/2 - bubble.bitmap.getWidth()/2;

float offset = 0;

if (i % 2 == 0) {

offset = mWidth*0.1f + mWidth*0.15f * i/count;

}

if (i%3 == 0) {

offset = mWidth*0.25f + mWidth*0.15f * i/count;

}

if (i%5 == 0) {

offset = mWidth*0.4f + mWidth*0.12f * mRandom.nextFloat();

}

bubble.top = offset - bubble.bitmap.getHeight();

mBubbles.add(0, bubble);

}

mBubbles.get(0).top = mWidth*0.52f - dip2px(5); // 以第一个气泡的位置判断是否该dismiss

mBubbles.get(0).alpha = 1; // 防止正在消失时突然显现出来

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

this.mWidth = width;

this.mHeight = height;

mBombX = mWidth/2;

mBombY = mWidth/2;

}

class Bubble {

public Bitmap bitmap;

public float scale = 1.0f; // 缩放

public float top = 0f; // 偏移

public float left = 0f; // 偏移

public int rotate = 0; // 旋转

public int alpha = 255; // 透明度

public Bubble() {

this.bitmap = getRandBitmap();

}

}

class FuseView {

public Bitmap bitmap;

public float scale;

public int alpha;

public int x;

public int y;

}

// 抛物线

private float getY(float x) {

return mHeight*10/11 - 0.009f * x * x;

}

public void release() {

mFuseView = null; // 防止过度绘制

for (Bitmap bitmap : mDrawables) {

if (bitmap != null && !bitmap.isRecycled()) {

bitmap.recycle();

}

}

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。