Browse Source
The code of `ScalableImage` is exactly the same as [here](https://github.com/JetBrains/compose-multiplatform-core/pull/459/files#diff-2df227d37a7fcdb885f4fd1a715c0efd94b8e206d446d553d69a456f83e284f6R19): 1. The initial size of an image is chosen by the area size (phone/windows size) 2. We can zoom using pinch-to-zoom (with taking centroid of touches into account) 3. We can zoom using mouse scroll (also, taking the mouse position into account). On touchpad/macOS it also works great. 4. The code of the old `ScalableState` and `ScalableImage` was complete rewritten. 5. The zoom is not limited by phone/window dimensions, we can zoom outv.mazunin/dev/image-viewer-share
Igor Demin
2 years ago
committed by
GitHub
9 changed files with 205 additions and 162 deletions
@ -1,7 +0,0 @@ |
|||||||
package example.imageviewer.view |
|
||||||
|
|
||||||
import androidx.compose.ui.Modifier |
|
||||||
import example.imageviewer.model.ScalableState |
|
||||||
|
|
||||||
actual fun Modifier.addUserInput(state: ScalableState) = |
|
||||||
addTouchUserInput(state) |
|
@ -1,5 +1,3 @@ |
|||||||
package example.imageviewer.model |
package example.imageviewer.model |
||||||
|
|
||||||
const val MAX_SCALE = 5f |
|
||||||
const val MIN_SCALE = 1f |
|
||||||
const val TOAST_DURATION = 3000L |
const val TOAST_DURATION = 3000L |
||||||
|
@ -0,0 +1,26 @@ |
|||||||
|
package example.imageviewer.utils |
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue |
||||||
|
import androidx.compose.runtime.rememberUpdatedState |
||||||
|
import androidx.compose.ui.Modifier |
||||||
|
import androidx.compose.ui.composed |
||||||
|
import androidx.compose.ui.input.pointer.* |
||||||
|
|
||||||
|
fun Modifier.onPointerEvent( |
||||||
|
eventType: PointerEventType, |
||||||
|
pass: PointerEventPass = PointerEventPass.Main, |
||||||
|
onEvent: AwaitPointerEventScope.(event: PointerEvent) -> Unit |
||||||
|
): Modifier = composed { |
||||||
|
val currentEventType by rememberUpdatedState(eventType) |
||||||
|
val currentOnEvent by rememberUpdatedState(onEvent) |
||||||
|
pointerInput(pass) { |
||||||
|
awaitPointerEventScope { |
||||||
|
while (true) { |
||||||
|
val event = awaitPointerEvent(pass) |
||||||
|
if (event.type == currentEventType) { |
||||||
|
currentOnEvent(event) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,28 +0,0 @@ |
|||||||
package example.imageviewer.view |
|
||||||
|
|
||||||
import androidx.compose.foundation.gestures.detectDragGestures |
|
||||||
import androidx.compose.ui.Modifier |
|
||||||
import androidx.compose.ui.geometry.Offset |
|
||||||
import androidx.compose.ui.input.pointer.PointerEventType |
|
||||||
import androidx.compose.ui.input.pointer.pointerInput |
|
||||||
import example.imageviewer.model.ScalableState |
|
||||||
import example.imageviewer.model.addDragAmount |
|
||||||
import example.imageviewer.model.addScale |
|
||||||
|
|
||||||
actual fun Modifier.addUserInput(state: ScalableState): Modifier = |
|
||||||
pointerInput(Unit) { |
|
||||||
detectDragGestures { change, dragAmount: Offset -> |
|
||||||
state.addDragAmount(dragAmount) |
|
||||||
change.consume() |
|
||||||
} |
|
||||||
}.pointerInput(Unit) { |
|
||||||
awaitPointerEventScope { |
|
||||||
while (true) { |
|
||||||
val event = awaitPointerEvent() |
|
||||||
if (event.type == PointerEventType.Scroll) { |
|
||||||
val delta = event.changes.getOrNull(0)?.scrollDelta ?: Offset.Zero |
|
||||||
state.addScale(delta.y / 100) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,7 +0,0 @@ |
|||||||
package example.imageviewer.view |
|
||||||
|
|
||||||
import androidx.compose.ui.Modifier |
|
||||||
import example.imageviewer.model.ScalableState |
|
||||||
|
|
||||||
actual fun Modifier.addUserInput(state: ScalableState): Modifier = |
|
||||||
addTouchUserInput(state) |
|
Loading…
Reference in new issue