Skip to content

Fix Shape snippets to correctly work with different parent sizing. #233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Matrix
Expand All @@ -66,9 +67,11 @@ import androidx.graphics.shapes.Cubic
import androidx.graphics.shapes.Morph
import androidx.graphics.shapes.RoundedPolygon
import androidx.graphics.shapes.star
import androidx.graphics.shapes.toPath
import com.example.compose.snippets.R
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.max
import kotlin.math.sin

@Preview
Expand Down Expand Up @@ -348,22 +351,49 @@ private fun MorphOnClick() {
}

// [START android_compose_shapes_polygon_compose_shape]
@JvmOverloads
fun RoundedPolygon.toPath(path: Path = Path()): Path {
pathFromCubics(path, cubics)
return path
}
private fun pathFromCubics(
path: Path,
cubics: List<Cubic>
) {
var first = true
path.rewind()
for (element in cubics) {
if (first) {
path.moveTo(element.anchor0X, element.anchor0Y)
first = false
}
path.cubicTo(
element.control0X, element.control0Y, element.control1X, element.control1Y,
element.anchor1X, element.anchor1Y
)
}
path.close()
}
fun RoundedPolygon.getBounds() = calculateBounds().let { Rect(it[0], it[1], it[2], it[3]) }
class RoundedPolygonShape(
private val polygon: RoundedPolygon
private val polygon: RoundedPolygon,
private var matrix: Matrix = Matrix()
) : Shape {
private val matrix = Matrix()
private val path = Path()
override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density
): Outline {
val path = polygon.cubics.toPath()
// below assumes that you haven't changed the default radius of 1f, nor the centerX and centerY of 0f
// By default this stretches the path to the size of the container, if you don't want stretching, use the same size.width for both x and y.
matrix.scale(size.width / 2f, size.height / 2f)
matrix.translate(1f, 1f)
path.transform(matrix)
path.rewind()
polygon.toPath(path)
matrix.reset()
val bounds = polygon.getBounds()
val maxDimension = max(bounds.width, bounds.height)
matrix.scale(size.width / maxDimension, size.height / maxDimension)
matrix.translate(-bounds.left, -bounds.top)

path.transform(matrix)
return Outline.Generic(path)
}
}
Expand Down