一、简介 最近开始写一些文章记录一下以前的一些自己写的小项目或者是定义View积累,积灰的东西还是要多翻出来整理整理看看的。这个只完成了一部分燃起熄灭的动画,没有为何燃起火焰的动画,希望有兴趣的同学也可以接着完成并分享,话不多说,我们来看这两根萌萌的小蜡烛。 小蜡烛憋足气把火焰燃起,一下被旁边的哥们吹灭了 0^0 ,看起来还是萌气十足的啊。看着图大家应该能想到应该怎么实现了吧,自定义View!对了,但是具体要怎么把这个过程做好呢,跟着脚步一起来看一看吧。代码稍微有点多,大家耐心观看,有兴趣的同学可以从我的GITHUB上clone下来,对着代码看。 二、过程实现 蜡烛的绘制和动画
public abstract class ICandle { //蜡烛底部左下坐标 protected int mCurX; protected int mCurY; //蜡烛宽高 protected int mCandleWidth; protected int mCandleHeight; //蜡烛左眼坐标 protected Point mEyeLPoint; //蜡烛右眼坐标 protected Point mEyeRPoint; //蜡烛眼睛半径 protected int mEyeRadius; //眼睛间隔距离 protected int mEyeDevide; //身体颜色 protected int mCandleColor; //是否停止动画中 protected boolean mIsAnimStoping = false; //蜡烛芯坐标 protected Point mCandlewickPoint; public void initAnim(){ } public void stopAnim(){ } public void drawSelf(Canvas canvas){ } } 对应着这蜡烛还有代码,那就一目了然了。可能需要解释的应该就是下面的几个方法了public void initAnim(), stopAnim()初始化开始和结束动画需要的数据,小蜡烛将会实现这个方法,drawSelf(Canvas canvas)把画布传进来然后蜡烛自己绘制自己。 现在就是让我们来看一看小蜡烛身体内部构造的时候了,hiahiahiahia! 不对,和蜡烛生死相随的还有火焰呢!先来看看火焰吧,等下小蜡烛还要燃烧自己呢。 10086s Flame
好像也没什么毛病,首先是里面的区域,就是Flame啦,外面的呢,就是Flame先生燃烧自己散发的人性之光和飘散的骨灰(手动抹眼泪)。 来看一下Flame的实现吧。我们一步步分析。 private static float CHANGE_FACTOR = 20; private Paint mPaint; private Path mPath; //左下点坐标 private int mCurX; private int mCurY; //火焰宽度 private int mWidth; //火焰高度 private int mHeight; //记录初始高度 private int mPreHeight; //记录初始宽度 private int mPreWidth; //火焰顶部贝塞尔曲线控制点变化参数 private int mTopXFactor; private int mTopYFactor; //用于实现火焰的抖动 private Random mRandom; //光环半径 private int mHaloRadius; //正在燃烧 private boolean mIsFiring; //是否启动停止动画 private boolean mIsStopAnim = false; private boolean mFlagStop = false; private LinearGradient mLinearGradient; private RadialGradient mRadialGradient; private ValueAnimator mFlameAnimator; private ValueAnimator mHaloAnimator; 参数就是这些了,主要是我们的动画实现过程,也就是我们的属性动画ValueAnimator这里还有两个渲染类不知道大家用过没有,LinearGradient和RadialGradient不了解的同学可以直接点我的博文了解一下。LinearGradient绘制出了火焰,RadialGradient绘制除了发散的光芒。 初始化的过程我就不写了,大家对这代码看吧。那主要的就是小火焰的是怎么绘制出来的呢 show the code mPaint.setStyle(Paint.Style.FILL); mPaint.setShader(mLinearGradient); mPath.reset(); mPath.moveTo(mCurX, mCurY); mPath.quadTo(mCurX mWidth / 2, mCurY mHeight / 3, mCurX mWidth, mCurY); mPath.quadTo(mCurX mWidth / 2 ((1 - mRandom.nextFloat()) * CHANGE_FACTOR) mTopXFactor, mCurY - 2 * mHeight mTopYFactor, mCurX, mCurY); canvas.drawPath(mPath, mPaint); 这就是火焰flame的绘制,可以看到这里用到了二次贝塞尔曲线的绘制,不太清楚贝塞尔曲线的同学也可以点这波浪Loading动画(贝塞尔曲线)有简单的介绍,当时是用在一个水波的view里面。这里的绘制是以前面那个图里面的矩形为参照,我们再来看一下这个图(当然是加强版hiahia)。 那为什么上面的x坐标还加了mRandom.nextFloat()) * CHANGE_FACTOR呢?你想啊,火焰不是会左右晃动吗,利用一个随机来控制左右摆动咯。 mFlameAnimator = ValueAnimator.ofFloat(0, 4).setDuration(4000); mFlameAnimator.setRepeatCount(ValueAnimator.INFINITE); mFlameAnimator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float zeroToOne = (float) animation.getAnimatedValue(); if (zeroToOne |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|