@@ -8,9 +8,12 @@ import androidx.compose.foundation.layout.wrapContentSize
8
8
import androidx.compose.runtime.Composable
9
9
import androidx.compose.ui.Alignment
10
10
import androidx.compose.ui.Modifier
11
+ import androidx.compose.ui.geometry.Offset
12
+ import androidx.compose.ui.graphics.TransformOrigin
11
13
import androidx.compose.ui.graphics.graphicsLayer
12
14
import androidx.compose.ui.input.pointer.PointerEventType
13
15
import androidx.compose.ui.input.pointer.pointerInput
16
+ import androidx.compose.ui.unit.IntSize
14
17
import com.squareup.workflow1.traceviewer.SandboxState
15
18
16
19
/* *
@@ -22,6 +25,7 @@ import com.squareup.workflow1.traceviewer.SandboxState
22
25
*/
23
26
@Composable
24
27
internal fun SandboxBackground (
28
+ appWindowSize : IntSize ,
25
29
sandboxState : SandboxState ,
26
30
modifier : Modifier = Modifier ,
27
31
content : @Composable () -> Unit ,
@@ -41,14 +45,29 @@ internal fun SandboxBackground(
41
45
awaitEachGesture {
42
46
val event = awaitPointerEvent()
43
47
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
45
55
// Applies zoom factor based on the actual delta change rather than just the act of scrolling
46
56
// This helps to normalize mouse scrolling and touchpad scrolling, since touchpad will
47
57
// fire a lot more scroll events.
48
58
val factor = 1f + (- scrollDelta * 0.1f )
49
59
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
+
52
71
event.changes.forEach { it.consume() }
53
72
}
54
73
}
0 commit comments