Skip to content

Commit a9a44e9

Browse files
committed
Fix zooming for sandbox
1 parent cc40120 commit a9a44e9

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/App.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ internal fun App(
7676

7777
// Main content
7878
SandboxBackground(
79+
appWindowSize = appWindowSize,
7980
sandboxState = sandboxState,
8081
) {
8182
// if there is not a file selected and trace mode is live, then don't render anything.

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/util/SandboxBackground.kt

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import androidx.compose.foundation.layout.wrapContentSize
88
import androidx.compose.runtime.Composable
99
import androidx.compose.ui.Alignment
1010
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.geometry.Offset
12+
import androidx.compose.ui.graphics.TransformOrigin
1113
import androidx.compose.ui.graphics.graphicsLayer
1214
import androidx.compose.ui.input.pointer.PointerEventType
1315
import androidx.compose.ui.input.pointer.pointerInput
16+
import androidx.compose.ui.unit.IntSize
1417
import com.squareup.workflow1.traceviewer.SandboxState
1518

1619
/**
@@ -22,6 +25,7 @@ import com.squareup.workflow1.traceviewer.SandboxState
2225
*/
2326
@Composable
2427
internal fun SandboxBackground(
28+
appWindowSize: IntSize,
2529
sandboxState: SandboxState,
2630
modifier: Modifier = Modifier,
2731
content: @Composable () -> Unit,
@@ -41,14 +45,29 @@ internal fun SandboxBackground(
4145
awaitEachGesture {
4246
val event = awaitPointerEvent()
4347
if (event.type == PointerEventType.Scroll) {
44-
val scrollDelta = event.changes.first().scrollDelta.y
48+
val pointerInput = event.changes.first()
49+
val pointerOffsetToCenter = Offset(
50+
// For some reason using 1.5 made zooming more natural than 2
51+
x = pointerInput.position.x - appWindowSize.width / (3/2),
52+
y = pointerInput.position.y - appWindowSize.height / 2
53+
)
54+
val scrollDelta = pointerInput.scrollDelta.y
4555
// Applies zoom factor based on the actual delta change rather than just the act of scrolling
4656
// This helps to normalize mouse scrolling and touchpad scrolling, since touchpad will
4757
// fire a lot more scroll events.
4858
val factor = 1f + (-scrollDelta * 0.1f)
4959
val minWindowSize = 0.1f
50-
val maxWindowSize = 10f
51-
sandboxState.scale = (sandboxState.scale * factor).coerceIn(minWindowSize, maxWindowSize)
60+
val maxWindowSize = 2f
61+
val oldScale = sandboxState.scale
62+
val newScale = (oldScale * factor).coerceIn(minWindowSize, maxWindowSize)
63+
val scaleRatio = newScale / oldScale
64+
65+
val newOrigin = sandboxState.offset - pointerOffsetToCenter
66+
val scaledView = newOrigin * scaleRatio
67+
val resetViewOffset = scaledView + pointerOffsetToCenter
68+
sandboxState.offset = resetViewOffset
69+
sandboxState.scale = newScale
70+
5271
event.changes.forEach { it.consume() }
5372
}
5473
}

0 commit comments

Comments
 (0)