【Android贝塞尔曲线应用-跳动的水滴】人生处万类,知识最为贤。这篇文章主要讲述Android贝塞尔曲线应用-跳动的水滴相关的知识,希望能为你提供帮助。
文章图片
主要通过6个控制点实现。
val startPoint = PointF()
val endPoint = PointF()
val control1 = PointF()
val control2 = PointF()
val control3 = PointF()
val control4 = PointF()
文章图片
绘制过程:
private fun drawWater(canvas: Canvas) {
waterPath.apply {
reset()
moveTo(startPoint)
cubicTo(control1, control3, endPoint)
cubicTo(control4, control2, startPoint)
}
canvas.save()
// clipOut 出中间的圆
if (Build.VERSION.SDK_INT >
= Build.VERSION_CODES.O) {
canvas.clipOutPath(Path().apply { addCircle(circleX, circleY, circleR, Path.Direction.CW) })
} else {
canvas.clipPath(Path().apply {
addCircle(circleX, circleY, circleR, Path.Direction.CW)
}, Region.Op.DIFFERENCE)
}
canvas.drawPath(waterPath, waterPaint)
canvas.drawCircle(circleX, circleY, circleR, waterPaint)
canvas.restore()
}
一些扩展函数,方便直接使用 PointF。
private fun Path.moveTo(p: PointF) {
moveTo(p.x, p.y)
}
private fun Path.lineTo(p: PointF) {
lineTo(p.x, p.y)
}
private fun Path.cubicTo(control1: PointF, control2: PointF, end: PointF) {
cubicTo(control1.x, control1.y, control2.x, control2.y, end.x, end.y)
}
private fun Path.quadTo(control: PointF, end: PointF) {
quadTo(control.x, control.y, end.x, end.y)
}
private fun Canvas.drawPoint(p: PointF, paint: Paint) {
drawPoint(p.x, p.y, paint)
}
动画分为 6 个阶段完成
class AnimatorHelper(val target: JumpWater) {private var animDuration = 300L
private var animStartDown: ValueAnimator? = null
private var animStartJump: ValueAnimator? = null
private var animJump: ValueAnimator? = null
private var animDown: ValueAnimator? = null
private var animTail: ValueAnimator? = null
private var animTailReconver: ValueAnimator? = null
private var animSet: AnimatorSet? = nullinternal fun startJump(tailMove: Float, jumpH: Float) {
endJump()
animStartDown = ValueAnimator.ofFloat(0f, jumpH).apply {
addUpdateListener {
target.updateStartDown(it.animatedValue as Float)
}
}
animStartJump = ValueAnimator.ofFloat(jumpH, 0f).apply {
addUpdateListener {
target.updateStartDown(it.animatedValue as Float)
}
}
animJump = ValueAnimator.ofFloat(0f, jumpH).apply {
addUpdateListener {
target.updateJump(it.animatedValue as Float)
}
}
animDown = ValueAnimator.ofFloat(jumpH, 0f).apply {
addUpdateListener {
target.updateJump(it.animatedValue as Float)
}
}
animTail = ValueAnimator.ofFloat(0f, tailMove).apply {
addUpdateListener {
target.updateTail(it.animatedValue as Float)
}
}
animTailReconver = ValueAnimator.ofFloat(tailMove, 0f).apply {
addUpdateListener {
target.updateTail(it.animatedValue as Float)
}
}val tailSet = AnimatorSet().apply {
playTogether(animJump, animTail)
}val tailSetReconver = AnimatorSet().apply {
playTogether(animDown, animTailReconver)
}animSet = AnimatorSet().apply {
playSequentially(animStartDown, animStartJump, tailSet, tailSetReconver)
addListener(object : Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator?) {}override fun onAnimationEnd(animation: Animator?) {
mOnAnimEndListener?.onAnimEnd()
}override fun onAnimationCancel(animation: Animator?) {
}override fun onAnimationStart(animation: Animator?) {
}
})
start()
}
}
}
具体请看:https://github.com/stefanJi/AndroidView/tree/master/jumpwater
推荐阅读
- Android--SharedPreferences数据存储方案
- Android RxJava小结
- Java Service Wrapper 使用(windows)
- 使用Java Service Wrapper将java程序作为linux服务并且开机自动启动
- SpringMVC-HandlerMapping
- Gym - 100548H The Problem to Make You Happy2014-2015 ACM-ICPC, Asia Xian Regional Contest (BFS+博弈)
- Android MVVM小结
- 安卓preview不显示的问题
- 当安卓手机的数据线接口损坏时,如何刷机RECOVERY