Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Jetpack Compose drag gesture and pinch gesture
Search
Moyuru Aizawa
April 21, 2023
Programming
4.3k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Jetpack Compose drag gesture and pinch gesture
Moyuru Aizawa
April 21, 2023
More Decks by Moyuru Aizawa
See All by Moyuru Aizawa
BLUETOOTH_SCAN and iBeacon
lvla
1
150
graphicsLayer
lvla
0
290
BluetoothDevice.getName()に裏切られた話
lvla
0
410
Jetpack Composeで画像クロップ機能を実装する
lvla
0
1.3k
Jetpack Compose Layout API
lvla
1
710
BLEを使ったアプリを継続的に開発するために
lvla
0
1.1k
RecyclerView.ItemAnimator
lvla
1
380
RecycledViewPool
lvla
1
290
CameraX
lvla
2
2.5k
Other Decks in Programming
See All in Programming
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
0
220
Foundation Models frameworkで画像分析
ryodeveloper
1
120
Prismを使った型安全な暗号化_関数型まつり2026
_fhhmm
0
140
yield再入門 #phpcon
o0h
PRO
0
400
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
6.2k
フィードバックで育てるAI開発
kotaminato
1
120
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
8
4.3k
【やさしく解説 設計編 #0】DDDのコード、読めるのに分からない人へ
panda728
PRO
2
270
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
9.1k
霧の中の代数的エフェクト
funnyycat
1
390
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
110
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
330
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
RailsConf 2023
tenderlove
30
1.5k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
3
1.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
340
Context Engineering - Making Every Token Count
addyosmani
9
1k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Transcript
Jetpack Compose Drag Gesture / Pinch Gesture @MoyuruAizawa
Moyuru Aizawa Software Engineer of Catlog, RABO. Previously at Azit,
CyberAgent, and Eureka. Love Metal, Hardcore and EDM. MoyuruAizawa
github.com/MoyuruAizawa/Cropify
࠷ۙࣄͰ Drag Gestureͱ͔Pinch Gestureͱ͔ ѻͬͨͷͰͦͷհ
CatlogͬͯԿ? Catlog Catlog Board ŮŧŠźƃɺͪΌΜͱ͏Μͨ͜͠?͓ͬͨ͜͠͠? සͩͬͨΓ͠ͳ͍? ମॏͷٸܹͳ૿ݮͱ͔ͯ͠ͳ͍? ͬͯͷ͕͔Δੌ͍IoT൘ ŮŧŠźƃɺӡಈͯ͠Δ?ͪΌΜͱ͝൧৯ͯΔ?Α͘৸ΕͯΔ? ͬͯͷ͕͔Δੌ͍IoTϖϯμϯτ
None
ݩؾείΞମॏτϨϯυɺτΠϨճ ɺ৯ࣄճͳͲ ͋ΒΏΔCatlogσʔλΛγΣΞͯ͠͏ͪ ͷࢠࣗຫͰ͖Δػೳ
‣ ༷ʑͳσʔλΛεςοΧʔԽͯ͠ஔ ‣ υϥοάͯ͠ҠಈͰ͖ΔΑ ‣ ը໘্ΑΓ্ʹυϥοάͨ͠ΒআͰ͖ΔΑ ‣ ϐϯνͨ͠ΒζʔϜͰ͖ΔΑ ‣ CenterVerticallyͱ͔CenterHorizontallyʹεφοϓͰ͖ΔΑ
͜ͷը໘ͷΤϯδχΞత໘നΈ
Ͳ͏Μͷ?
‣ Modifier#pointerInput ‣ PointerInputScope#detectDragGesture ‣ PointerInputScope#detectTransformGesture ॆ࣮ͷgesture API
modifier .pointerInput(Unit) { detectDragGestures { change, dragAmount -> state.offset +=
dragAmount } } .graphicsLayer { translationX = state.offset.x translationY = state.offset.y } PointerInput#detectDragGestures
modifier .pointerInput(Unit) { detectTransformGestures { centroid, pan, zoom, rotation ->
state.scale *= zoom } } .graphicsLayer { scaleX = state.scale scaleY = state.scale } PointerInput#detectTransformGestures
‣ PointerInputScope#detectDragGesture ‣ Drag͚͖͍ͩͨ͞ͳΒ͍ͭ͜Λ͑OK ‣ PointerInputScope#detectTransformGesture ‣ DragҎ֎ʹZoomRotationѻ͍͍ͨͳΒ͜Ε ‣ ֤δΣενϟʔͷ͕ಉ࣌ʹ͘ΔͷͰͲͷδΣενϟʔ͕ܧଓதͳ
ͷ͔ผ͍͠ ‣ Zoom͠ͳ͕ΒDragͱ͔Ͱ͖ͪΌ͏ ‣ onGestureStart, onGestureEndίʔϧόοΫແ͍ APIੇධ
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
‣ Catlogͷཁ݅తʹdetect͔ؔΒॻ͍ͨ ‣ ը໘֎ͷυϥοάෆՄ ‣ εςοΧʔ͔Βը໘·ͰͷڑΛܭࢉɺͦΕΛ͑Δ dragAmountΔ ‣ υϥοάதʹCenterVertically |
CenterHorizontallyۙʹ͖ͨΒͦ ͜εφοϓ ‣ ը໘ͱεφοϓΛߟྀͯ͠࠷ऴతͳdragAmountΛܾఆ͢Δ ‣ ը໘ͰZoomͨ͠Βը໘֎ʹΈग़ͪΌ͍·͢ΑͶ ‣ Ͱ͔͘ͳͬͯը໘֎ʹग़ͯ͠·ͬͨը໘ͣΒͯ͋͛͠Δ ͩΔ͔ͬͨࣄ
δΣενϟʔ࣮͢Δ͚ͩͳΒ؆୯ ΞϓϦͷཁ݅ʹΑͬͯͪΐͬͱμϧ͍
Thank you