ZoomableBox small changes
This commit is contained in:
parent
266d48b48b
commit
fe246e0a7b
1 changed files with 25 additions and 19 deletions
|
|
@ -28,6 +28,7 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
import androidx.compose.ui.graphics.RectangleShape
|
||||||
|
|
@ -39,27 +40,31 @@ import androidx.compose.ui.unit.IntSize
|
||||||
@Composable
|
@Composable
|
||||||
fun ZoomableBox(
|
fun ZoomableBox(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
minScale: Float = 1f,
|
contentAlignment: Alignment = Alignment.TopStart,
|
||||||
maxScale: Float = 5f,
|
minZoom: Float = 1f,
|
||||||
|
maxZoom: Float = 5f,
|
||||||
content: @Composable ZoomableBoxScope.() -> Unit
|
content: @Composable ZoomableBoxScope.() -> Unit
|
||||||
) {
|
) {
|
||||||
var scale by remember { mutableStateOf(1f) }
|
var zoom by remember { mutableStateOf(minZoom) }
|
||||||
var offsetX by remember { mutableStateOf(0f) }
|
var offsetX by remember { mutableStateOf(0f) }
|
||||||
var offsetY by remember { mutableStateOf(0f) }
|
var offsetY by remember { mutableStateOf(0f) }
|
||||||
var size by remember { mutableStateOf(IntSize.Zero) }
|
var size by remember { mutableStateOf(IntSize.Zero) }
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clip(RectangleShape)
|
.clip(RectangleShape)
|
||||||
.onSizeChanged { size = it }
|
.onSizeChanged {
|
||||||
|
size = it
|
||||||
|
}
|
||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
detectTransformGestures { _, pan, zoom, _ ->
|
detectTransformGestures { _, panChange, zoomChange, _ ->
|
||||||
scale = maxOf(minScale, minOf(scale * zoom, maxScale))
|
zoom = (zoom * zoomChange).coerceIn(minZoom, maxZoom)
|
||||||
val maxX = (size.width * (scale - 1)) / 2
|
val maxX = (size.width * (zoom - 1)) / 2f
|
||||||
val minX = -maxX
|
val minX = -maxX
|
||||||
offsetX = maxOf(minX, minOf(maxX, offsetX + pan.x))
|
val maxY = (size.height * (zoom - 1)) / 2f
|
||||||
val maxY = (size.height * (scale - 1)) / 2
|
|
||||||
val minY = -maxY
|
val minY = -maxY
|
||||||
offsetY = maxOf(minY, minOf(maxY, offsetY + pan.y))
|
offsetX = maxOf(minX, minOf(maxX, offsetX + panChange.x))
|
||||||
|
offsetY = maxOf(minY, minOf(maxY, offsetY + panChange.y))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
|
|
@ -67,17 +72,18 @@ fun ZoomableBox(
|
||||||
onDoubleTap = {
|
onDoubleTap = {
|
||||||
offsetX = 0f
|
offsetX = 0f
|
||||||
offsetY = 0f
|
offsetY = 0f
|
||||||
scale = if (scale > minScale) {
|
zoom = if (zoom > minZoom) {
|
||||||
minScale
|
minZoom
|
||||||
} else {
|
} else {
|
||||||
maxScale / 2f
|
maxZoom / 2f
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
|
contentAlignment = contentAlignment,
|
||||||
) {
|
) {
|
||||||
DefaultZoomableBoxScope(this, scale, offsetX, offsetY).content()
|
DefaultZoomableBoxScope(this, zoom, offsetX, offsetY).content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,12 +101,12 @@ private class DefaultZoomableBoxScope(
|
||||||
private val offsetY: Float
|
private val offsetY: Float
|
||||||
) : ZoomableBoxScope, BoxScope by parentScope {
|
) : ZoomableBoxScope, BoxScope by parentScope {
|
||||||
|
|
||||||
override fun Modifier.zoomable(): Modifier {
|
override fun Modifier.zoomable() = this.then(
|
||||||
return graphicsLayer(
|
graphicsLayer(
|
||||||
scaleX = scale,
|
scaleX = scale,
|
||||||
scaleY = scale,
|
scaleY = scale,
|
||||||
translationX = offsetX,
|
translationX = offsetX,
|
||||||
translationY = offsetY
|
translationY = offsetY,
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue