前言
自定义View的时候,有时会碰到一些轨迹移动之类的需求,比如让某个物体沿着特定的路线移动,通常都是使用Path搭配PathMeasure来实现,比如下面的效果图
看起来蛮有意思的,其实很本质简单,就是小船沿着给定的路线运动,路线就是Path,然后就是使用PathMeasure计算Path相关参数,这篇文章就来讲讲关于PathMeasure的内容,不多BB,先上代码
PS:其实我想先贴PathMeasure API的,但感觉这样文章就太长了,就直接放链接吧
重点关注下文档中的getLength() 、getPosTan(float distance, float[] pos, float[] tan) 、getMatrix(float distance, Matrix matrix, int flags) ,下面的代码会用到
mMatrix.reset()
pathMeasure = PathMeasure(path, false)
length = pathMeasure.length
/*
* 因为路径是不规则的,为了让小船在移动的时候,紧贴着路径,所以我们需要移动小船并旋转一定的角度
* 为了达到目的,有两种方法
*/
/*
//方法一:自己计算
//获取Path指定点的的位置,和正切值tan
pathMeasure.getPosTan(boatDx, pos, tan)
//将tan值通过反三角函数得到对应的弧度,然后将弧度转换成度数
var degrees : Float = ((Math.atan2(tan[1].toDouble(), tan[0].toDouble())*180f/Math.PI).toFloat())
//旋转
mMatrix.postRotate(degrees , bitmap.width/2F, bitmap.height/2F)
//移动
mMatrix.postTranslate((pos[0]-bitmap.width/2F).toFloat(), (pos[1]-bitmap.height).toFloat())
*/
//方法二:使用API
//getMatrix(),获取Path指定位置的Matrix
pathMeasure.getMatrix(boatDx, mMatrix, PathMeasure.TANGENT_MATRIX_FLAG
or PathMeasure.POSITION_MATRIX_FLAG)
mMatrix.preTranslate((-bitmap.width / 2).toFloat(), (-bitmap.height).toFloat())
canvas.drawPath(path, paint)
canvas.drawBitmap(bitmap, mMatrix, paint)
circleMatrix.reset()
circlePathMeasure = PathMeasure(circlePath, false)
circleLength = circlePathMeasure.length
circlePathMeasure.getMatrix(circleDx, circleMatrix, PathMeasure.TANGENT_MATRIX_FLAG
or PathMeasure.POSITION_MATRIX_FLAG)
circleMatrix.preTranslate((-bitmap.width / 2).toFloat(), (-bitmap.height).toFloat())
canvas.drawPath(circlePath, paint)
canvas.drawBitmap(bitmap, circleMatrix, paint)
注意:方法一和方法二中的postTranslate()和preTranslate()的区别,这里涉及到矩阵Matrix相关的知识点,可以看着这篇文章Android Matrix 详解