从 onDraw 动画 clipPath

Animating a clipPath from onDraw

我正在使用 PaintCanvas 在 onDraw 中绘制自定义形状。在 onDraw class 中,我有一个矩形 clipPath.

我希望能够为 MainActivityclipPath 的位置设置动画(从左到右设置动画)。这将从左到右隐藏绘制的形状 (BlackGraph)。

class BlackGraph(context: Context) : View(context) {

    var clipAmount:Float = 0.0f

    override fun onDraw(canvas: Canvas) {
        val paint = Paint()
        paint.style = Paint.Style.FILL
        paint.color = Color.parseColor("#000000")
        val path = Path()

        val clipPath = Path()
        clipPath.addRect(clipAmount, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW)
        canvas.clipPath(clipPath)

        path.moveTo(0f, height-30.toFloat())
        path.lineTo(width.toFloat(), 0f)
        path.lineTo(width.toFloat(), height.toFloat())
        path.lineTo(0f, height.toFloat())
        path.lineTo(0f, 0f)

        canvas.drawPath(path, paint)

    }
}

onCreate中:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val layout1 = findViewById<android.support.constraint.ConstraintLayout>(R.id.layout1)
    val blackGraph = BlackGraph(this)

    layout1.addView(blackGraph)

    val valueAnimator = ValueAnimator.ofFloat(0f, 450f)
    valueAnimator.addUpdateListener {
        val value = it.animatedValue as Float
        println("Value -> $value")
        blackGraph.clipAmount = value
    }
    valueAnimator.duration = 2000
    valueAnimator.start()

}

我正在尝试简单地为 clipAmount 的位置设置动画以实现所需的动画效果。

问题出在 onCreate,clipAmount 值从未设置动画。然而,打印语句工作得很好。 Logcat 充满了从 0.0 到 450.0 的浮点值

如何制作 clipPath 的动画?

好的,你在这里遇到了一些问题。首先,你不应该在onDraw()中初始化Paint,Path,应该先初始化它,然后你可以修改它,你会得到更好的性能。当你更新 clipAmount 值时,你需要调用 postInvalidateOnAnimation() 让你的 BlackGraph 视图重新绘制,这将触发方法 onDraw()。最后一件事是 clipPath 在使用 addRect().

方法添加新路径之前需要调用 reset() 清除
class BlackGraph(context: Context) : View(context) {

    var clipAmount:Float = 0.0f
    val paint = Paint().apply {
        style = Paint.Style.FILL
        color = Color.parseColor("#000000")
    }
    val path = Path()
    val clipPath = Path()

    override fun onDraw(canvas: Canvas) {
        clipPath.apply {
            reset()
            addRect(clipAmount, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW)
        }
        canvas.clipPath(clipPath)

        path.moveTo(0f, height-30.toFloat())
        path.lineTo(width.toFloat(), 0f)
        path.lineTo(width.toFloat(), height.toFloat())
        path.lineTo(0f, height.toFloat())
        path.lineTo(0f, 0f)

        canvas.drawPath(path, paint)
    }

    fun animateClipAmount() {
        val valueAnimator = ValueAnimator.ofFloat(0f, 450f)
        valueAnimator.addUpdateListener {
            val value = it.animatedValue as Float
            clipAmount = value
            println("Value -> $clipAmount")
            postInvalidateOnAnimation()
        }
        valueAnimator.duration = 2000
        valueAnimator.start()
    }

}

在创建中:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val layout1 = findViewById<android.support.constraint.ConstraintLayout>(R.id.layout1)

        val blackGraph = BlackGraph(this)
        layout1 .addView(blackGraph)
        blackGraph.animateClipAmount()
    }

}