自定义日出日落动画

背景

最近在使用某一款天气软件的时候发现了它的一个日出日落的动画,感觉还不错,后面就自己动手撸了一个源码地址。

分析

我们先对这个动画元素进行分析:

  1. 需要一条曲线。
  2. 需要一个沿着曲线运动的小太阳。
  3. 需要一个跟着太阳一起运动的阴影面。

好了我们直接开始

首先我们定义一个自定义View,然后初始化一些我们上面分析到的元素

 //曲线初始化
        mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPathPaint.setStyle(Paint.Style.STROKE);
        mPathPaint.setStrokeWidth(2);
        mPathPaint.setColor(Color.parseColor("#ffffff"));
        PathEffect effects = new DashPathEffect(new float[]{10, 10, 10, 10}, 0);
        mPathPaint.setPathEffect(effects);

        //日出动画阴影部分初始化
        mAnmationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mAnmationPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mAnmationPaint.setColor(Color.parseColor("#32ffffff"));

        //开始坐标的XY
        mStartPointX = dp2px(9);
        mStartPointY = dp2px(80);

        //结束坐标的XY
        mEndPointX = dp2px(139);
        mEndPointY = mStartPointY;

        //太阳的移动坐标的XY
        mMovePointX = mStartPointX;
        mMovePointY = mStartPointY;

        //圆的半径
        mRadius = dp2px(74);

        //圆心坐标
        mCirclePointX = dp2px(74);
        mCirclePointY = dp2px(115);

        //圆的初始化
        mRectF = new RectF(mCirclePointX - mRadius, mCirclePointY - mRadius, mCirclePointX + mRadius, mCirclePointY + mRadius);

接下来就是我们绘制的代码

if (isNeedSun) {
            //画曲线
            canvas.save();
            canvas.clipRect(mStartPointX, 0, mEndPointX, mStartPointY, Region.Op.INTERSECT);
            canvas.clipRect(mMovePointX - mBitmapW / 2, mMovePointY - mBitmapH / 2, mMovePointX + mBitmapW / 2, mMovePointY + mBitmapH / 2, Region.Op.DIFFERENCE);
            canvas.drawArc(mRectF, 200, 140, true, mPathPaint);
            //画透明背景用圆的角度来控制
            canvas.clipRect(mStartPointX, 0, mMovePointX, mStartPointY, Region.Op.INTERSECT);
            canvas.drawArc(mRectF, 200, 140, true, mAnmationPaint);
            canvas.restore();

            //画小太阳
            canvas.drawBitmap(mSunBitmap, mMovePointX - mBitmapW, mMovePointY - mBitmapH, null);

        } else if (mNotUp || mHasDown) {
            //画曲线
            canvas.save();
            canvas.clipRect(mMovePointX - mBitmapW / 2, mMovePointY - mBitmapH / 2, mMovePointX + mBitmapW / 2, mMovePointY + mBitmapH / 2, Region.Op.DIFFERENCE);
            canvas.clipRect(0, 0, getWidth(), mStartPointY, Region.Op.INTERSECT);
            canvas.drawCircle(mCirclePointX, mCirclePointY, mRadius, mPathPaint);
            canvas.restore();

            if (mNotUp) {
                //画小太阳
                canvas.drawBitmap(mSunBitmap, mStartPointX - mBitmapW, mStartPointY - mBitmapH, null);
            } else {
                canvas.drawBitmap(mSunBitmap, mEndPointX - mBitmapW, mEndPointY - mBitmapH, null);
            }
        } else {
            //这里不绘制小太阳,只有曲线
            canvas.save();
            canvas.clipRect(0, 0, getWidth(), mStartPointY, Region.Op.INTERSECT);
            canvas.drawCircle(mCirclePointX, mCirclePointY, mRadius, mPathPaint);
            canvas.restore();
        }

最后就是通过我们外部的控制来实现小太阳的动画

mSunBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.daily_deatil_sun);
            mBitmapW = mSunBitmap.getWidth() / 2;
            mBitmapH = mSunBitmap.getHeight() / 2;
            mNotUp = false;
            isNeedSun = true;
            mHasDown = false;
            ValueAnimator progressAnimator = ValueAnimator.ofFloat(210, 330);
            progressAnimator.setDuration(3000);
            progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    /**每次在初始值和结束值之间产生的一个平滑过渡的值,逐步去更新进度*/
                    float x = (float) animation.getAnimatedValue();
                    if ((x - 210) <= (120 * a)) {
                        mMovePointX = mCirclePointX + (int) (mRadius * (Math.cos(x * 3.14 / 180)));
                        mMovePointY = mCirclePointY + (int) (mRadius * (Math.sin(x * 3.14 / 180)));
                        invalidate();
                    } else {
                        return;
                    }
                }
            });
            progressAnimator.setInterpolator(new LinearInterpolator());
            progressAnimator.start();

最后附上源码地址和简单看一下效果图:

自定义日出日落动画_第1张图片
曲线效果图

你可能感兴趣的:(自定义日出日落动画)