-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
Pointer.js
206 lines (185 loc) · 6.47 KB
/
Pointer.js
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/**
* @module ol/interaction/Pointer
*/
import Interaction from './Interaction.js';
import MapBrowserEventType from '../MapBrowserEventType.js';
/**
* @typedef {Object} Options
* @property {function(import("../MapBrowserEvent.js").default):boolean} [handleDownEvent]
* Function handling "down" events. If the function returns `true` then a drag
* sequence is started.
* @property {function(import("../MapBrowserEvent.js").default):void} [handleDragEvent]
* Function handling "drag" events. This function is called on "move" events
* during a drag sequence.
* @property {function(import("../MapBrowserEvent.js").default):boolean} [handleEvent]
* Method called by the map to notify the interaction that a browser event was
* dispatched to the map. The function may return `false` to prevent the
* propagation of the event to other interactions in the map's interactions
* chain.
* @property {function(import("../MapBrowserEvent.js").default):void} [handleMoveEvent]
* Function handling "move" events. This function is called on "move" events.
* This functions is also called during a drag sequence, so during a drag
* sequence both the `handleDragEvent` function and this function are called.
* If `handleDownEvent` is defined and it returns true this function will not
* be called during a drag sequence.
* @property {function(import("../MapBrowserEvent.js").default):boolean} [handleUpEvent]
* Function handling "up" events. If the function returns `false` then the
* current drag sequence is stopped.
* @property {function(boolean):boolean} [stopDown]
* Should the down event be propagated to other interactions, or should be
* stopped?
*/
/**
* @classdesc
* Base class that calls user-defined functions on `down`, `move` and `up`
* events. This class also manages "drag sequences".
*
* When the `handleDownEvent` user function returns `true` a drag sequence is
* started. During a drag sequence the `handleDragEvent` user function is
* called on `move` events. The drag sequence ends when the `handleUpEvent`
* user function is called and returns `false`.
* @api
*/
class PointerInteraction extends Interaction {
/**
* @param {Options} [options] Options.
*/
constructor(options) {
options = options ? options : {};
super(
/** @type {import("./Interaction.js").InteractionOptions} */ (options),
);
if (options.handleDownEvent) {
this.handleDownEvent = options.handleDownEvent;
}
if (options.handleDragEvent) {
this.handleDragEvent = options.handleDragEvent;
}
if (options.handleMoveEvent) {
this.handleMoveEvent = options.handleMoveEvent;
}
if (options.handleUpEvent) {
this.handleUpEvent = options.handleUpEvent;
}
if (options.stopDown) {
this.stopDown = options.stopDown;
}
/**
* @type {boolean}
* @protected
*/
this.handlingDownUpSequence = false;
/**
* @type {Array<PointerEvent>}
* @protected
*/
this.targetPointers = [];
}
/**
* Returns the current number of pointers involved in the interaction,
* e.g. `2` when two fingers are used.
* @return {number} The number of pointers.
* @api
*/
getPointerCount() {
return this.targetPointers.length;
}
/**
* Handle pointer down events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @return {boolean} If the event was consumed.
* @protected
*/
handleDownEvent(mapBrowserEvent) {
return false;
}
/**
* Handle pointer drag events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @protected
*/
handleDragEvent(mapBrowserEvent) {}
/**
* Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} and may call into
* other functions, if event sequences like e.g. 'drag' or 'down-up' etc. are
* detected.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
* @return {boolean} `false` to stop event propagation.
* @api
*/
handleEvent(mapBrowserEvent) {
if (!mapBrowserEvent.originalEvent) {
return true;
}
let stopEvent = false;
this.updateTrackedPointers_(mapBrowserEvent);
if (this.handlingDownUpSequence) {
if (mapBrowserEvent.type == MapBrowserEventType.POINTERDRAG) {
this.handleDragEvent(mapBrowserEvent);
// prevent page scrolling during dragging
mapBrowserEvent.originalEvent.preventDefault();
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERUP) {
const handledUp = this.handleUpEvent(mapBrowserEvent);
this.handlingDownUpSequence =
handledUp && this.targetPointers.length > 0;
}
} else {
if (mapBrowserEvent.type == MapBrowserEventType.POINTERDOWN) {
const handled = this.handleDownEvent(mapBrowserEvent);
this.handlingDownUpSequence = handled;
stopEvent = this.stopDown(handled);
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE) {
this.handleMoveEvent(mapBrowserEvent);
}
}
return !stopEvent;
}
/**
* Handle pointer move events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @protected
*/
handleMoveEvent(mapBrowserEvent) {}
/**
* Handle pointer up events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @return {boolean} If the event was consumed.
* @protected
*/
handleUpEvent(mapBrowserEvent) {
return false;
}
/**
* This function is used to determine if "down" events should be propagated
* to other interactions or should be stopped.
* @param {boolean} handled Was the event handled by the interaction?
* @return {boolean} Should the `down` event be stopped?
*/
stopDown(handled) {
return handled;
}
/**
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @private
*/
updateTrackedPointers_(mapBrowserEvent) {
if (mapBrowserEvent.activePointers) {
this.targetPointers = mapBrowserEvent.activePointers;
}
}
}
/**
* @param {Array<PointerEvent>} pointerEvents List of events.
* @return {{clientX: number, clientY: number}} Centroid pixel.
*/
export function centroid(pointerEvents) {
const length = pointerEvents.length;
let clientX = 0;
let clientY = 0;
for (let i = 0; i < length; i++) {
clientX += pointerEvents[i].clientX;
clientY += pointerEvents[i].clientY;
}
return {clientX: clientX / length, clientY: clientY / length};
}
export default PointerInteraction;