什么?你不知道 DVD 是啥?呵呵,暴露年龄了。这是一个具备年代感的东西。你没看到过说明要么你年轻,年轻好啊。要么你家穷,我那会儿反正是租的碟片在同窗家放,本身家买是不可能的了,一生都不可能。git
正式开始实现以前,开始简单的建模及分析。github
总体效果就是:一个圆或者矩形在一个大的矩形(类比电视屏幕)上面运动,撞到屏幕边缘就开始反弹,这里类比于光的反射。直到它成功切入一个角落,那么就中止运动。数组
转化一下其实就是我须要在两点连线的轨迹上面做圆或者其余图形,这两点必须知足在大的矩形的任意两边上(能够是相邻的,也能够是隔开的,单不能是同一边)。函数
那么对应到 Android 中就转换成两个问题,第一 如何经过已知点和角度和相关约束条件计算出另一个点的坐标。第二 如何拿到两点相连的轨迹。spa
针对问题一,很明确,这里须要使用到勾股定理那些知识,或者准确的说,这里就是须要用到「正切函数」。code
针对问题二,这里就须要使用到 Path 和 PathMeasure 这两个类。在 Path 中咱们能够经过 moveTo() lineTo() 两个方法实现两点连线。而后调用 pathMeasure.setPath(path, false)
方式使 Path 和 PathMeasure 相关联。接着介绍 PathMeasure 一个超级厉害的方法: pathMeasure.getPosTan(distance, positionArray, tanArray)
这个方法第一个参数指定一段长度,接着传入两个数组,positionArray[2] 和 tanArray[2] 。 最后positionArray 返回的就是对应 distance 后的终点坐标,到这里,终点坐标问题解决。更厉害的是后面,给到你 X 和 Y 对应的正切值。那么咱们这里须要使用的正切值就是 tanValue = Math.abs(tanArray[1] / tanArray[0])
orm
两个大问题解决了,在讨论一些小问题,好比说运动轨迹到底有多少种? cdn
大体就是这个状况,唉,第一次用「预览」画图,你们能看明白就好。这里具体有八种状况的轨迹。按大类分就是四大类,分别对应各个象限的状况。每一个象限又有上下两种运动方向,因此就是有八大类。blog
轨迹有八种,可是要再具体的话,每一种又能够再拆分出一种状况。那就是上面提到的,这两点是相邻的或者是隔开的。get
最后直接刚上一组代码,对应上图的相关状况。
private fun handUp() {
if (currentX == startX()) {// normal
val resultX = startX() + (currentY - startY()) / tanValue
val dx = resultX - endX()
if (resultX > endX()) {
Log.e("calculate", "上升 handUp:越界状况")
val dy = tanValue * (endX() - currentX)
path.lineTo(endX(), currentY - dy)
} else {
Log.e("calculate", "上升 handUp:正常状况")
path.lineTo(resultX, startY())
}
needRevert = dx > 0
} else if (currentX == endX()) {// normal revert
val resultX = (endY() - currentY) / tanValue
val dx = resultX - currentX
if (currentX - resultX < startX()) {
Log.e("calculate", " handUp 降低:越界状况")
path.lineTo(startX(), rectF.height() - dx * tanValue)
needRevert = true
} else {
Log.e("calculate", " handUp 降低:正常状况")
path.lineTo(currentX - resultX, rectF.height() - ovalY())
needRevert = false
}
} else {
Log.e(
"calculate",
" handUp 异常状况:currentX =$currentX startX=${startX()} endx:${endX()} startX=${startX()} endx:${endX()}"
)
animator.cancel()
state = STATE_ERROR
}
}
复制代码
最后效果就是这样的,目前支持「圆形」和「椭圆形」
源码地址:DVD loading by Joe