美文网首页Android开发Android-自定义viewAndroid控件
Android贝塞尔曲线应用-跳动的水滴

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

作者: stefanJi | 来源:发表于2018-10-03 00:36 被阅读9次
    jumpWater

    主要通过6个控制点实现。

    val startPoint = PointF()
    val endPoint = PointF()
    val control1 = PointF()
    val control2 = PointF()
    val control3 = PointF()
    val control4 = PointF()
    
    control point

    绘制过程:

    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? = null
    
        internal 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贝塞尔曲线应用-跳动的水滴

        本文链接:https://www.haomeiwen.com/subject/rdfzoftx.html