Path animation

1.1. Initialization

Set whether to close after initialization:

Path path = new Path();

PathMeasure pathMeasure1 = new PathMeasure();

/ * *

* Whether the path is closed forceClosed

* /

pathMeasure1.setPath(path, true);

Copy the code

Or we can initialize the constructor directly:

PathMeasure pathMeasure2 = new PathMeasure(path, true);

Copy the code

1.2. Obtain the path length

/ * *

* Path length, which measures the length of the current path state if forceClosed istrue, the measurement is the closure length of the path regardless of whether the path is closed.

* The length obtained is the length of the current curve.

* /

System.out.println(pathMeasure1.getLength());

Copy the code

1.3. Check whether the path is closed

/ * *

* Check whether a path is closed

* /

System.out.println(pathMeasure1.isClosed());

Copy the code

1.4 jump to the next curve of the path

/ * *

* Jump to the next curve,trueIndicates that the jump succeeds.falseIndicates that the jump fails.

 *

* /

System.out.println(pathMeasure1.nextContour());

Copy the code

1.5. Intercept a fragment of the path

/ * *

* Intercepts a fragment from startD to stopD in the entire Path, or returns it if it is not in rangefalseAfter intercepting, add Path to DST.

* startWithMoveTo: Iftrue, the intercepted Path fragment remains intact and is added to DST. If it isfalse, then the start point of the intercepted Path fragment moves to the last point of DST to ensure the continuity of DST Path.

* Need to disable hardware acceleration, setLayerType(LAYER_TYPE_SOFTWARE, NULL).

* Path intercepts are either clockwise path.direction. CW or counterclockwise path.direction. CCW in the upper left corner.

* /

boolean isSuccess = pathMeasure1.getSegment(0, 10, new Path(), true);

Copy the code

1.6. Obtain the position of a certain length on the path and its tangent value

/ * *

 *

* Gets the position of a length along the path and the value of the tangent of that position

* Distance: distance to the start of the path, 0<=distance<=pathMeasure1.getLength()

Pos [0] is the x coordinate and pos[1] is the y coordinate

* The tangent value of the position coordinates is the tangent value of the Angle between the origin and the X-axis. Tan [0] is the x-coordinate, tan[1] is the y-coordinate, is the corresponding point of the circle with radius 1, y/ X is the tangent value

Atan (double d) input radian value is also the result of the tangent value, atan2(double x, double y) input tangent point coordinate value.

* If you want the moving point to be rotated to coincide with the tangent line, the rotation Angle should be the same as the tangent Angle.

* /

boolean isTanSuccess = pathMeasure1.getPosTan(1, new float[]{1F, 1F}, new float[]{1F, 1F});

Copy the code

1.7. Obtain the position of a certain length along the path and the matrix of the tangent value of the position.

/ * *

* Returns a matrix of positions at a length along the path and the tangent values of that position.

* Distance: The distance from the start of the Path

* matrix: Matrix stores different content depending on the flags Settings.

* flags: Specifies what is stored in the matrix. POSITION_MATRIX_FLAG: Obtains location information. TANGENT_MATRIX_FLAG: Gets edge cutting information to rotate the image according to Path.

* /

boolean isMatrixSuccess = pathMeasure1.getMatrix(1, new Matrix(), PathMeasure.POSITION_MATRIX_FLAG);

Copy the code

1.8. Load the instance

While initializing the data, listen for the animation to change in value and refresh the UI by calling onDraw to redraw:

private void init() {

    setLayerType(LAYER_TYPE_SOFTWARE,null);

    mArrow = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_arrow);

    mMatrix = new Matrix();

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    mPaint.setStyle(Paint.Style.STROKE);

    mPaint.setStrokeWidth(4);

    mPaint.setColor(Color.RED);



    mDstPath = new Path();

    mCirclePath = new Path();

    mCirclePath.addCircle(dip2px(getContext(),100),dip2px(getContext(),100),dip2px(getContext(),25),Path.Direction.CW);

    mPathMeasure = new PathMeasure(mCirclePath,true);



ValueAnimator animator = ValueAnimator. OfFloat (0, 1);

    animator.setRepeatCount(ValueAnimator.INFINITE);

    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

        @Override

        public void onAnimationUpdate(ValueAnimator animation) {

// Refresh the interface after obtaining the rotation Angle value

            mCurrentAnimValue = (Float) animation.getAnimatedValue();

            invalidate();

        }

    });

    animator.setDuration(2000);

    animator.start();

}

Copy the code

Redraw the interface, including drawing paths and drawing arrow bitmaps:

@Override

protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    mStop = mPathMeasure.getLength()*mCurrentAnimValue;

    mStart = (float) (mStop ((0.5 - Math. Abs (mCurrentAnimValue 0.5)) * mPathMeasure getLength ()));

    mDstPath.reset();

    mPathMeasure.getSegment(mStart,mStop, mDstPath,true);

// Draw the path

    canvas.drawPath(mDstPath, mPaint);



    mMatrix = new Matrix();



/ * *

* The first way

* /

    mPathMeasure.getPosTan(mStop,mPos,mTan);

    float degrees = (float) (Math. Atan2 (mTan [1], mTan [0]) * 180.0 / Math. PI);

    mMatrix.postRotate(degrees,mArrow.getWidth()/2,mArrow.getHeight()/2);

    mMatrix.postTranslate(mPos[0]-mArrow.getWidth()/2,mPos[1]-mArrow.getHeight()/2);



/ * *

* The second way

* /

    mPathMeasure.getMatrix(mStop,mMatrix,PathMeasure.POSITION_MATRIX_FLAG|PathMeasure.TANGENT_MATRIX_FLAG);

    mMatrix.preTranslate(mArrow.getWidth()/2,-mArrow.getHeight()/2);

// Draw arrows

    canvas.drawBitmap(mArrow,mMatrix,mPaint);

}

Copy the code

Welcome to the Android technology stack public number: