Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack Compose drag gesture and pinch gesture

Jetpack Compose drag gesture and pinch gesture

Moyuru Aizawa

April 21, 2023
Tweet

More Decks by Moyuru Aizawa

Other Decks in Programming

Transcript

  1. Moyuru Aizawa Software Engineer of Catlog, RABO. Previously at Azit,

    CyberAgent, and Eureka. Love Metal, Hardcore and EDM. MoyuruAizawa
  2. modifier .pointerInput(Unit) { detectDragGestures { change, dragAmount -> state.offset +=

    dragAmount } } .graphicsLayer { translationX = state.offset.x translationY = state.offset.y } PointerInput#detectDragGestures
  3. modifier .pointerInput(Unit) { detectTransformGestures { centroid, pan, zoom, rotation ->

    state.scale *= zoom } } .graphicsLayer { scaleX = state.scale scaleY = state.scale } PointerInput#detectTransformGestures
  4. suspend fun PointerInputScope.detectTransformGestures( onGestureStart: (GestureType) -> Unit, onGestureEnd: (GestureType) ->

    Unit, onDrag: (dragAmount: Offset) -> Unit, onZoom: (zoom: Float) -> Unit, ) { forEachGesture { awaitPointerEventScope { awaitFirstDown(requireUnconsumed = false) val gestureType = detectGesture() ?: return@awaitPointerEventScope onGestureStart(gestureType) do { val event = awaitPointerEvent() when (gestureType) { GestureType.DRAG -> { val dragChange = event.calculatePan() if (dragChange != Offset.Zero) onDrag(dragChange) } GestureType.ZOOM -> { val zoomChange = event.calculateZoom() if (zoomChange != 1f) onZoom(zoomChange) } } event.changes.fastForEach { if (it.positionChanged()) it.consume() } } while (event.changes.fastAny { it.pressed }) onGestureEnd(gestureType) } } } private suspend fun AwaitPointerEventScope.detectGesture(): GestureType? { var zoom = 1f var pan = Offset.Zero val touchSlop = viewConfiguration.touchSlop var gestureType: GestureType? = null do { val event = awaitPointerEvent() zoom *= event.calculateZoom() pan += event.calculatePan() val zoomMotion = abs(1 - zoom) * event.calculateCentroidSize(useCurrent = false) val panMotion = pan.getDistance() if (zoomMotion > touchSlop) { gestureType = GestureType.ZOOM break } if (panMotion > touchSlop) { gestureType = GestureType.DRAG break } } while (event.changes.fastAny { it.pressed }) return gestureType } enum class GestureType { DRAG, ZOOM } ΞϓϦͷཁ݅Λຬͨͤͳ͍ͷͰdetectؔ਺Λࣗ෼Ͱॻ͍ͨ ※Ջͳͱ͖ʹݟͯͶ https://bit.ly/composegesture
  5. ‣ Catlogͷཁ݅తʹdetectؔ਺͔Βॻ͍ͨ ‣ ը໘֎΁ͷυϥοά͸ෆՄ ‣ εςοΧʔ͔Βը໘୺·Ͱͷڑ཭ΛܭࢉɺͦΕΛ௒͑Δ dragAmount͸࡟Δ ‣ υϥοάதʹCenterVertically |

    CenterHorizontally෇ۙʹ͖ͨΒͦ ͜΁εφοϓ ‣ ը໘୺໰୊ͱεφοϓΛߟྀͯ͠࠷ऴతͳdragAmountΛܾఆ͢Δ ‣ ը໘୺ͰZoomͨ͠Βը໘֎ʹ͸Έग़ͪΌ͍·͢ΑͶ ‣ Ͱ͔͘ͳͬͯը໘֎ʹग़ͯ͠·ͬͨ෼ը໘಺΁ͣΒͯ͋͛͠Δ ͩΔ͔ͬͨࣄ