@deck.gl-community/bing-maps 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/README.md +96 -0
- package/dist/deck-overlay.d.ts +19 -0
- package/dist/deck-overlay.js +59 -0
- package/dist/index.cjs +208 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/load-module.d.ts +9 -0
- package/dist/load-module.js +31 -0
- package/dist/utils.d.ts +13 -0
- package/dist/utils.js +106 -0
- package/package.json +42 -0
- package/src/deck-overlay.ts +72 -0
- package/src/index.ts +5 -0
- package/src/load-module.ts +45 -0
- package/src/utils.ts +136 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2020 vis.gl a Series of LF Projects, LLC
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# @deck.gl-community/bing-maps
|
|
2
|
+
|
|
3
|
+
This module allows [deck.gl](https://deck.gl) to be used as a Bing Maps custom layer.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install deck.gl @deck.gl-community/bing-maps
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import {loadModules} from '@deck.gl-community/bing-maps';
|
|
15
|
+
import {GeoJsonLayer} from 'deck.gl';
|
|
16
|
+
|
|
17
|
+
loadModules().then(({Maps, Location, DeckOverlay}) => {
|
|
18
|
+
// Create map
|
|
19
|
+
const map = new Map(document.getElementById('map'), {
|
|
20
|
+
credentials: 'YOUR_API_KEY',
|
|
21
|
+
// Disable modes that are not supported
|
|
22
|
+
disableBirdsEye: true,
|
|
23
|
+
disableStreetside: true
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
map.setView({
|
|
27
|
+
center: new Location(37.78, -122.45),
|
|
28
|
+
zoom: 10
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Add deck.gl overlay
|
|
32
|
+
const deckOverlay = new DeckOverlay({
|
|
33
|
+
layers: [
|
|
34
|
+
new GeoJsonLayer({
|
|
35
|
+
data:
|
|
36
|
+
'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_admin_0_scale_rank.geojson',
|
|
37
|
+
lineWidthMinPixels: 2,
|
|
38
|
+
getLineColor: [60, 60, 60],
|
|
39
|
+
getFillColor: [200, 200, 200]
|
|
40
|
+
})
|
|
41
|
+
]
|
|
42
|
+
});
|
|
43
|
+
map.layers.insert(deckOverlay);
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API Reference
|
|
48
|
+
|
|
49
|
+
### loadModules
|
|
50
|
+
|
|
51
|
+
`loadModules(moduleNames)`
|
|
52
|
+
|
|
53
|
+
Arguments:
|
|
54
|
+
|
|
55
|
+
- `moduleNames` (Array<String>?) - Optional modules to load, e.g. `'Microsoft.Maps.GeoJson'`, `'Microsoft.Maps.DrawingTools'`
|
|
56
|
+
|
|
57
|
+
Returns a Promise that resolves to the global `Microsoft.Maps` namespace. A custom class, `DeckOverlay`, is also added to the namespace.
|
|
58
|
+
|
|
59
|
+
### DeckOverlay
|
|
60
|
+
|
|
61
|
+
An implementation of [CustomOverlay](https://docs.microsoft.com/en-us/bingmaps/v8-web-control/map-control-api/customoverlay-class).
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
const deckOverlay = new DeckOverlay({...});
|
|
65
|
+
map.layers.insert(deckOverlay);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The constructor accepts a props object that is passed to the [Deck](https://deck.gl/docs/api-reference/core/deck) constructor. See the [limitations](#supported-features-and-limitations) section below for more details.
|
|
69
|
+
|
|
70
|
+
The following [Deck methods](https://deck.gl/docs/api-reference/core/deck#methods) can be called directly from a `DeckOverlay` instance:
|
|
71
|
+
|
|
72
|
+
- `deckOverlay.setProps`
|
|
73
|
+
- `deckOverlay.pickObject`
|
|
74
|
+
- `deckOverlay.pickMultipleObjects`
|
|
75
|
+
- `deckOverlay.pickObjects`
|
|
76
|
+
- `deckOverlay.redraw`
|
|
77
|
+
- `deckOverlay.finalize`
|
|
78
|
+
|
|
79
|
+
## Supported Features and Limitations
|
|
80
|
+
|
|
81
|
+
Supported deck.gl features:
|
|
82
|
+
|
|
83
|
+
- Layers
|
|
84
|
+
- Effects
|
|
85
|
+
- Auto-highlighting
|
|
86
|
+
- Attribute transitions
|
|
87
|
+
- `onHover` and `onClick` callbacks
|
|
88
|
+
- Tooltip
|
|
89
|
+
|
|
90
|
+
Not supported features:
|
|
91
|
+
|
|
92
|
+
- Tilting
|
|
93
|
+
- Multiple views
|
|
94
|
+
- Controller
|
|
95
|
+
- React integration
|
|
96
|
+
- Gesture event callbacks (e.g. `onDrag*`)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default function getDeckOverlay({ CustomOverlay, Events, MapTypeId }: {
|
|
2
|
+
CustomOverlay: any;
|
|
3
|
+
Events: any;
|
|
4
|
+
MapTypeId: any;
|
|
5
|
+
}): {
|
|
6
|
+
new (props?: {}): {
|
|
7
|
+
[x: string]: any;
|
|
8
|
+
setProps(props: any): void;
|
|
9
|
+
pickObject(params: any): any;
|
|
10
|
+
pickMultipleObjects(params: any): any;
|
|
11
|
+
pickObjects(params: any): any;
|
|
12
|
+
finalize(): void;
|
|
13
|
+
onAdd(): void;
|
|
14
|
+
onLoad(): void;
|
|
15
|
+
onRemove(): void;
|
|
16
|
+
redraw(): void;
|
|
17
|
+
};
|
|
18
|
+
[x: string]: any;
|
|
19
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { createContainer, createDeckInstance, destroyDeckInstance, getViewState } from './utils';
|
|
5
|
+
const HIDE_ALL_LAYERS = () => false;
|
|
6
|
+
export default function getDeckOverlay({ CustomOverlay, Events, MapTypeId }) {
|
|
7
|
+
class DeckOverlay extends CustomOverlay {
|
|
8
|
+
constructor(props = {}) {
|
|
9
|
+
super();
|
|
10
|
+
this.props = props;
|
|
11
|
+
}
|
|
12
|
+
setProps(props) {
|
|
13
|
+
Object.assign(this.props, props);
|
|
14
|
+
if (this.deck) {
|
|
15
|
+
this.deck.setProps(props);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
pickObject(params) {
|
|
19
|
+
return this.deck && this.deck.pickObject(params);
|
|
20
|
+
}
|
|
21
|
+
pickMultipleObjects(params) {
|
|
22
|
+
return this.deck && this.deck.pickMultipleObjects(params);
|
|
23
|
+
}
|
|
24
|
+
pickObjects(params) {
|
|
25
|
+
return this.deck && this.deck.pickObjects(params);
|
|
26
|
+
}
|
|
27
|
+
finalize() {
|
|
28
|
+
destroyDeckInstance(this.deck, Events);
|
|
29
|
+
}
|
|
30
|
+
// Set up DOM elements, and use setHtmlElement to bind it with the overlay.
|
|
31
|
+
onAdd() {
|
|
32
|
+
this.container = createContainer(this.props.style);
|
|
33
|
+
// Add the container to the overlay
|
|
34
|
+
this.setHtmlElement(this.container);
|
|
35
|
+
}
|
|
36
|
+
// Perform custom operations after adding the overlay to the map.
|
|
37
|
+
onLoad() {
|
|
38
|
+
const map = this.getMap();
|
|
39
|
+
this.deck = createDeckInstance(map, this, this.props, Events);
|
|
40
|
+
}
|
|
41
|
+
// Remove all event handlers from the map.
|
|
42
|
+
onRemove() {
|
|
43
|
+
destroyDeckInstance(this.deck, Events);
|
|
44
|
+
this.deck = null;
|
|
45
|
+
}
|
|
46
|
+
redraw() {
|
|
47
|
+
const map = this.getMap();
|
|
48
|
+
const { deck } = this;
|
|
49
|
+
const mapType = map.getMapTypeId();
|
|
50
|
+
const canSyncWithMap = mapType !== MapTypeId.streetside && mapType !== MapTypeId.birdseye;
|
|
51
|
+
deck.setProps({
|
|
52
|
+
...getViewState(map),
|
|
53
|
+
layerFilter: canSyncWithMap ? this.props.layerFilter : HIDE_ALL_LAYERS
|
|
54
|
+
});
|
|
55
|
+
// deck.redraw();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return DeckOverlay;
|
|
59
|
+
}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// dist/index.js
|
|
20
|
+
var dist_exports = {};
|
|
21
|
+
__export(dist_exports, {
|
|
22
|
+
loadModule: () => loadModule
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(dist_exports);
|
|
25
|
+
|
|
26
|
+
// dist/utils.js
|
|
27
|
+
var import_core = require("@deck.gl/core");
|
|
28
|
+
function createContainer(style) {
|
|
29
|
+
const container = document.createElement("canvas");
|
|
30
|
+
Object.assign(container.style, {
|
|
31
|
+
position: "absolute",
|
|
32
|
+
zIndex: 0,
|
|
33
|
+
// block deck.gl's own event listeners
|
|
34
|
+
pointerEvents: "none",
|
|
35
|
+
left: 0,
|
|
36
|
+
top: 0
|
|
37
|
+
}, style);
|
|
38
|
+
return container;
|
|
39
|
+
}
|
|
40
|
+
var mouseEvents = ["click", "dblclick", "mousedown", "mousemove", "mouseout"];
|
|
41
|
+
var redrawEvents = ["viewchange", "mapresize", "maptypechanged"];
|
|
42
|
+
function createDeckInstance(map, overlay, props, Events) {
|
|
43
|
+
const eventListeners = {};
|
|
44
|
+
const deck = new import_core.Deck({
|
|
45
|
+
...props,
|
|
46
|
+
canvas: overlay.container,
|
|
47
|
+
views: new import_core.MapView({ repeat: true }),
|
|
48
|
+
...getViewState(map),
|
|
49
|
+
controller: false,
|
|
50
|
+
userData: {
|
|
51
|
+
_map: map,
|
|
52
|
+
_eventListeners: eventListeners
|
|
53
|
+
},
|
|
54
|
+
onLoad: () => {
|
|
55
|
+
if (props.onLoad) {
|
|
56
|
+
props.onLoad();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
for (const eventType of mouseEvents) {
|
|
61
|
+
eventListeners[eventType] = Events.addHandler(map, eventType, (evt) => handleMouseEvent(deck, eventType, evt));
|
|
62
|
+
}
|
|
63
|
+
for (const eventType of redrawEvents) {
|
|
64
|
+
eventListeners[eventType] = Events.addHandler(map, eventType, () => overlay.redraw());
|
|
65
|
+
}
|
|
66
|
+
return deck;
|
|
67
|
+
}
|
|
68
|
+
function getViewState(map) {
|
|
69
|
+
const zoom = map.getZoom();
|
|
70
|
+
const center = map.getCenter();
|
|
71
|
+
const width = map.getWidth();
|
|
72
|
+
const height = map.getHeight();
|
|
73
|
+
return {
|
|
74
|
+
width,
|
|
75
|
+
height,
|
|
76
|
+
viewState: {
|
|
77
|
+
longitude: center.longitude,
|
|
78
|
+
latitude: center.latitude,
|
|
79
|
+
zoom: zoom - 1
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function destroyDeckInstance(deck, Events) {
|
|
84
|
+
if (!deck)
|
|
85
|
+
return;
|
|
86
|
+
const eventListeners = deck.props.userData._eventListeners;
|
|
87
|
+
for (const eventType in eventListeners) {
|
|
88
|
+
Events.removeHandler(eventListeners[eventType]);
|
|
89
|
+
}
|
|
90
|
+
deck.finalize();
|
|
91
|
+
}
|
|
92
|
+
function handleMouseEvent(deck, type, event) {
|
|
93
|
+
const mockEvent = {
|
|
94
|
+
type,
|
|
95
|
+
offsetCenter: {
|
|
96
|
+
x: deck.props.width / 2 + event.getX(),
|
|
97
|
+
y: deck.props.height / 2 + event.getY()
|
|
98
|
+
},
|
|
99
|
+
srcEvent: event
|
|
100
|
+
};
|
|
101
|
+
switch (type) {
|
|
102
|
+
case "mousedown":
|
|
103
|
+
deck._onPointerDown(mockEvent);
|
|
104
|
+
break;
|
|
105
|
+
case "click":
|
|
106
|
+
mockEvent.tapCount = 1;
|
|
107
|
+
deck._onEvent(mockEvent);
|
|
108
|
+
break;
|
|
109
|
+
case "dblclick":
|
|
110
|
+
mockEvent.type = "click";
|
|
111
|
+
mockEvent.tapCount = 2;
|
|
112
|
+
deck._onEvent(mockEvent);
|
|
113
|
+
break;
|
|
114
|
+
case "mousemove":
|
|
115
|
+
mockEvent.type = "pointermove";
|
|
116
|
+
deck._onPointerMove(mockEvent);
|
|
117
|
+
break;
|
|
118
|
+
case "mouseout":
|
|
119
|
+
mockEvent.type = "pointerleave";
|
|
120
|
+
deck._onPointerMove(mockEvent);
|
|
121
|
+
break;
|
|
122
|
+
default:
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// dist/deck-overlay.js
|
|
128
|
+
var HIDE_ALL_LAYERS = () => false;
|
|
129
|
+
function getDeckOverlay({ CustomOverlay, Events, MapTypeId }) {
|
|
130
|
+
class DeckOverlay extends CustomOverlay {
|
|
131
|
+
constructor(props = {}) {
|
|
132
|
+
super();
|
|
133
|
+
this.props = props;
|
|
134
|
+
}
|
|
135
|
+
setProps(props) {
|
|
136
|
+
Object.assign(this.props, props);
|
|
137
|
+
if (this.deck) {
|
|
138
|
+
this.deck.setProps(props);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
pickObject(params) {
|
|
142
|
+
return this.deck && this.deck.pickObject(params);
|
|
143
|
+
}
|
|
144
|
+
pickMultipleObjects(params) {
|
|
145
|
+
return this.deck && this.deck.pickMultipleObjects(params);
|
|
146
|
+
}
|
|
147
|
+
pickObjects(params) {
|
|
148
|
+
return this.deck && this.deck.pickObjects(params);
|
|
149
|
+
}
|
|
150
|
+
finalize() {
|
|
151
|
+
destroyDeckInstance(this.deck, Events);
|
|
152
|
+
}
|
|
153
|
+
// Set up DOM elements, and use setHtmlElement to bind it with the overlay.
|
|
154
|
+
onAdd() {
|
|
155
|
+
this.container = createContainer(this.props.style);
|
|
156
|
+
this.setHtmlElement(this.container);
|
|
157
|
+
}
|
|
158
|
+
// Perform custom operations after adding the overlay to the map.
|
|
159
|
+
onLoad() {
|
|
160
|
+
const map = this.getMap();
|
|
161
|
+
this.deck = createDeckInstance(map, this, this.props, Events);
|
|
162
|
+
}
|
|
163
|
+
// Remove all event handlers from the map.
|
|
164
|
+
onRemove() {
|
|
165
|
+
destroyDeckInstance(this.deck, Events);
|
|
166
|
+
this.deck = null;
|
|
167
|
+
}
|
|
168
|
+
redraw() {
|
|
169
|
+
const map = this.getMap();
|
|
170
|
+
const { deck } = this;
|
|
171
|
+
const mapType = map.getMapTypeId();
|
|
172
|
+
const canSyncWithMap = mapType !== MapTypeId.streetside && mapType !== MapTypeId.birdseye;
|
|
173
|
+
deck.setProps({
|
|
174
|
+
...getViewState(map),
|
|
175
|
+
layerFilter: canSyncWithMap ? this.props.layerFilter : HIDE_ALL_LAYERS
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return DeckOverlay;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// dist/load-module.js
|
|
183
|
+
var BING_MAPS_API_URL = "https://www.bing.com/api/maps/mapcontrol?callback=__loadBingMaps";
|
|
184
|
+
function loadModule(moduleNames) {
|
|
185
|
+
return new Promise((resolve) => {
|
|
186
|
+
window.__loadBingMaps = () => {
|
|
187
|
+
const namespace = window.Microsoft.Maps;
|
|
188
|
+
namespace.DeckOverlay = getDeckOverlay(namespace);
|
|
189
|
+
delete window.__loadBingMaps;
|
|
190
|
+
if (moduleNames) {
|
|
191
|
+
Promise.all(moduleNames.map((m) => awaitCallback(namespace.loadModule, m))).then(() => resolve(namespace));
|
|
192
|
+
} else {
|
|
193
|
+
resolve(namespace);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const script = document.createElement("script");
|
|
197
|
+
script.type = "text/javascript";
|
|
198
|
+
script.src = BING_MAPS_API_URL;
|
|
199
|
+
const head = document.querySelector("head");
|
|
200
|
+
head.appendChild(script);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function awaitCallback(func, ...args) {
|
|
204
|
+
return new Promise((resolve) => {
|
|
205
|
+
func(...args, resolve);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["index.js", "utils.js", "deck-overlay.js", "load-module.js"],
|
|
4
|
+
"sourcesContent": ["// deck.gl-community\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nexport { default as loadModule } from './load-module';\n", "// deck.gl-community\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport { Deck, MapView } from '@deck.gl/core';\nexport function createContainer(style) {\n const container = document.createElement('canvas');\n Object.assign(container.style, {\n position: 'absolute',\n zIndex: 0,\n // block deck.gl's own event listeners\n pointerEvents: 'none',\n left: 0,\n top: 0\n }, style);\n return container;\n}\nconst mouseEvents = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout'];\nconst redrawEvents = ['viewchange', 'mapresize', 'maptypechanged'];\nexport function createDeckInstance(map, overlay, props, Events) {\n const eventListeners = {};\n const deck = new Deck({\n ...props,\n canvas: overlay.container,\n views: new MapView({ repeat: true }),\n ...getViewState(map),\n controller: false,\n userData: {\n _map: map,\n _eventListeners: eventListeners\n },\n onLoad: () => {\n // TODO: .tooltip is protected, find another way to set this.\n // Bing Maps' label canvas has z-index of 20000\n // deck.tooltip.el.style.zIndex = 30000;\n if (props.onLoad) {\n props.onLoad();\n }\n }\n });\n // Register event listeners\n for (const eventType of mouseEvents) {\n eventListeners[eventType] = Events.addHandler(map, eventType, (evt) => handleMouseEvent(deck, eventType, evt));\n }\n for (const eventType of redrawEvents) {\n eventListeners[eventType] = Events.addHandler(map, eventType, () => overlay.redraw());\n }\n return deck;\n}\nexport function getViewState(map) {\n const zoom = map.getZoom();\n const center = map.getCenter();\n const width = map.getWidth();\n const height = map.getHeight();\n return {\n width,\n height,\n viewState: {\n longitude: center.longitude,\n latitude: center.latitude,\n zoom: zoom - 1\n }\n };\n}\nexport function destroyDeckInstance(deck, Events) {\n if (!deck)\n return;\n const eventListeners = deck.props.userData._eventListeners;\n for (const eventType in eventListeners) {\n Events.removeHandler(eventListeners[eventType]);\n }\n deck.finalize();\n}\nfunction handleMouseEvent(deck, type, event) {\n const mockEvent = {\n type,\n offsetCenter: {\n x: deck.props.width / 2 + event.getX(),\n y: deck.props.height / 2 + event.getY()\n },\n srcEvent: event\n };\n switch (type) {\n case 'mousedown':\n deck._onPointerDown(mockEvent);\n break;\n case 'click':\n mockEvent.tapCount = 1;\n deck._onEvent(mockEvent);\n break;\n case 'dblclick':\n mockEvent.type = 'click';\n mockEvent.tapCount = 2;\n deck._onEvent(mockEvent);\n break;\n case 'mousemove':\n mockEvent.type = 'pointermove';\n deck._onPointerMove(mockEvent);\n break;\n case 'mouseout':\n mockEvent.type = 'pointerleave';\n deck._onPointerMove(mockEvent);\n break;\n default:\n return;\n }\n}\n", "// deck.gl-community\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport { createContainer, createDeckInstance, destroyDeckInstance, getViewState } from './utils';\nconst HIDE_ALL_LAYERS = () => false;\nexport default function getDeckOverlay({ CustomOverlay, Events, MapTypeId }) {\n class DeckOverlay extends CustomOverlay {\n constructor(props = {}) {\n super();\n this.props = props;\n }\n setProps(props) {\n Object.assign(this.props, props);\n if (this.deck) {\n this.deck.setProps(props);\n }\n }\n pickObject(params) {\n return this.deck && this.deck.pickObject(params);\n }\n pickMultipleObjects(params) {\n return this.deck && this.deck.pickMultipleObjects(params);\n }\n pickObjects(params) {\n return this.deck && this.deck.pickObjects(params);\n }\n finalize() {\n destroyDeckInstance(this.deck, Events);\n }\n // Set up DOM elements, and use setHtmlElement to bind it with the overlay.\n onAdd() {\n this.container = createContainer(this.props.style);\n // Add the container to the overlay\n this.setHtmlElement(this.container);\n }\n // Perform custom operations after adding the overlay to the map.\n onLoad() {\n const map = this.getMap();\n this.deck = createDeckInstance(map, this, this.props, Events);\n }\n // Remove all event handlers from the map.\n onRemove() {\n destroyDeckInstance(this.deck, Events);\n this.deck = null;\n }\n redraw() {\n const map = this.getMap();\n const { deck } = this;\n const mapType = map.getMapTypeId();\n const canSyncWithMap = mapType !== MapTypeId.streetside && mapType !== MapTypeId.birdseye;\n deck.setProps({\n ...getViewState(map),\n layerFilter: canSyncWithMap ? this.props.layerFilter : HIDE_ALL_LAYERS\n });\n // deck.redraw();\n }\n }\n return DeckOverlay;\n}\n", "// deck.gl-community\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport getDeckOverlay from './deck-overlay';\nconst BING_MAPS_API_URL = 'https://www.bing.com/api/maps/mapcontrol?callback=__loadBingMaps';\nexport default function loadModule(moduleNames) {\n return new Promise((resolve) => {\n // Callback\n window.__loadBingMaps = () => {\n const namespace = window.Microsoft.Maps;\n namespace.DeckOverlay = getDeckOverlay(namespace);\n delete window.__loadBingMaps;\n if (moduleNames) {\n Promise.all(moduleNames.map((m) => awaitCallback(namespace.loadModule, m))).then(() => resolve(namespace));\n }\n else {\n resolve(namespace);\n }\n };\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = BING_MAPS_API_URL;\n const head = document.querySelector('head');\n head.appendChild(script);\n });\n}\nfunction awaitCallback(func, ...args) {\n return new Promise((resolve) => {\n func(...args, resolve);\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as loadModule } from './load-module';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import getDeckOverlay from './deck-overlay';
|
|
5
|
+
const BING_MAPS_API_URL = 'https://www.bing.com/api/maps/mapcontrol?callback=__loadBingMaps';
|
|
6
|
+
export default function loadModule(moduleNames) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
// Callback
|
|
9
|
+
window.__loadBingMaps = () => {
|
|
10
|
+
const namespace = window.Microsoft.Maps;
|
|
11
|
+
namespace.DeckOverlay = getDeckOverlay(namespace);
|
|
12
|
+
delete window.__loadBingMaps;
|
|
13
|
+
if (moduleNames) {
|
|
14
|
+
Promise.all(moduleNames.map((m) => awaitCallback(namespace.loadModule, m))).then(() => resolve(namespace));
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
resolve(namespace);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const script = document.createElement('script');
|
|
21
|
+
script.type = 'text/javascript';
|
|
22
|
+
script.src = BING_MAPS_API_URL;
|
|
23
|
+
const head = document.querySelector('head');
|
|
24
|
+
head.appendChild(script);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function awaitCallback(func, ...args) {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
func(...args, resolve);
|
|
30
|
+
});
|
|
31
|
+
}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Deck } from '@deck.gl/core';
|
|
2
|
+
export declare function createContainer(style: any): HTMLCanvasElement;
|
|
3
|
+
export declare function createDeckInstance(map: any, overlay: any, props: any, Events: any): Deck<null>;
|
|
4
|
+
export declare function getViewState(map: any): {
|
|
5
|
+
width: any;
|
|
6
|
+
height: any;
|
|
7
|
+
viewState: {
|
|
8
|
+
longitude: any;
|
|
9
|
+
latitude: any;
|
|
10
|
+
zoom: number;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export declare function destroyDeckInstance(deck: any, Events: any): void;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { Deck, MapView } from '@deck.gl/core';
|
|
5
|
+
export function createContainer(style) {
|
|
6
|
+
const container = document.createElement('canvas');
|
|
7
|
+
Object.assign(container.style, {
|
|
8
|
+
position: 'absolute',
|
|
9
|
+
zIndex: 0,
|
|
10
|
+
// block deck.gl's own event listeners
|
|
11
|
+
pointerEvents: 'none',
|
|
12
|
+
left: 0,
|
|
13
|
+
top: 0
|
|
14
|
+
}, style);
|
|
15
|
+
return container;
|
|
16
|
+
}
|
|
17
|
+
const mouseEvents = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout'];
|
|
18
|
+
const redrawEvents = ['viewchange', 'mapresize', 'maptypechanged'];
|
|
19
|
+
export function createDeckInstance(map, overlay, props, Events) {
|
|
20
|
+
const eventListeners = {};
|
|
21
|
+
const deck = new Deck({
|
|
22
|
+
...props,
|
|
23
|
+
canvas: overlay.container,
|
|
24
|
+
views: new MapView({ repeat: true }),
|
|
25
|
+
...getViewState(map),
|
|
26
|
+
controller: false,
|
|
27
|
+
userData: {
|
|
28
|
+
_map: map,
|
|
29
|
+
_eventListeners: eventListeners
|
|
30
|
+
},
|
|
31
|
+
onLoad: () => {
|
|
32
|
+
// TODO: .tooltip is protected, find another way to set this.
|
|
33
|
+
// Bing Maps' label canvas has z-index of 20000
|
|
34
|
+
// deck.tooltip.el.style.zIndex = 30000;
|
|
35
|
+
if (props.onLoad) {
|
|
36
|
+
props.onLoad();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// Register event listeners
|
|
41
|
+
for (const eventType of mouseEvents) {
|
|
42
|
+
eventListeners[eventType] = Events.addHandler(map, eventType, (evt) => handleMouseEvent(deck, eventType, evt));
|
|
43
|
+
}
|
|
44
|
+
for (const eventType of redrawEvents) {
|
|
45
|
+
eventListeners[eventType] = Events.addHandler(map, eventType, () => overlay.redraw());
|
|
46
|
+
}
|
|
47
|
+
return deck;
|
|
48
|
+
}
|
|
49
|
+
export function getViewState(map) {
|
|
50
|
+
const zoom = map.getZoom();
|
|
51
|
+
const center = map.getCenter();
|
|
52
|
+
const width = map.getWidth();
|
|
53
|
+
const height = map.getHeight();
|
|
54
|
+
return {
|
|
55
|
+
width,
|
|
56
|
+
height,
|
|
57
|
+
viewState: {
|
|
58
|
+
longitude: center.longitude,
|
|
59
|
+
latitude: center.latitude,
|
|
60
|
+
zoom: zoom - 1
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export function destroyDeckInstance(deck, Events) {
|
|
65
|
+
if (!deck)
|
|
66
|
+
return;
|
|
67
|
+
const eventListeners = deck.props.userData._eventListeners;
|
|
68
|
+
for (const eventType in eventListeners) {
|
|
69
|
+
Events.removeHandler(eventListeners[eventType]);
|
|
70
|
+
}
|
|
71
|
+
deck.finalize();
|
|
72
|
+
}
|
|
73
|
+
function handleMouseEvent(deck, type, event) {
|
|
74
|
+
const mockEvent = {
|
|
75
|
+
type,
|
|
76
|
+
offsetCenter: {
|
|
77
|
+
x: deck.props.width / 2 + event.getX(),
|
|
78
|
+
y: deck.props.height / 2 + event.getY()
|
|
79
|
+
},
|
|
80
|
+
srcEvent: event
|
|
81
|
+
};
|
|
82
|
+
switch (type) {
|
|
83
|
+
case 'mousedown':
|
|
84
|
+
deck._onPointerDown(mockEvent);
|
|
85
|
+
break;
|
|
86
|
+
case 'click':
|
|
87
|
+
mockEvent.tapCount = 1;
|
|
88
|
+
deck._onEvent(mockEvent);
|
|
89
|
+
break;
|
|
90
|
+
case 'dblclick':
|
|
91
|
+
mockEvent.type = 'click';
|
|
92
|
+
mockEvent.tapCount = 2;
|
|
93
|
+
deck._onEvent(mockEvent);
|
|
94
|
+
break;
|
|
95
|
+
case 'mousemove':
|
|
96
|
+
mockEvent.type = 'pointermove';
|
|
97
|
+
deck._onPointerMove(mockEvent);
|
|
98
|
+
break;
|
|
99
|
+
case 'mouseout':
|
|
100
|
+
mockEvent.type = 'pointerleave';
|
|
101
|
+
deck._onPointerMove(mockEvent);
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deck.gl-community/bing-maps",
|
|
3
|
+
"description": "deck.gl integration with Bing Maps",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"version": "9.0.1",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"webgl",
|
|
11
|
+
"visualization",
|
|
12
|
+
"bing maps"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/visgl/deck.gl-community.gl.git"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"main": "./dist/index.cjs",
|
|
22
|
+
"module": "./dist/index.js",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"require": "./dist/index.cjs",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"src"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test-watch": "vitest"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@deck.gl/core": "^9.0.12"
|
|
40
|
+
},
|
|
41
|
+
"gitHead": "646f8328d27d67d596f05c9154072051ec5cf4f0"
|
|
42
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {createContainer, createDeckInstance, destroyDeckInstance, getViewState} from './utils';
|
|
6
|
+
|
|
7
|
+
const HIDE_ALL_LAYERS = () => false;
|
|
8
|
+
|
|
9
|
+
export default function getDeckOverlay({CustomOverlay, Events, MapTypeId}) {
|
|
10
|
+
class DeckOverlay extends CustomOverlay {
|
|
11
|
+
constructor(props = {}) {
|
|
12
|
+
super();
|
|
13
|
+
this.props = props;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
setProps(props) {
|
|
17
|
+
Object.assign(this.props, props);
|
|
18
|
+
if (this.deck) {
|
|
19
|
+
this.deck.setProps(props);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pickObject(params) {
|
|
24
|
+
return this.deck && this.deck.pickObject(params);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pickMultipleObjects(params) {
|
|
28
|
+
return this.deck && this.deck.pickMultipleObjects(params);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
pickObjects(params) {
|
|
32
|
+
return this.deck && this.deck.pickObjects(params);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
finalize() {
|
|
36
|
+
destroyDeckInstance(this.deck, Events);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Set up DOM elements, and use setHtmlElement to bind it with the overlay.
|
|
40
|
+
onAdd() {
|
|
41
|
+
this.container = createContainer(this.props.style);
|
|
42
|
+
// Add the container to the overlay
|
|
43
|
+
this.setHtmlElement(this.container);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Perform custom operations after adding the overlay to the map.
|
|
47
|
+
onLoad() {
|
|
48
|
+
const map = this.getMap();
|
|
49
|
+
this.deck = createDeckInstance(map, this, this.props, Events);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Remove all event handlers from the map.
|
|
53
|
+
onRemove() {
|
|
54
|
+
destroyDeckInstance(this.deck, Events);
|
|
55
|
+
this.deck = null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
redraw() {
|
|
59
|
+
const map = this.getMap();
|
|
60
|
+
const {deck} = this;
|
|
61
|
+
const mapType = map.getMapTypeId();
|
|
62
|
+
const canSyncWithMap = mapType !== MapTypeId.streetside && mapType !== MapTypeId.birdseye;
|
|
63
|
+
deck.setProps({
|
|
64
|
+
...getViewState(map),
|
|
65
|
+
layerFilter: canSyncWithMap ? this.props.layerFilter : HIDE_ALL_LAYERS
|
|
66
|
+
});
|
|
67
|
+
// deck.redraw();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return DeckOverlay;
|
|
72
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import getDeckOverlay from './deck-overlay';
|
|
6
|
+
|
|
7
|
+
const BING_MAPS_API_URL = 'https://www.bing.com/api/maps/mapcontrol?callback=__loadBingMaps';
|
|
8
|
+
|
|
9
|
+
declare global {
|
|
10
|
+
interface Window {
|
|
11
|
+
__loadBingMaps: (() => void) | undefined;
|
|
12
|
+
Microsoft: {Maps: any};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default function loadModule(moduleNames?: string[]) {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
// Callback
|
|
19
|
+
window.__loadBingMaps = () => {
|
|
20
|
+
const namespace: any = window.Microsoft.Maps;
|
|
21
|
+
namespace.DeckOverlay = getDeckOverlay(namespace);
|
|
22
|
+
delete window.__loadBingMaps;
|
|
23
|
+
|
|
24
|
+
if (moduleNames) {
|
|
25
|
+
Promise.all(moduleNames.map((m) => awaitCallback(namespace.loadModule, m))).then(() =>
|
|
26
|
+
resolve(namespace)
|
|
27
|
+
);
|
|
28
|
+
} else {
|
|
29
|
+
resolve(namespace);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const script = document.createElement('script');
|
|
34
|
+
script.type = 'text/javascript';
|
|
35
|
+
script.src = BING_MAPS_API_URL;
|
|
36
|
+
const head = document.querySelector('head');
|
|
37
|
+
head.appendChild(script);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function awaitCallback(func: Function, ...args: unknown[]) {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
func(...args, resolve);
|
|
44
|
+
});
|
|
45
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {Deck, MapView} from '@deck.gl/core';
|
|
6
|
+
|
|
7
|
+
export function createContainer(style) {
|
|
8
|
+
const container = document.createElement('canvas');
|
|
9
|
+
Object.assign(
|
|
10
|
+
container.style,
|
|
11
|
+
{
|
|
12
|
+
position: 'absolute',
|
|
13
|
+
zIndex: 0,
|
|
14
|
+
// block deck.gl's own event listeners
|
|
15
|
+
pointerEvents: 'none',
|
|
16
|
+
left: 0,
|
|
17
|
+
top: 0
|
|
18
|
+
},
|
|
19
|
+
style
|
|
20
|
+
);
|
|
21
|
+
return container;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const mouseEvents = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout'];
|
|
25
|
+
const redrawEvents = ['viewchange', 'mapresize', 'maptypechanged'];
|
|
26
|
+
|
|
27
|
+
export function createDeckInstance(map, overlay, props, Events) {
|
|
28
|
+
const eventListeners = {};
|
|
29
|
+
|
|
30
|
+
const deck = new Deck({
|
|
31
|
+
...props,
|
|
32
|
+
canvas: overlay.container,
|
|
33
|
+
|
|
34
|
+
views: new MapView({repeat: true}),
|
|
35
|
+
...getViewState(map),
|
|
36
|
+
controller: false,
|
|
37
|
+
userData: {
|
|
38
|
+
_map: map,
|
|
39
|
+
_eventListeners: eventListeners
|
|
40
|
+
},
|
|
41
|
+
onLoad: () => {
|
|
42
|
+
// TODO: .tooltip is protected, find another way to set this.
|
|
43
|
+
// Bing Maps' label canvas has z-index of 20000
|
|
44
|
+
// deck.tooltip.el.style.zIndex = 30000;
|
|
45
|
+
if (props.onLoad) {
|
|
46
|
+
props.onLoad();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Register event listeners
|
|
52
|
+
for (const eventType of mouseEvents) {
|
|
53
|
+
eventListeners[eventType] = Events.addHandler(map, eventType, (evt) =>
|
|
54
|
+
handleMouseEvent(deck, eventType, evt)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
for (const eventType of redrawEvents) {
|
|
58
|
+
eventListeners[eventType] = Events.addHandler(map, eventType, () => overlay.redraw());
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return deck;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getViewState(map) {
|
|
65
|
+
const zoom = map.getZoom();
|
|
66
|
+
const center = map.getCenter();
|
|
67
|
+
const width = map.getWidth();
|
|
68
|
+
const height = map.getHeight();
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
width,
|
|
72
|
+
height,
|
|
73
|
+
viewState: {
|
|
74
|
+
longitude: center.longitude,
|
|
75
|
+
latitude: center.latitude,
|
|
76
|
+
zoom: zoom - 1
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function destroyDeckInstance(deck, Events) {
|
|
82
|
+
if (!deck) return;
|
|
83
|
+
const eventListeners = deck.props.userData._eventListeners;
|
|
84
|
+
for (const eventType in eventListeners) {
|
|
85
|
+
Events.removeHandler(eventListeners[eventType]);
|
|
86
|
+
}
|
|
87
|
+
deck.finalize();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface MockEvent {
|
|
91
|
+
type: string;
|
|
92
|
+
offsetCenter: {x: number; y: number};
|
|
93
|
+
srcEvent: unknown;
|
|
94
|
+
tapCount?: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function handleMouseEvent(deck, type, event) {
|
|
98
|
+
const mockEvent: MockEvent = {
|
|
99
|
+
type,
|
|
100
|
+
offsetCenter: {
|
|
101
|
+
x: deck.props.width / 2 + event.getX(),
|
|
102
|
+
y: deck.props.height / 2 + event.getY()
|
|
103
|
+
},
|
|
104
|
+
srcEvent: event
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
switch (type) {
|
|
108
|
+
case 'mousedown':
|
|
109
|
+
deck._onPointerDown(mockEvent);
|
|
110
|
+
break;
|
|
111
|
+
|
|
112
|
+
case 'click':
|
|
113
|
+
mockEvent.tapCount = 1;
|
|
114
|
+
deck._onEvent(mockEvent);
|
|
115
|
+
break;
|
|
116
|
+
|
|
117
|
+
case 'dblclick':
|
|
118
|
+
mockEvent.type = 'click';
|
|
119
|
+
mockEvent.tapCount = 2;
|
|
120
|
+
deck._onEvent(mockEvent);
|
|
121
|
+
break;
|
|
122
|
+
|
|
123
|
+
case 'mousemove':
|
|
124
|
+
mockEvent.type = 'pointermove';
|
|
125
|
+
deck._onPointerMove(mockEvent);
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case 'mouseout':
|
|
129
|
+
mockEvent.type = 'pointerleave';
|
|
130
|
+
deck._onPointerMove(mockEvent);
|
|
131
|
+
break;
|
|
132
|
+
|
|
133
|
+
default:
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|