Skip to content

Instantly share code, notes, and snippets.

val heartPath = Path().apply {
// ... heart shape geometry
}
withTransform({
clipPath(heartPath)
}) {
// Everything drawn here will be heart-shaped
drawRect(Color.Red, size = size) // Fills only the heart
@Composable
fun ClipRectSplitExample() {
Box(
modifier = Modifier
.size(340.dp)
.drawBehind {
// Draw dark background for the full area
drawRect(color = Color(0xFF1A1A2E))
// Clip complex pattern to right half only
clipRect(
Modifier.drawBehind {
// Access the underlying canvas when absolutely necessary
drawContext.canvas.nativeCanvas.apply {
// Now you have android.graphics.Canvas
// Use sparingly, cause you're bypassing Compose's safety
}
}
// What withTransform actually does (simplified):
inline fun DrawScope.withTransform(
transformBlock: DrawTransform.() -> Unit,
drawBlock: DrawScope.() -> Unit
) {
drawContext.canvas.save() // Snapshot current state
drawContext.transform.transformBlock() // Apply your transformations
drawBlock() // Execute drawing commands
drawContext.canvas.restore() // Revert to snapshot
}
// Inside any DrawScope, you can access:
drawContext.size // The final pixel dimensions
drawContext.canvas // The actual drawing surface
drawContext.transform // The transformation controller
withTransform({
// Modify the coordinate system
scale(2f, 2f)
}) {
// Draw in the modified system
drawRect(Color.Blue, topLeft = Offset(1f, 1f), size = Size(2f, 1f))
// You write the same coordinates, but they mean different things now
}
Identity Matrix:
┌ ┐
│ 1 0 │ ← X basis vector (1, 0)
│ 0 1 │ ← Y basis vector (0, 1)
└ ┘
fun Modifier.optimizedGrid(gridColor: Color): Modifier = drawWithCache {
val stepSizePx = 10.dp.toPx().roundToInt().toFloat()
val strokeWidth = 1f
val offset = strokeWidth / 2f
val gridPath = Path().apply {
// Vertical lines
var x = 0f
while (x <= size.width) {
// Inside the loop, adjust the offset:
start = Offset(x = x + 0.5f, y = 0f)
fun Modifier.precisionGrid(color: Color) = drawWithContent {
// Always draw the actual content first so the grid sits on top
drawContent()
val stepSize = 10.dp.toPx().roundToInt().toFloat()
var x = stepSize
// Draw Vertical Lines
while (x < size.width) {
drawLine(
color = color,
start = Offset(x = x, y = 0f),