Skip to content

Commit 835349b

Browse files
committed
Fix zooming for sandbox
1 parent cc40120 commit 835349b

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-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: 23 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,30 @@ 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+
// The x scale seems to be a little different than y, and (3/2) seemed to make zooming
51+
// smoother easier than just dividing by 2.
52+
x = pointerInput.position.x - appWindowSize.width / (3/2),
53+
y = pointerInput.position.y - appWindowSize.height / 2
54+
)
55+
val scrollDelta = pointerInput.scrollDelta.y
4556
// Applies zoom factor based on the actual delta change rather than just the act of scrolling
4657
// This helps to normalize mouse scrolling and touchpad scrolling, since touchpad will
4758
// fire a lot more scroll events.
4859
val factor = 1f + (-scrollDelta * 0.1f)
4960
val minWindowSize = 0.1f
50-
val maxWindowSize = 10f
51-
sandboxState.scale = (sandboxState.scale * factor).coerceIn(minWindowSize, maxWindowSize)
61+
val maxWindowSize = 2f
62+
val oldScale = sandboxState.scale
63+
val newScale = (oldScale * factor).coerceIn(minWindowSize, maxWindowSize)
64+
val scaleRatio = newScale / oldScale
65+
66+
val newOrigin = sandboxState.offset - pointerOffsetToCenter
67+
val scaledView = newOrigin * scaleRatio
68+
val resetViewOffset = scaledView + pointerOffsetToCenter
69+
sandboxState.offset = resetViewOffset
70+
sandboxState.scale = newScale
71+
5272
event.changes.forEach { it.consume() }
5373
}
5474
}

0 commit comments

Comments
 (0)