前言
屬性動畫
和 貝賽爾曲線
已經出來很久了,很多前輩寫了很多不錯的文章,在此不得不感謝這些前輩無私奉獻的開源精神,能讓我們站在巨人的肩膀上望得更遠.如果你對屬性動畫還不太了解可以看看郭林的文章,貝塞爾曲線的使用可以參考Lin_Zero
效果圖
image
實現思路
整體實現思路還是比較簡單的,首先要有一個容器來裝點出來的贊,然后通過屬性動畫對贊加一些動畫效果,最后通過貝塞爾曲線使其做不規則的運動。
代碼實現
好了,思路有了,咱們也廢話不多說,直接上代碼,首先是所有動畫的實現
/**
* 實現點贊效果 平移 縮放 漸變
* @param imageView
* @return 所有動畫的集合
*/
private AnimatorSet getAnimator(final ImageView imageView) {
//縮放
ObjectAnimator scaleX = ObjectAnimator.ofFloat(imageView,"scaleX",0.4f,1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(imageView,"scaleY",0.4f,1f);
//alpha
ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView,"alpha",0.4f,1f);
//執行三個動畫
AnimatorSet enterSet = new AnimatorSet();
enterSet.setDuration(500);
enterSet.playTogether(scaleX,scaleY,alpha);
//用貝塞爾曲線控制點贊的走向
ValueAnimator bezierAnimator = getBezierAnimator(imageView);
//綜合所有動畫
AnimatorSet set = new AnimatorSet();
//按順序執行
set.playSequentially(enterSet,bezierAnimator);
//添加插值器
set.setInterpolator(interpolators[random.nextInt(3)]);
set.setTarget(imageView);
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
removeView(imageView);
}
});
return set;
}
然后是通過貝塞爾曲線對贊的走向做了控制,代碼如下
/**
* 通過貝塞爾曲線對贊走向做控制
* @param imageView
* @return
*/
private ValueAnimator getBezierAnimator(final ImageView imageView) {
//準備控制貝塞爾曲線的四個點(起始點p0,拐點p1,拐點p2,終點p3)
PointF pointF0 = new PointF((mWidth-dWidth)/2,mHeight-dHeight);
PointF pointF1 = getTogglePointF(1);
PointF pointF2 = getTogglePointF(2);
PointF pointF3 = new PointF(random.nextInt(mWidth),0);
BezierEvaluator bezierEvaluator = new BezierEvaluator(pointF1,pointF2);
final ValueAnimator animator = ValueAnimator.ofObject(bezierEvaluator,pointF0,pointF3);
animator.setDuration(3000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
PointF pointF = (PointF) valueAnimator.getAnimatedValue();
//控制屬性變化
imageView.setX(pointF.x);
imageView.setY(pointF.y);
imageView.setAlpha(1 - valueAnimator.getAnimatedFraction());//從可見到不可見
}
});
return animator;
}
這是估值器的實現
/**
*
* @author Liuzj
* 功能描述: 貝塞爾曲線估值器
*/
public class BezierEvaluator implements TypeEvaluator<PointF> {
/**
* 拐點
*/
private PointF pointF1;
private PointF pointF2;
public BezierEvaluator(PointF pointF1,PointF pointF2) {
this.pointF1 = pointF1;
this.pointF2 = pointF2;
}
@Override
public PointF evaluate(float v, PointF pointF, PointF t1) {
PointF point = new PointF();
point.x = pointF.x*(1-v)*(1-v)*(1-v)
+3*pointF1.x*v*(1-v)* (1-v)
+3*pointF2.x*v*v*(1-v)
+t1.x*v*v*v;
point.y = pointF.y*(1-v)*(1-v)*(1-v)
+3*pointF1.y*v*(1-v)* (1-v)
+3*pointF2.y*v*v*(1-v)
+t1.y*v*v*v;
return point;
}
}
可能有的朋友對evaluate
方法里的實現有所疑惑,其實調用貝塞爾的三階公式,然后把點跟公式里的對應上就ok了
image
END!
Thanks