android path animation

 1 Introduction

             Today, the project uses a function similar to WeChat sending, that kind of screen floating expression, so I analyzed and studied it for a while. The technology used should be path animation. I don’t know if this is correct or not. Anyway, it is just drawing 1 A path line, and then the object moves according to this path. So call him path animation.

The first problem to be solved in path animation is how to draw this path? Then how to get the coordinates of all points on the path after the path is drawn?

       To solve these two problems here, look at a class PathMeasure This class receives a path object, and then you can get the coordinate value of the length ratio according to pathMeasure.getPosTan(). These two problems are solved directly. Draw a path with path and then take a point, move the object dynamically, it becomes a path animation. Is it very simple.

 

2. Look at the effect

3. Core code

/**
 * sprinkle flowers
 *
 * @author yd
 *
  
 Knowledge points used:
    1, android attribute animation
    2. Path path drawing
    3. Bezier curve
 *
 */
public class FllowerAnimation extends View implements AnimatorUpdateListener {
 
    /**
     * Animated property values ​​changed
     */
    private float phase1 = 0f;
    private float phase2 = 0f;
    private float phase3 = 0f;
 
    /**
     * Ball collection
     */
    private List<fllower> fllowers1 = new ArrayList<fllower>();
    private List<fllower> fllowers2 = new ArrayList<fllower>();
    private List<fllower> fllowers3 = new ArrayList<fllower>();
 
    /**
     * The duration of the animation
     */
    private int time = 4000;
    /**
     * Animation interval
     */
    private int delay = 500;
 
    /**
     * resource 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);
 
    }
 
    /**
     * width
     */
    private int width = 0;
    /**
     * high
     */
    private int height = 0;
 
    /**
     * The number of curve heights is divided
     */
    private int quadCount = 10;
    /**
     * Curvature
     */
    private float intensity = 0.2f;
 
    /**
     * Number of the first batch
     */
    private int fllowerCount = 4;
 
    /**
     * Create flower
     */
    private void builderFollower(int count, List<fllower> 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<cpoint> points = builderPath(CPoint);
            drawFllowerPath(path, points);
            Fllower fllower = new Fllower();
            fllower.setPath(path);
            fllowers.add(fllower);
        }
 
    }
 
    /**
     * draw curves
     * @param path
     * @param points
     */
    private void drawFllowerPath(Path path, List<cpoint> 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 path
                if (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);
                }
            }
        }
    }
 
    /**
     * Amount of curve swing
     */
    private int range = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 70, getResources().getDisplayMetrics());
 
    /**
     * draw path
     *
     * @param point
     * @return
     */
    private List<cpoint> builderPath(CPoint point) {
        List<cpoint> points = new ArrayList<cpoint>();
        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;
    }
 
    /**
     * Brush
     */
    private Paint mPaint;
 
    /**
     * The coordinate position of the measurement path
     */
    private PathMeasure pathMeasure = null;
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
 
        drawFllower(canvas, fllowers1);
        drawFllower(canvas, fllowers2);
        drawFllower(canvas, fllowers3);
 
    }
 
    /**
     * Offset the height up, move the starting point out of the top of the screen
     */
    private float dy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40, getResources().getDisplayMetrics());
     
    /**
     *
     * @param canvas
     * @param fllowers
     */
    private void drawFllower(Canvas canvas, List<fllower> fllowers) {
        for (Fllower fllower : fllowers) {
            float[] pos = new float[2];
            canvas.drawPath(fllower.getPath(),mPaint);
            pathMeasure.setPath(flower.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);
    }
 
    /**
     * Follow the position of the new ball
     *
     * @param value
     * @param fllowers
     */
    private void updateValue(float value, List<fllower> fllowers) {
        for (Fllower fllower : fllowers) {
            fllower.setValue(value);
        }
    }
 
    /**
     * animation change callback
     */
    @Override
    public 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;
        }
    }
 
}

Download address: http://download.csdn.net/detail/hxc2008q/8473053

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326848797&siteId=291194637