-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathRotationGestureHandler.kt
More file actions
93 lines (80 loc) · 2.47 KB
/
RotationGestureHandler.kt
File metadata and controls
93 lines (80 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.swmansion.gesturehandler
import android.graphics.PointF
import android.view.MotionEvent
import com.swmansion.gesturehandler.RotationGestureDetector.OnRotationGestureListener
import kotlin.math.abs
class RotationGestureHandler : GestureHandler<RotationGestureHandler>() {
private var rotationGestureDetector: RotationGestureDetector? = null
var rotation = 0.0
private set
var velocity = 0.0
private set
var anchorX: Float = Float.NaN
private set
var anchorY: Float = Float.NaN
private set
init {
setShouldCancelWhenOutside(false)
}
private val gestureListener: OnRotationGestureListener = object : OnRotationGestureListener {
override fun onRotation(detector: RotationGestureDetector): Boolean {
val prevRotation: Double = rotation
rotation += detector.rotation
val delta = detector.timeDelta
if (delta > 0) {
velocity = (rotation - prevRotation) / delta
}
if (abs(rotation) >= ROTATION_RECOGNITION_THRESHOLD && state == STATE_BEGAN) {
activate()
}
return true
}
override fun onRotationBegin(detector: RotationGestureDetector) = true
override fun onRotationEnd(detector: RotationGestureDetector) {
end()
}
}
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
if (state == STATE_UNDETERMINED) {
resetProgress()
rotationGestureDetector = RotationGestureDetector(gestureListener)
// set the anchor to the position of the first pointer as NaN causes the event not to arrive
this.anchorX = event.x
this.anchorY = event.y
begin()
}
rotationGestureDetector?.onTouchEvent(sourceEvent)
rotationGestureDetector?.let {
val point = transformPoint(PointF(it.anchorX, it.anchorY))
anchorX = point.x
anchorY = point.y
}
if (sourceEvent.actionMasked == MotionEvent.ACTION_UP) {
if (state == STATE_ACTIVE) {
end()
} else {
fail()
}
}
}
override fun activate(force: Boolean) {
// reset rotation if the handler has not yet activated
if (state != STATE_ACTIVE) {
resetProgress()
}
super.activate(force)
}
override fun onReset() {
rotationGestureDetector = null
anchorX = Float.NaN
anchorY = Float.NaN
resetProgress()
}
override fun resetProgress() {
velocity = 0.0
rotation = 0.0
}
companion object {
private const val ROTATION_RECOGNITION_THRESHOLD = Math.PI / 36.0 // 5 deg in radians
}
}