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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
スマートグラスで並列バイブコーディング
hyshu
0
290
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
act2-costs.pdf
sumedhbala
0
110
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
350
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
140
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
280
20260623_Loop Engineeringで自分の分身の問い合わせBotを作る
ryugen04
0
200
Performance Engineering for Everyone
elenatanasoiu
0
270
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
480
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
8
3.9k
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.7k
えっ!!コードを読まずに開発を!?
hananouchi
0
190
Featured
See All Featured
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
970
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
870
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Into the Great Unknown - MozCon
thekraken
41
2.6k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
How to Think Like a Performance Engineer
csswizardry
28
2.7k
Discover your Explorer Soul
emna__ayadi
2
1.2k
Balancing Empowerment & Direction
lara
6
1.2k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
72
40k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
340
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
460
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