-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
DragRotateAndZoom.js
136 lines (121 loc) · 3.68 KB
/
DragRotateAndZoom.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
/**
* @module ol/interaction/DragRotateAndZoom
*/
import PointerInteraction from './Pointer.js';
import {mouseOnly, shiftKeyOnly} from '../events/condition.js';
/**
* @typedef {Object} Options
* @property {import("../events/condition.js").Condition} [condition] A function that
* takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
* boolean to indicate whether that event should be handled.
* Default is {@link module:ol/events/condition.shiftKeyOnly}.
* @property {number} [duration=400] Animation duration in milliseconds.
*/
/**
* @classdesc
* Allows the user to zoom and rotate the map by clicking and dragging
* on the map. By default, this interaction is limited to when the shift
* key is held down.
*
* This interaction is only supported for mouse devices.
*
* And this interaction is not included in the default interactions.
* @api
*/
class DragRotateAndZoom extends PointerInteraction {
/**
* @param {Options} [options] Options.
*/
constructor(options) {
options = options ? options : {};
super(/** @type {import("./Pointer.js").Options} */ (options));
/**
* @private
* @type {import("../events/condition.js").Condition}
*/
this.condition_ = options.condition ? options.condition : shiftKeyOnly;
/**
* @private
* @type {number|undefined}
*/
this.lastAngle_ = undefined;
/**
* @private
* @type {number|undefined}
*/
this.lastMagnitude_ = undefined;
/**
* @private
* @type {number}
*/
this.lastScaleDelta_ = 0;
/**
* @private
* @type {number}
*/
this.duration_ = options.duration !== undefined ? options.duration : 400;
}
/**
* Handle pointer drag events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
*/
handleDragEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) {
return;
}
const map = mapBrowserEvent.map;
const size = map.getSize();
const offset = mapBrowserEvent.pixel;
const deltaX = offset[0] - size[0] / 2;
const deltaY = size[1] / 2 - offset[1];
const theta = Math.atan2(deltaY, deltaX);
const magnitude = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
const view = map.getView();
if (this.lastAngle_ !== undefined) {
const angleDelta = this.lastAngle_ - theta;
view.adjustRotationInternal(angleDelta);
}
this.lastAngle_ = theta;
if (this.lastMagnitude_ !== undefined) {
view.adjustResolutionInternal(this.lastMagnitude_ / magnitude);
}
if (this.lastMagnitude_ !== undefined) {
this.lastScaleDelta_ = this.lastMagnitude_ / magnitude;
}
this.lastMagnitude_ = magnitude;
}
/**
* Handle pointer up events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @return {boolean} If the event was consumed.
*/
handleUpEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) {
return true;
}
const map = mapBrowserEvent.map;
const view = map.getView();
const direction = this.lastScaleDelta_ > 1 ? 1 : -1;
view.endInteraction(this.duration_, direction);
this.lastScaleDelta_ = 0;
return false;
}
/**
* Handle pointer down events.
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
* @return {boolean} If the event was consumed.
*/
handleDownEvent(mapBrowserEvent) {
if (!mouseOnly(mapBrowserEvent)) {
return false;
}
if (this.condition_(mapBrowserEvent)) {
mapBrowserEvent.map.getView().beginInteraction();
this.lastAngle_ = undefined;
this.lastMagnitude_ = undefined;
return true;
}
return false;
}
}
export default DragRotateAndZoom;