Android贝塞尔曲线应用-跳动的水滴

【Android贝塞尔曲线应用-跳动的水滴】人生处万类,知识最为贤。这篇文章主要讲述Android贝塞尔曲线应用-跳动的水滴相关的知识,希望能为你提供帮助。

Android贝塞尔曲线应用-跳动的水滴

文章图片

主要通过6个控制点实现。
val startPoint = PointF() val endPoint = PointF() val control1 = PointF() val control2 = PointF() val control3 = PointF() val control4 = PointF()

Android贝塞尔曲线应用-跳动的水滴

文章图片

绘制过程:
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

    推荐阅读