自定义View之动画篇(十三)动画进阶-PathMeasure

动画进阶

当我们实现更复杂的动画时,如nexus开机动画,前面的属性动画、容器动画就实现不了。

PathMeasure实现路径动画

其实就是一个Path路径点的坐标追踪,可计算出指定路径的一些信息如总路长、指定长度所对应的坐标点;

要计算,肯定就需要和路径绑定:

两种方式:

		PathMeasure pm=new  PathMeasure();
		pm.setPath(Path path,boolean forceClosed);


		PathMeasure pm=new PathMeasure(Path path,boolean forceClosed);

常用函数:

		public float getLength();


	//我们知道,Path可以由多条曲线构成,但不管是getLength()、getSegment()还是其他函数都是计算其中一条线段。而该函数就是跳转到下一条曲线的函数;

	//轮询得到的曲线与Path添加的顺序一致;
		boolean nextContour();

	//获取路径上某一长度的位置已经位置的正切值
	//	distance:距离该路径起始点的长度0<=diatance<=getLength
	//	pos:该点坐标,当前点在画布上的位置有两个值,x、y分别为pos[0]、pos[1]
	//  tan:该点的正切值;坐标系某点的正切值,即为远原点与该点连接起来,形成的夹角即为正切值y/x
		boolean getPosTan(float distance,float[] pos,float tan)

	//截取整个Path的某个片段,截取后的片段保存在dst中,最后一个                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            参数表示截取片段添加的到dst中,dst的起始点是否使用moveTo将路径的新起始点移动到结果Path的起始点,

重点讲解下该函数:

		boolean getSegment(float startD,float stopD,Path dst,boolean startWithMoveTo)

截取路径的某个片段,将该片段路径***添加(注意:不是替换)***到dst路径中;

最后一个参数:决定在将截取的片段路径添加到dst中前,是否将dst的绘制起始点移动到添加片段路径的起始点;true:就会将路径起始点移动到添加路径的的起始点,这样被截取出来的片段路径保持原状;false:则会将路径的起始点改为上一条路径的终点,从而保证路径的延续性,新添加的路径起始点会被改变;

	canvas.translate(100,100);
    mPath.addRect(-50,-50,50,50, Path.Direction.CW);
    Path dst = new Path();
    dst.lineTo(100,100);
    mPm.setPath(mPath,false);
    mPm.getSegment(0,150,dst,false);
    canvas.drawPath(dst,mPaint);

当我们改变getSegment()参数分别为true、false效果分别入下:

自定义View之动画篇(十三)动画进阶-PathMeasure_第1张图片
自定义View之动画篇(十三)动画进阶-PathMeasure_第2张图片

当startWithMoveTo为true,被截取的的Path片段会保持原状,为false会将截取出来的片段的起始点移动到dst的最后一个点,以保证dst的连续性;

借助PathMeasure的getSegment()函数以及前面的属性动画实现路径加载动画效果:

public SegmentView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();


}

private void init() {
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setColor(Color.RED);
    mPaint.setStrokeWidth(5);
    mPath = new Path();
    mPm = new PathMeasure();

    mPaint.setStyle(Paint.Style.STROKE);
    mPath.addRect(-50,-50,50,50, Path.Direction.CW);
    mPm.setPath(mPath,false);
    ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
    animator.setDuration(2000);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            mFraction = (float) animation.getAnimatedValue();
            invalidate();
        }
    });
    animator.setRepeatCount(2);
    animator.start();

}

 @Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.translate(100,100);

    Path dst = new Path();

    float stopD=mPm.getLength()*mFraction;

    mPm.getSegment(0,stopD,dst,true);
    canvas.drawPath(dst,mPaint);


}

自定义View之动画篇(十三)动画进阶-PathMeasure_第3张图片

nt(0,stopD,dst,true);
canvas.drawPath(dst,mPaint);

}

[外链图片转存中…(img-B17xm4eK-1575363727971)]

你可能感兴趣的:(自定义View之动画篇(十三)动画进阶-PathMeasure)