android 路徑動畫製作

來源:互聯網
上載者:User

android 路徑動畫製作

1、前言

今天項目要用到一個類似發送麼麼噠,那種螢幕飄表情的功能,所以分析研究了一下,用到的技術應該是路徑動畫,不知道這樣就正不正確,反正就是畫一個路徑線,然後對象根據這個路徑去運動。所以就叫他路徑動畫了。

路徑動畫要首先要解決的問題就是怎麼畫這個路徑?然後路徑畫出來後怎麼取路徑上的所有點的座標值?

這裡解決這兩個問題就看一個類PathMeasure 這個類接收一個path對象,然後可以根據pathMeasure.getPosTan()可以得到長度比例的座標值。這兩個問題就直接搞定了。用path畫一個路徑然後取點,動態移動對象,就變成了路徑動畫了。是不是很簡單。

 

2、看效果

 

 

3、核心代碼

 

 

/** * 撒花 *  * @author yd *  用到的知識點: 1、android屬性動畫 2、Path路徑繪製 3、貝茲路徑 *  *  * * * * * * */public class FllowerAnimation extends View implements AnimatorUpdateListener {/** * 動畫改變的屬性值 */private float phase1 = 0f;private float phase2 = 0f;private float phase3 = 0f;/** * 小球集合 */private List fllowers1 = new ArrayList();private List fllowers2 = new ArrayList();private List fllowers3 = new ArrayList();/** * 動畫播放的時間 */private int time = 4000;/** * 動畫間隔 */private int delay = 500;/** * 資源ID *///private int resId = R.drawable.fllower_love;public FllowerAnimation(Context context) {super(context);init(context);//this.resId = resId;}@SuppressWarnings(deprecation)private void init(Context context) {WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);width = wm.getDefaultDisplay().getWidth();height = (int) (wm.getDefaultDisplay().getHeight() * 3 / 2f);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStrokeWidth(2);mPaint.setColor(Color.BLUE);mPaint.setStyle(Style.STROKE);pathMeasure = new PathMeasure();builderFollower(fllowerCount, fllowers1);builderFollower(fllowerCount , fllowers2);builderFollower(fllowerCount , fllowers3);}/** * 寬度 */private int width = 0;/** * 高度 */private int height = 0;/** * 曲線高度個數分割 */private int quadCount = 10;/** * 曲度 */private float intensity = 0.2f;/** * 第一批個數 */private int fllowerCount = 4;/** * 建立花 */private void builderFollower(int count, List fllowers) {int max = (int) (width * 3 / 4f);int min = (int) (width / 4f);Random random = new Random();for (int i = 0; i < count; i++) {int s = random.nextInt(max) % (max - min + 1) + min;Path path = new Path();CPoint CPoint = new CPoint(s, 0);List points = builderPath(CPoint);drawFllowerPath(path, points);Fllower fllower = new Fllower();fllower.setPath(path);fllowers.add(fllower);}}/** * 畫曲線 * @param path * @param points */private void drawFllowerPath(Path path, List points) {if (points.size() > 1) {for (int j = 0; j < points.size(); j++) {CPoint point = points.get(j);if (j == 0) {CPoint next = points.get(j + 1);point.dx = ((next.x - point.x) * intensity);point.dy = ((next.y - point.y) * intensity);} else if (j == points.size() - 1) {CPoint prev = points.get(j - 1);point.dx = ((point.x - prev.x) * intensity);point.dy = ((point.y - prev.y) * intensity);} else {CPoint next = points.get(j + 1);CPoint prev = points.get(j - 1);point.dx = ((next.x - prev.x) * intensity);point.dy = ((next.y - prev.y) * intensity);}// create the cubic-spline pathif (j == 0) {path.moveTo(point.x, point.y);} else {CPoint prev = points.get(j - 1);path.cubicTo(prev.x + prev.dx, (prev.y + prev.dy),point.x - point.dx, (point.y - point.dy),point.x, point.y);}}}}/** * 曲線搖擺的幅度 */private int range = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 70, getResources().getDisplayMetrics());/** * 畫路徑 *  * @param point * @return */private List builderPath(CPoint point) {List points = new ArrayList();Random random = new Random();for (int i = 0; i < quadCount; i++) {if (i == 0) {points.add(point);} else {CPoint tmp = new CPoint(0, 0);if (random.nextInt(100) % 2 == 0) {tmp.x = point.x + random.nextInt(range);} else {tmp.x = point.x - random.nextInt(range);}tmp.y = (int) (height / (float) quadCount * i);points.add(tmp);}}return points;}/** * 畫筆 */private Paint mPaint;/** * 測量路徑的座標位置 */private PathMeasure pathMeasure = null;@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawFllower(canvas, fllowers1);drawFllower(canvas, fllowers2);drawFllower(canvas, fllowers3);}/** * 高度往上位移量,把開始點移出螢幕頂部 */private float dy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40, getResources().getDisplayMetrics());/** *  * @param canvas * @param fllowers */private void drawFllower(Canvas canvas, List fllowers) {for (Fllower fllower : fllowers) {float[] pos = new float[2];canvas.drawPath(fllower.getPath(),mPaint);pathMeasure.setPath(fllower.getPath(), false);pathMeasure.getPosTan(height * fllower.getValue(), pos, null);canvas.drawCircle(pos[0], pos[1], 10, mPaint);//Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);//canvas.drawBitmap(bitmap, pos[0], pos[1] - dy, null);//bitmap.recycle();}}public void startAnimation() {ObjectAnimator mAnimator1 = ObjectAnimator.ofFloat(this, phase1, 0f,1f);mAnimator1.setDuration(time);mAnimator1.addUpdateListener(this);mAnimator1.start();mAnimator1.setInterpolator(new AccelerateInterpolator(1f));ObjectAnimator mAnimator2 = ObjectAnimator.ofFloat(this, phase2, 0f,1f);mAnimator2.setDuration(time);mAnimator2.addUpdateListener(this);mAnimator2.start();mAnimator2.setInterpolator(new AccelerateInterpolator(1f));mAnimator2.setStartDelay(delay);ObjectAnimator mAnimator3 = ObjectAnimator.ofFloat(this, phase3, 0f,1f);mAnimator3.setDuration(time);mAnimator3.addUpdateListener(this);mAnimator3.start();mAnimator3.setInterpolator(new AccelerateInterpolator(1f));mAnimator3.setStartDelay(delay * 2);}/** * 跟新小球的位置 *  * @param value * @param fllowers */private void updateValue(float value, List fllowers) {for (Fllower fllower : fllowers) {fllower.setValue(value);}}/** * 動畫改變回調 */@Overridepublic void onAnimationUpdate(ValueAnimator arg0) {updateValue(getPhase1(), fllowers1);updateValue(getPhase2(), fllowers2);updateValue(getPhase3(), fllowers3);Log.i(tag, getPhase1() + );invalidate();}public float getPhase1() {return phase1;}public void setPhase1(float phase1) {this.phase1 = phase1;}public float getPhase2() {return phase2;}public void setPhase2(float phase2) {this.phase2 = phase2;}public float getPhase3() {return phase3;}public void setPhase3(float phase3) {this.phase3 = phase3;}private String tag = this.getClass().getSimpleName();private class CPoint {public float x = 0f;public float y = 0f;/** x-axis distance */public float dx = 0f;/** y-axis distance */public float dy = 0f;public CPoint(float x, float y) {this.x = x;this.y = y;}}}
 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.