自定义日出日落曲线动画

来源:互联网 发布:sql count 1 编辑:程序博客网 时间:2024/04/29 09:23

背景

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

分析

我们先对这个动画元素进行分析:
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();

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

曲线效果图

原创粉丝点击