-
Notifications
You must be signed in to change notification settings - Fork 0
/
GooeyModifierNode.kt
74 lines (68 loc) · 2.66 KB
/
GooeyModifierNode.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.doool.gooey
import android.graphics.BlurMaskFilter
import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.addOutline
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.LayoutAwareModifierNode
import androidx.compose.ui.node.modifierElementOf
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
@OptIn(ExperimentalComposeUiApi::class)
fun Modifier.gooeyBackground(color: Color, shape: Shape, solidShape: Boolean = true) =
this.composed {
val intensity = LocalGooeyIntensity.current.intensity
val layoutDirection = LocalLayoutDirection.current
val density = LocalDensity.current
modifierElementOf(params = Pair(color, shape), create = {
GooeyModifierNode(
shape, layoutDirection, density, color, intensity, solidShape
)
}, update = {
it.gooeyColor = color
}, definitions = {
name = "gooeyBackgroundNode"
properties["color"] = color
properties["shape"] = shape
properties["solidShape"] = solidShape
})
}
@OptIn(ExperimentalComposeUiApi::class)
class GooeyModifierNode(
private val shape: Shape,
private val layoutDirection: LayoutDirection,
private val density: Density,
var gooeyColor: Color,
intensity: Float,
solidShape: Boolean = false
) : DrawModifierNode, LayoutAwareModifierNode, Modifier.Node() {
private var path = Path()
private var blurPaint = createBlurPaint(
intensity, if (solidShape) BlurMaskFilter.Blur.SOLID else BlurMaskFilter.Blur.NORMAL
)
override fun onRemeasured(size: IntSize) {
this.path = Path().apply {
val size = Size(width = size.width.toFloat(), height = size.height.toFloat())
addOutline(shape.createOutline(size, layoutDirection, density))
}
}
override fun ContentDrawScope.draw() {
drawIntoCanvas { canvas ->
canvas.drawPath(path, blurPaint.apply {
color = gooeyColor
})
drawContent()
}
}
}