Android动画之烟花

作者: 徐影魔 | 来源:发表于2018-05-07 17:05 被阅读77次
    boom.gif

    思路

    主要步骤就是上升和爆炸。都是用属性动画实现的。使用属性动画的时候,该属性必须要有set和get方法。

     ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(boomView, "flyFraction", 0, 1);
            objectAnimator.setDuration(700);
    
            objectAnimator.setInterpolator(new DecelerateInterpolator());
            ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(boomView, "boomFraction", 0, 1);
            objectAnimator1.setDuration(400);
    
            final AnimatorSet set = new AnimatorSet();
            set.playSequentially(objectAnimator, objectAnimator1);
    
            boomView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    set.start();
    
                }
            });
    
            set.addListener(new AnimatorListenerAdapter() {
    
                @Override
                public void onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);
                    //改变颜色
                    color = Color.argb(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));
                    boomView.setColor(color);
                    DrawableCompat.setTint(imageView.getDrawable(),color);
    
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    //循环播放
                    set.start();
                }
            });
    

    上升过程

    上升过程用canvas画一个矩形,从0-3/4高度。

    if(flyFraction!=1){
                int y = (int) ((1 - flyFraction * 3 / 4) * canvas.getHeight());
                mPaint.setColor(color);
                canvas.drawRect(canvas.getWidth() / 2 - 5, y, canvas.getWidth() / 2 + 5, y + 10, mPaint);
            }
    

    爆炸过程

    爆炸粒子的围绕半径逐渐变大。(使用极坐标可以很容易地在画小圆点)

    public class BoomUtil {
    
        private Paint mPaint;
        private int pointCount;//爆炸时的粒子数量
        private int radiusMax;//最大爆炸半径
        private int pointRadius;//粒子半径
    
    
        public BoomUtil(int pointCount, int radiusMax, int pointRadius) {
            this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            this.pointCount = pointCount;
            this.radiusMax = radiusMax;
            this.pointRadius = pointRadius;
        }
    
        public void drawBoom(Canvas canvas, int cx,int cy,float fraction,int color) {
            mPaint.setColor(color);
            mPaint.setAlpha((int) (255 * (1 - fraction)));
            int radius = (int) (radiusMax * fraction);
            for (int i = 0; i < pointCount; i++) {
                double angle = i * 2 * Math.PI / pointCount;
                float x = (float) Math.cos(angle) * radius+cx;
                float y = (float) Math.sin(angle) * radius+cy;
                canvas.drawCircle(x, y, pointRadius, mPaint);
            }
        }
    }
    

    BoomView

    public class BoomView extends View {
    
        Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        private float flyFraction = 0;
        private float boomFraction = 0;
        private BoomUtil boomUtil;
        private Random random;
        private int color;
    
        public int getColor() {
            return color;
        }
    
        public void setColor(int color) {
            this.color = color;
        }
    
        public BoomView(Context context) {
            super(context);
            initBoomUtil();
        }
    
        public BoomView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initBoomUtil();
        }
    
        private void initBoomUtil() {
            boomUtil = new BoomUtil(12, 200, 12);
    
        }
    
        public float getBoomFraction() {
            return boomFraction;
        }
    
        public void setBoomFraction(float boomFraction) {
            this.boomFraction = boomFraction;
            invalidate();
        }
    
        public float getFlyFraction() {
            return flyFraction;
        }
    
        public void setFlyFraction(float flyFraction) {
            this.flyFraction = flyFraction;
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(flyFraction!=1){
                int y = (int) ((1 - flyFraction * 3 / 4) * canvas.getHeight());
                mPaint.setColor(color);
                canvas.drawRect(canvas.getWidth() / 2 - 5, y, canvas.getWidth() / 2 + 5, y + 10, mPaint);
            }
    
            if (boomFraction != 0) {
                boomUtil.drawBoom(canvas, canvas.getWidth() / 2, canvas.getHeight() / 4, boomFraction, color);
            }
        }
    }
    

    总结

    把一个复杂的过程分解为多个简单的过程,思路瞬间清晰了。
    github源码

    相关文章

      网友评论

        本文标题:Android动画之烟花

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