What is PathMeasures
As the name suggests, PathMeasure is a class that measures Path
The constructor
The constructor | Methods described |
---|---|
PathMeasure() | Create an empty PathMeasure object. |
PathMeasure(Path path, boolean forceClosed) | Create a PathMeasure object associated with the specified path object (already created and specified). |
Public methods
The return value | Method names |
---|---|
float | getLength() |
boolean | getMatrix(float distance, Matrix matrix, int flags) |
boolean | getPosTan(float distance, float[] pos, float[] tan) |
boolean | getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) |
boolean | isClosed() |
boolean | nextContour() |
void | setPath(Path path, boolean forceClosed) |
Next, introduce the above methods respectively
1. Constructor
Parameterless constructor:
PathMeasure()
Copy the code
To create an empty PathMeasure that can be used to measure the path length, or to find the location and tangent of the path, call setPath. Once the Path is associated with the measurement object and the Path is changed, the setPath method needs to be called again.
Has parameter constructors
PathMeasure(Path path, boolean forceClosed)
Copy the code
Create a PathMeasure object associated with the specified path object. The measurement object can now return the length of the path as well as the position and tangent at any point along the path. As above, once the Path is associated with the measurement object and the Path is changed, the setPath method needs to be called again. ForceClosed: If true, this path is also considered “closed”.
ForceClosed does not affect the state of the Path itself. But it will affect the measurement results.
Here’s an example:
canvas.translate(mWidth/2,mHeight/2);
Path path = new Path();
path.lineTo(0.200);
path.lineTo(200.200);
path.lineTo(200.0);
PathMeasure measure1 = new PathMeasure(path,false);
PathMeasure measure2 = new PathMeasure(path,true);
Log.e("TAG"."forceClosed=false---->"+measure1.getLength());
Log.e("TAG"."forceClosed=true----->"+measure2.getLength());
canvas.drawPath(path,mDeafultPaint);
Copy the code
The log is as follows:
E/TAG: forceClosed = false -- -- -- - > 600.0 E/TAG: forceClosed = true -- -- -- -- -- > 800.0Copy the code
The drawing looks like this:
2. Public methods
getLength
Returns the total length of the current Path; If there is no path associated with this measure object, 0 is returned.
isClosed
Returns true if the current Path is close ().
setPath
Path is associated with PathMeasure. Mainly talk about the following methods:
nextContour
public boolean nextContour(a)
Copy the code
Get the next contour in the path, if there is a next contour, return true, and the PathMeasure cuts to the next contour data; Return false if there is no next contour. I understand once moveTo adds a silhouette.
getSegment
public booleanGetSegment (floatStartD,floatStopD, Path DST,booleanStartWithMoveTo)Copy the code
Given the distance between the start and finish, return to the middle section. Return false if the segment length is zero, true otherwise. StartD and stopD fixed value range (0,getLength()). If startD> = stopD, return false (and leave DST unchanged). If startWithMoveTo is true, it begins with moveTo.
parameter | role |
---|---|
startD | Distance from the start of the Path |
stopD | End Distance between the interception position and the start of the Path |
dst | The intercepted Path is added to DST |
startWithMoveTo | Whether the starting point is moveTo enabled |
StartD and stopD ranges from 0 <= startD < stopD <= getLength startWithMoveTo: Whether the first point of the intercepted fragment remains unchanged.
Set to true: Keep the captured fragment unchanged and add it to the DST path. Set to false: The start point of the captured fragment is moved to the last point in the DST path, keeping the DST path continuous
For example: startWithMoveTo is flase
canvas.translate(width/2,height/2);
Path mPath = new Path();
Path mDst = new Path();
PathMeasure mPathMeasure = new PathMeasure();
// Draw a circle with radius 400px clockwise
mPath.addCircle(0.0.400, Path.Direction.CW);
mPathMeasure.setPath(mPath, false);
/ / draw a straight line
mDst.moveTo(110.0);
mDst.lineTo(200.300);
// Cut the arc from 0.25 to 0.5 and place it in DST
mPathMeasure.getSegment(mPathMeasure.getLength() * 0.25 f,
mPathMeasure.getLength() * 0.5 f,
mDst,
false);
canvas.drawPath(mDst, paint);
Copy the code
The renderings are as follows:
StartWithMoveTo: True
getPosTan
public boolean getPosTan(floatdistancefloat pos[], float tan[])
Copy the code
parameter | role |
---|---|
distance | That is, the distance between the desired measurement point and the current path start position |
pos | Pos [0] is the x coordinate, and pos[1] is the Y coordinate |
tan | The sine and cosine of the measurement point, tan[0] is cosine, that is, cosine or x-coordinate of the unit circle; Tan [1] is sin, which is the sine value or y coordinate of the unit circle; |
Distance value range: 0<=distance<=getLength() A(x,y) origin is O,cos = OA/OB,sin = OA/AB
getMatrix
public boolean getMatrix(float distance, Matrix matrix, int flags)
Copy the code
parameter | role |
---|---|
distance | That is, the distance between the desired measurement point and the current path start position |
matrix | According to matrix encapsulated by Falgs |
flags | Specify what content is stored in the matrix |
Flags can be POSITION_MATRIX_FLAG or ANGENT_MATRIX_FLAG
In fact, this method is equivalent to the process of getPosTan packaging matrix, which is done by getMatrix for us. We can directly obtain a package to matrix.
In actual combat
Loading animation (1)
rendering
The getSegment method of PathMeasure is mainly used to intercept the path and draw the animation
Train of thought
1. Outline a clockwise hollow circle and generate a pathMeasure object
// Draw a hollow circle
path.addCircle(width / 2, height / 2, radius, Path.Direction.CW);
// Generate pathMeasure objects
pathMeasure.setPath(path, true);
Copy the code
2. Truncated start and end values
stop = mAnimatorValue * mLength;
start = (float) (stop - ((0.5 - Math.abs(mAnimatorValue - 0.5)) * mLength));
Copy the code
The value of mAnimatorValue is (0,1). When mAnimatorValue is 0 or 1, the two values are the same.
3. Intercept a path and draw a path
pathMeasure.getSegment(start, stop, dst, true);
canvas.drawPath(dst, paint);
Copy the code
Useful remember to point a little star
Loading animation (2)
rendering
Train of thought
GetPosTan is mainly used to obtain the coordinates and sines and cosines of the measuring point, and control the method and position of the arrow 1. Draw a clockwise hollow circle and then generate a pathMeasure object
// Draw a hollow circle
path.addCircle(width / 2, height / 2, radius, Path.Direction.CW);
// Generate pathMeasure objects
pathMeasure.setPath(path, true);
Copy the code
2. Obtain the measured coordinates and sines and cosines of the drawing point, and calculate the rotation Angle of the arrow according to tan[0] and Tan [1].
measure.getPosTan(measure.getLength() * mAnimatorValue, pos, tan);
float angle = (float) (Math.atan2(tan[1], tan[0]) * 180 / Math.PI);
Copy the code
The value of mAnimatorValue is (0,1). When mAnimatorValue is 0 or 1, the two values are the same. Angle calculation method to find their own mathematical knowledge.
3. Rotate and translate bitmap with Matrix
mMatrix.postRotate(angle,mBitmap.getWidth()/2,mBitmap.getHeight()/2);
mMatrix.postTranslate(pos[0] - mBitmap.getWidth() / 2,pos[1] - mBitmap.getHeight() / 2);
Copy the code
4. Draw the bitmap
canvas.drawBitmap(mBitmap,mMatrix,mPaint);
Copy the code
Useful remember to point a little star
Address of previous articles
Android animation – Fake bouquet live loading animation
Android animation – copy 58 city loading animation
Android animation – Copy tiktok loading animation