@deck.gl/widgets 9.1.12 → 9.2.0-alpha.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/dist/compass-widget.d.ts +11 -34
- package/dist/compass-widget.d.ts.map +1 -1
- package/dist/compass-widget.js +27 -62
- package/dist/compass-widget.js.map +1 -1
- package/dist/context-menu-widget.d.ts +37 -0
- package/dist/context-menu-widget.d.ts.map +1 -0
- package/dist/context-menu-widget.js +74 -0
- package/dist/context-menu-widget.js.map +1 -0
- package/dist/dist.dev.js +2271 -581
- package/dist/fps-widget.d.ts +29 -0
- package/dist/fps-widget.d.ts.map +1 -0
- package/dist/fps-widget.js +51 -0
- package/dist/fps-widget.js.map +1 -0
- package/dist/fullscreen-widget.d.ts +15 -33
- package/dist/fullscreen-widget.d.ts.map +1 -1
- package/dist/fullscreen-widget.js +20 -51
- package/dist/fullscreen-widget.js.map +1 -1
- package/dist/geocoder-widget.d.ts +51 -0
- package/dist/geocoder-widget.d.ts.map +1 -0
- package/dist/geocoder-widget.js +138 -0
- package/dist/geocoder-widget.js.map +1 -0
- package/dist/gimbal-widget.d.ts +33 -0
- package/dist/gimbal-widget.d.ts.map +1 -0
- package/dist/gimbal-widget.js +116 -0
- package/dist/gimbal-widget.js.map +1 -0
- package/dist/index.cjs +1587 -341
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +37 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -7
- package/dist/index.js.map +1 -1
- package/dist/info-widget.d.ts +37 -0
- package/dist/info-widget.d.ts.map +1 -0
- package/dist/info-widget.js +183 -0
- package/dist/info-widget.js.map +1 -0
- package/dist/lib/components/button-group.d.ts +8 -0
- package/dist/lib/components/button-group.d.ts.map +1 -0
- package/dist/lib/components/button-group.js +7 -0
- package/dist/lib/components/button-group.js.map +1 -0
- package/dist/lib/components/dropdown-menu.d.ts +8 -0
- package/dist/lib/components/dropdown-menu.d.ts.map +1 -0
- package/dist/lib/components/dropdown-menu.js +55 -0
- package/dist/lib/components/dropdown-menu.js.map +1 -0
- package/dist/lib/components/grouped-icon-button.d.ts +8 -0
- package/dist/lib/components/grouped-icon-button.d.ts.map +1 -0
- package/dist/lib/components/grouped-icon-button.js +7 -0
- package/dist/lib/components/grouped-icon-button.js.map +1 -0
- package/dist/lib/components/icon-button.d.ts +11 -0
- package/dist/lib/components/icon-button.d.ts.map +1 -0
- package/dist/lib/components/icon-button.js +7 -0
- package/dist/lib/components/icon-button.js.map +1 -0
- package/dist/lib/components/icon-menu.d.ts +16 -0
- package/dist/lib/components/icon-menu.d.ts.map +1 -0
- package/dist/lib/components/icon-menu.js +49 -0
- package/dist/lib/components/icon-menu.js.map +1 -0
- package/dist/lib/components/simple-menu.d.ts +16 -0
- package/dist/lib/components/simple-menu.d.ts.map +1 -0
- package/dist/lib/components/simple-menu.js +30 -0
- package/dist/lib/components/simple-menu.js.map +1 -0
- package/dist/lib/geocode/geocoder-history.d.ts +23 -0
- package/dist/lib/geocode/geocoder-history.d.ts.map +1 -0
- package/dist/lib/geocode/geocoder-history.js +64 -0
- package/dist/lib/geocode/geocoder-history.js.map +1 -0
- package/dist/lib/geocode/geocoder.d.ts +15 -0
- package/dist/lib/geocode/geocoder.d.ts.map +1 -0
- package/dist/lib/geocode/geocoder.js +5 -0
- package/dist/lib/geocode/geocoder.js.map +1 -0
- package/dist/lib/geocode/geocoders.d.ts +68 -0
- package/dist/lib/geocode/geocoders.d.ts.map +1 -0
- package/dist/lib/geocode/geocoders.js +182 -0
- package/dist/lib/geocode/geocoders.js.map +1 -0
- package/dist/loading-widget.d.ts +26 -0
- package/dist/loading-widget.d.ts.map +1 -0
- package/dist/loading-widget.js +41 -0
- package/dist/loading-widget.js.map +1 -0
- package/dist/reset-view-widget.d.ts +4 -4
- package/dist/reset-view-widget.d.ts.map +1 -1
- package/dist/reset-view-widget.js +7 -10
- package/dist/reset-view-widget.js.map +1 -1
- package/dist/scale-widget.d.ts +28 -0
- package/dist/scale-widget.d.ts.map +1 -0
- package/dist/scale-widget.js +111 -0
- package/dist/scale-widget.js.map +1 -0
- package/dist/screenshot-widget.d.ts +4 -4
- package/dist/screenshot-widget.d.ts.map +1 -1
- package/dist/screenshot-widget.js +7 -14
- package/dist/screenshot-widget.js.map +1 -1
- package/dist/splitter-widget.d.ts +32 -0
- package/dist/splitter-widget.d.ts.map +1 -0
- package/dist/splitter-widget.js +123 -0
- package/dist/splitter-widget.js.map +1 -0
- package/dist/stats-widget.d.ts +36 -0
- package/dist/stats-widget.d.ts.map +1 -0
- package/dist/stats-widget.js +115 -0
- package/dist/stats-widget.js.map +1 -0
- package/dist/stylesheet.css +121 -4
- package/dist/theme-widget.d.ts +31 -0
- package/dist/theme-widget.d.ts.map +1 -0
- package/dist/theme-widget.js +83 -0
- package/dist/theme-widget.js.map +1 -0
- package/dist/themes.d.ts +65 -36
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +20 -8
- package/dist/themes.js.map +1 -1
- package/dist/timeline-widget.d.ts +59 -0
- package/dist/timeline-widget.d.ts.map +1 -0
- package/dist/timeline-widget.js +83 -0
- package/dist/timeline-widget.js.map +1 -0
- package/dist/view-selector-widget.d.ts +33 -0
- package/dist/view-selector-widget.d.ts.map +1 -0
- package/dist/view-selector-widget.js +62 -0
- package/dist/view-selector-widget.js.map +1 -0
- package/dist/zoom-widget.d.ts +14 -43
- package/dist/zoom-widget.d.ts.map +1 -1
- package/dist/zoom-widget.js +14 -56
- package/dist/zoom-widget.js.map +1 -1
- package/dist.min.js +3 -1
- package/package.json +4 -3
- package/src/compass-widget.tsx +44 -106
- package/src/context-menu-widget.tsx +115 -0
- package/src/fps-widget.tsx +67 -0
- package/src/fullscreen-widget.tsx +33 -86
- package/src/geocoder-widget.tsx +209 -0
- package/src/gimbal-widget.tsx +188 -0
- package/src/index.ts +58 -8
- package/src/info-widget.tsx +225 -0
- package/src/lib/components/button-group.tsx +16 -0
- package/src/lib/components/dropdown-menu.tsx +98 -0
- package/src/lib/components/grouped-icon-button.tsx +24 -0
- package/src/lib/components/icon-button.tsx +30 -0
- package/src/lib/components/icon-menu.tsx +89 -0
- package/src/lib/components/simple-menu.tsx +52 -0
- package/src/lib/geocode/geocoder-history.ts +73 -0
- package/src/lib/geocode/geocoder.ts +15 -0
- package/src/lib/geocode/geocoders.ts +199 -0
- package/src/loading-widget.tsx +67 -0
- package/src/reset-view-widget.tsx +8 -11
- package/src/scale-widget.tsx +183 -0
- package/src/screenshot-widget.tsx +9 -11
- package/src/splitter-widget.tsx +179 -0
- package/src/stats-widget.tsx +166 -0
- package/src/stylesheet.css +121 -4
- package/src/theme-widget.tsx +120 -0
- package/src/themes.ts +45 -12
- package/src/timeline-widget.tsx +155 -0
- package/src/view-selector-widget.tsx +108 -0
- package/src/zoom-widget.tsx +39 -113
- package/dist/components.d.ts +0 -4
- package/dist/components.d.ts.map +0 -1
- package/dist/components.js +0 -17
- package/dist/components.js.map +0 -1
- package/dist/widget-impl.d.ts +0 -29
- package/dist/widget-impl.d.ts.map +0 -1
- package/dist/widget-impl.js +0 -60
- package/dist/widget-impl.js.map +0 -1
- package/src/components.tsx +0 -38
- package/src/widget-impl.ts +0 -88
package/dist/index.cjs
CHANGED
|
@@ -24,414 +24,886 @@ __export(dist_exports, {
|
|
|
24
24
|
DarkGlassTheme: () => DarkGlassTheme,
|
|
25
25
|
DarkTheme: () => DarkTheme,
|
|
26
26
|
FullscreenWidget: () => FullscreenWidget,
|
|
27
|
+
GimbalWidget: () => GimbalWidget,
|
|
27
28
|
LightGlassTheme: () => LightGlassTheme,
|
|
28
29
|
LightTheme: () => LightTheme,
|
|
29
30
|
ResetViewWidget: () => ResetViewWidget,
|
|
30
31
|
ScreenshotWidget: () => ScreenshotWidget,
|
|
31
32
|
ZoomWidget: () => ZoomWidget,
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
_ButtonGroup: () => ButtonGroup,
|
|
34
|
+
_ContextMenuWidget: () => ContextMenuWidget,
|
|
35
|
+
_CoordinatesGeocoder: () => CoordinatesGeocoder,
|
|
36
|
+
_CurrentLocationGeocoder: () => CurrentLocationGeocoder,
|
|
37
|
+
_DropdownMenu: () => DropdownMenu,
|
|
38
|
+
_FpsWidget: () => FpsWidget,
|
|
39
|
+
_GeocoderWidget: () => GeocoderWidget,
|
|
40
|
+
_GoogleGeocoder: () => GoogleGeocoder,
|
|
41
|
+
_GroupedIconButton: () => GroupedIconButton,
|
|
42
|
+
_IconButton: () => IconButton,
|
|
43
|
+
_IconMenu: () => IconMenu,
|
|
44
|
+
_InfoWidget: () => InfoWidget,
|
|
45
|
+
_LoadingWidget: () => LoadingWidget,
|
|
46
|
+
_MapboxGeocoder: () => MapboxGeocoder,
|
|
47
|
+
_OpenCageGeocoder: () => OpenCageGeocoder,
|
|
48
|
+
_ScaleWidget: () => ScaleWidget,
|
|
49
|
+
_SimpleMenu: () => SimpleMenu,
|
|
50
|
+
_SplitterWidget: () => SplitterWidget,
|
|
51
|
+
_StatsWidget: () => StatsWidget,
|
|
52
|
+
_ThemeWidget: () => ThemeWidget,
|
|
53
|
+
_TimelineWidget: () => TimelineWidget,
|
|
54
|
+
_ViewSelectorWidget: () => ViewSelectorWidget
|
|
34
55
|
});
|
|
35
56
|
module.exports = __toCommonJS(dist_exports);
|
|
36
57
|
|
|
37
|
-
// dist/
|
|
38
|
-
var
|
|
58
|
+
// dist/zoom-widget.js
|
|
59
|
+
var import_jsx_runtime3 = require("preact/jsx-runtime");
|
|
39
60
|
var import_core = require("@deck.gl/core");
|
|
40
61
|
var import_preact = require("preact");
|
|
41
62
|
|
|
42
|
-
// dist/components.js
|
|
43
|
-
var components_exports = {};
|
|
44
|
-
__export(components_exports, {
|
|
45
|
-
ButtonGroup: () => ButtonGroup,
|
|
46
|
-
GroupedIconButton: () => GroupedIconButton,
|
|
47
|
-
IconButton: () => IconButton
|
|
48
|
-
});
|
|
63
|
+
// dist/lib/components/button-group.js
|
|
49
64
|
var import_jsx_runtime = require("preact/jsx-runtime");
|
|
50
|
-
var IconButton = (props) => {
|
|
51
|
-
const { className, label, onClick } = props;
|
|
52
|
-
return (0, import_jsx_runtime.jsx)("div", { className: "deck-widget-button", children: (0, import_jsx_runtime.jsx)("button", { className: `deck-widget-icon-button ${className}`, type: "button", onClick, title: label, children: (0, import_jsx_runtime.jsx)("div", { className: "deck-widget-icon" }) }) });
|
|
53
|
-
};
|
|
54
65
|
var ButtonGroup = (props) => {
|
|
55
66
|
const { children, orientation } = props;
|
|
56
67
|
return (0, import_jsx_runtime.jsx)("div", { className: `deck-widget-button-group ${orientation}`, children });
|
|
57
68
|
};
|
|
69
|
+
|
|
70
|
+
// dist/lib/components/grouped-icon-button.js
|
|
71
|
+
var import_jsx_runtime2 = require("preact/jsx-runtime");
|
|
58
72
|
var GroupedIconButton = (props) => {
|
|
59
73
|
const { className, label, onClick } = props;
|
|
60
|
-
return (0,
|
|
74
|
+
return (0, import_jsx_runtime2.jsx)("button", { className: `deck-widget-icon-button ${className || ""}`, type: "button", onClick, title: label, children: (0, import_jsx_runtime2.jsx)("div", { className: "deck-widget-icon" }) });
|
|
61
75
|
};
|
|
62
76
|
|
|
63
|
-
// dist/
|
|
64
|
-
var
|
|
65
|
-
constructor(props) {
|
|
66
|
-
|
|
77
|
+
// dist/zoom-widget.js
|
|
78
|
+
var ZoomWidget = class extends import_core.Widget {
|
|
79
|
+
constructor(props = {}) {
|
|
80
|
+
super(props, ZoomWidget.defaultProps);
|
|
81
|
+
this.className = "deck-widget-zoom";
|
|
67
82
|
this.placement = "top-left";
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
83
|
+
this.viewId = null;
|
|
84
|
+
this.viewports = {};
|
|
85
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
70
86
|
this.placement = props.placement ?? this.placement;
|
|
71
|
-
this.props = {
|
|
72
|
-
...props,
|
|
73
|
-
enterLabel: props.enterLabel ?? "Enter Fullscreen",
|
|
74
|
-
exitLabel: props.exitLabel ?? "Exit Fullscreen",
|
|
75
|
-
style: props.style ?? {}
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
onAdd({ deck }) {
|
|
79
|
-
const { style, className } = this.props;
|
|
80
|
-
const el = document.createElement("div");
|
|
81
|
-
el.classList.add("deck-widget", "deck-widget-fullscreen");
|
|
82
|
-
if (className)
|
|
83
|
-
el.classList.add(className);
|
|
84
|
-
(0, import_core._applyStyles)(el, style);
|
|
85
|
-
this.deck = deck;
|
|
86
|
-
this.element = el;
|
|
87
|
-
this.update();
|
|
88
|
-
document.addEventListener("fullscreenchange", this.onFullscreenChange.bind(this));
|
|
89
|
-
return el;
|
|
90
|
-
}
|
|
91
|
-
onRemove() {
|
|
92
|
-
this.deck = void 0;
|
|
93
|
-
this.element = void 0;
|
|
94
|
-
document.removeEventListener("fullscreenchange", this.onFullscreenChange.bind(this));
|
|
95
|
-
}
|
|
96
|
-
update() {
|
|
97
|
-
const { enterLabel, exitLabel } = this.props;
|
|
98
|
-
const element = this.element;
|
|
99
|
-
if (!element) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const ui = (0, import_jsx_runtime2.jsx)(IconButton, { onClick: this.handleClick.bind(this), label: this.fullscreen ? exitLabel : enterLabel, className: this.fullscreen ? "deck-widget-fullscreen-exit" : "deck-widget-fullscreen-enter" });
|
|
103
|
-
(0, import_preact.render)(ui, element);
|
|
104
87
|
}
|
|
105
88
|
setProps(props) {
|
|
106
89
|
this.placement = props.placement ?? this.placement;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (el) {
|
|
110
|
-
if (oldProps.className !== props.className) {
|
|
111
|
-
if (oldProps.className)
|
|
112
|
-
el.classList.remove(oldProps.className);
|
|
113
|
-
if (props.className)
|
|
114
|
-
el.classList.add(props.className);
|
|
115
|
-
}
|
|
116
|
-
if (!(0, import_core._deepEqual)(oldProps.style, props.style, 1)) {
|
|
117
|
-
(0, import_core._removeStyles)(el, oldProps.style);
|
|
118
|
-
(0, import_core._applyStyles)(el, props.style);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
Object.assign(this.props, props);
|
|
122
|
-
this.update();
|
|
90
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
91
|
+
super.setProps(props);
|
|
123
92
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
93
|
+
onRenderHTML(rootElement) {
|
|
94
|
+
const ui = (0, import_jsx_runtime3.jsxs)(ButtonGroup, { orientation: this.props.orientation, children: [(0, import_jsx_runtime3.jsx)(GroupedIconButton, { onClick: () => this.handleZoomIn(), label: this.props.zoomInLabel, className: "deck-widget-zoom-in" }), (0, import_jsx_runtime3.jsx)(GroupedIconButton, { onClick: () => this.handleZoomOut(), label: this.props.zoomOutLabel, className: "deck-widget-zoom-out" })] });
|
|
95
|
+
(0, import_preact.render)(ui, rootElement);
|
|
127
96
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const fullscreen = document.fullscreenElement === this.getContainer();
|
|
131
|
-
if (prevFullscreen !== fullscreen) {
|
|
132
|
-
this.fullscreen = !this.fullscreen;
|
|
133
|
-
}
|
|
134
|
-
this.update();
|
|
97
|
+
onViewportChange(viewport) {
|
|
98
|
+
this.viewports[viewport.id] = viewport;
|
|
135
99
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
100
|
+
handleZoom(viewport, nextZoom) {
|
|
101
|
+
const viewId = this.viewId || (viewport == null ? void 0 : viewport.id) || "default-view";
|
|
102
|
+
const nextViewState = {
|
|
103
|
+
...viewport,
|
|
104
|
+
zoom: nextZoom
|
|
105
|
+
};
|
|
106
|
+
if (this.props.transitionDuration > 0) {
|
|
107
|
+
nextViewState.transitionDuration = this.props.transitionDuration;
|
|
108
|
+
nextViewState.transitionInterpolator = "latitude" in nextViewState ? new import_core.FlyToInterpolator() : new import_core.LinearInterpolator();
|
|
141
109
|
}
|
|
142
|
-
this.
|
|
110
|
+
this.setViewState(viewId, nextViewState);
|
|
143
111
|
}
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
await container.requestFullscreen({ navigationUI: "hide" });
|
|
148
|
-
} else {
|
|
149
|
-
this.togglePseudoFullscreen();
|
|
112
|
+
handleZoomIn() {
|
|
113
|
+
for (const viewport of Object.values(this.viewports)) {
|
|
114
|
+
this.handleZoom(viewport, viewport.zoom + 1);
|
|
150
115
|
}
|
|
151
116
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
} else {
|
|
156
|
-
this.togglePseudoFullscreen();
|
|
117
|
+
handleZoomOut() {
|
|
118
|
+
for (const viewport of Object.values(this.viewports)) {
|
|
119
|
+
this.handleZoom(viewport, viewport.zoom - 1);
|
|
157
120
|
}
|
|
158
121
|
}
|
|
159
|
-
|
|
122
|
+
/** @todo - move to deck or widget manager */
|
|
123
|
+
setViewState(viewId, viewState) {
|
|
124
|
+
this.deck._onViewStateChange({ viewId, viewState, interactionState: {} });
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
ZoomWidget.defaultProps = {
|
|
128
|
+
...import_core.Widget.defaultProps,
|
|
129
|
+
id: "zoom",
|
|
130
|
+
placement: "top-left",
|
|
131
|
+
orientation: "vertical",
|
|
132
|
+
transitionDuration: 200,
|
|
133
|
+
zoomInLabel: "Zoom In",
|
|
134
|
+
zoomOutLabel: "Zoom Out",
|
|
135
|
+
viewId: void 0
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// dist/reset-view-widget.js
|
|
139
|
+
var import_jsx_runtime5 = require("preact/jsx-runtime");
|
|
140
|
+
var import_preact2 = require("preact");
|
|
141
|
+
var import_core2 = require("@deck.gl/core");
|
|
142
|
+
|
|
143
|
+
// dist/lib/components/icon-button.js
|
|
144
|
+
var import_jsx_runtime4 = require("preact/jsx-runtime");
|
|
145
|
+
var IconButton = (props) => {
|
|
146
|
+
const { className, label, onClick, children } = props;
|
|
147
|
+
return (0, import_jsx_runtime4.jsx)("div", { className: "deck-widget-button", children: (0, import_jsx_runtime4.jsx)("button", { className: `deck-widget-icon-button ${className}`, type: "button", onClick, title: label, children: children ? children : (0, import_jsx_runtime4.jsx)("div", { className: "deck-widget-icon" }) }) });
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// dist/reset-view-widget.js
|
|
151
|
+
var ResetViewWidget = class extends import_core2.Widget {
|
|
152
|
+
constructor(props = {}) {
|
|
153
|
+
super(props, ResetViewWidget.defaultProps);
|
|
154
|
+
this.className = "deck-widget-reset-view";
|
|
155
|
+
this.placement = "top-left";
|
|
156
|
+
this.placement = props.placement ?? this.placement;
|
|
157
|
+
}
|
|
158
|
+
setProps(props) {
|
|
159
|
+
this.placement = props.placement ?? this.placement;
|
|
160
|
+
super.setProps(props);
|
|
161
|
+
}
|
|
162
|
+
onRenderHTML(rootElement) {
|
|
163
|
+
(0, import_preact2.render)((0, import_jsx_runtime5.jsx)(IconButton, { className: "deck-widget-reset-focus", label: this.props.label, onClick: this.handleClick.bind(this) }), rootElement);
|
|
164
|
+
}
|
|
165
|
+
handleClick() {
|
|
160
166
|
var _a;
|
|
161
|
-
(_a = this.
|
|
167
|
+
const initialViewState = this.props.initialViewState || ((_a = this.deck) == null ? void 0 : _a.props.initialViewState);
|
|
168
|
+
this.setViewState(initialViewState);
|
|
169
|
+
}
|
|
170
|
+
setViewState(viewState) {
|
|
171
|
+
const viewId = this.props.viewId || (viewState == null ? void 0 : viewState.id) || "default-view";
|
|
172
|
+
const nextViewState = {
|
|
173
|
+
...viewState
|
|
174
|
+
// only works for geospatial?
|
|
175
|
+
// transitionDuration: this.props.transitionDuration,
|
|
176
|
+
// transitionInterpolator: new FlyToInterpolator()
|
|
177
|
+
};
|
|
178
|
+
this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
|
|
162
179
|
}
|
|
163
180
|
};
|
|
181
|
+
ResetViewWidget.defaultProps = {
|
|
182
|
+
...import_core2.Widget.defaultProps,
|
|
183
|
+
id: "reset-view",
|
|
184
|
+
placement: "top-left",
|
|
185
|
+
label: "Reset View",
|
|
186
|
+
initialViewState: void 0,
|
|
187
|
+
viewId: void 0
|
|
188
|
+
};
|
|
164
189
|
|
|
165
190
|
// dist/compass-widget.js
|
|
166
|
-
var
|
|
167
|
-
var
|
|
168
|
-
var
|
|
169
|
-
var CompassWidget = class {
|
|
170
|
-
constructor(props) {
|
|
171
|
-
|
|
191
|
+
var import_jsx_runtime6 = require("preact/jsx-runtime");
|
|
192
|
+
var import_core3 = require("@deck.gl/core");
|
|
193
|
+
var import_preact3 = require("preact");
|
|
194
|
+
var CompassWidget = class extends import_core3.Widget {
|
|
195
|
+
constructor(props = {}) {
|
|
196
|
+
super(props, CompassWidget.defaultProps);
|
|
197
|
+
this.className = "deck-widget-compass";
|
|
172
198
|
this.placement = "top-left";
|
|
173
199
|
this.viewId = null;
|
|
174
200
|
this.viewports = {};
|
|
175
|
-
this.
|
|
176
|
-
this.viewId = props.viewId ?? this.viewId;
|
|
177
|
-
this.placement = props.placement ?? this.placement;
|
|
178
|
-
this.props = {
|
|
179
|
-
...props,
|
|
180
|
-
transitionDuration: props.transitionDuration ?? 200,
|
|
181
|
-
label: props.label ?? "Reset Compass",
|
|
182
|
-
style: props.style ?? {}
|
|
183
|
-
};
|
|
201
|
+
this.setProps(this.props);
|
|
184
202
|
}
|
|
185
203
|
setProps(props) {
|
|
186
204
|
this.placement = props.placement ?? this.placement;
|
|
187
205
|
this.viewId = props.viewId ?? this.viewId;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
(0, import_core2._removeStyles)(el, oldProps.style);
|
|
199
|
-
(0, import_core2._applyStyles)(el, props.style);
|
|
206
|
+
super.setProps(props);
|
|
207
|
+
}
|
|
208
|
+
onRenderHTML(rootElement) {
|
|
209
|
+
var _a;
|
|
210
|
+
const viewId = this.viewId || ((_a = Object.values(this.viewports)[0]) == null ? void 0 : _a.id) || "default-view";
|
|
211
|
+
const widgetViewport = this.viewports[viewId];
|
|
212
|
+
const [rz, rx] = this.getRotation(widgetViewport);
|
|
213
|
+
const ui = (0, import_jsx_runtime6.jsx)("div", { className: "deck-widget-button", style: { perspective: 100 }, children: (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => {
|
|
214
|
+
for (const viewport of Object.values(this.viewports)) {
|
|
215
|
+
this.handleCompassReset(viewport);
|
|
200
216
|
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
this.update();
|
|
217
|
+
}, title: this.props.label, style: { transform: `rotateX(${rx}deg)` }, children: (0, import_jsx_runtime6.jsx)("svg", { fill: "none", width: "100%", height: "100%", viewBox: "0 0 26 26", children: (0, import_jsx_runtime6.jsxs)("g", { transform: `rotate(${rz},13,13)`, children: [(0, import_jsx_runtime6.jsx)("path", { d: "M10 13.0001L12.9999 5L15.9997 13.0001H10Z", fill: "var(--icon-compass-north-color, rgb(240, 92, 68))" }), (0, import_jsx_runtime6.jsx)("path", { d: "M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z", fill: "var(--icon-compass-south-color, rgb(204, 204, 204))" })] }) }) }) });
|
|
218
|
+
(0, import_preact3.render)(ui, rootElement);
|
|
204
219
|
}
|
|
205
220
|
onViewportChange(viewport) {
|
|
206
221
|
if (!viewport.equals(this.viewports[viewport.id])) {
|
|
207
222
|
this.viewports[viewport.id] = viewport;
|
|
208
|
-
this.
|
|
223
|
+
this.updateHTML();
|
|
209
224
|
}
|
|
210
225
|
}
|
|
211
|
-
onAdd({ deck }) {
|
|
212
|
-
const { style, className } = this.props;
|
|
213
|
-
const element = document.createElement("div");
|
|
214
|
-
element.classList.add("deck-widget", "deck-widget-compass");
|
|
215
|
-
if (className)
|
|
216
|
-
element.classList.add(className);
|
|
217
|
-
(0, import_core2._applyStyles)(element, style);
|
|
218
|
-
this.deck = deck;
|
|
219
|
-
this.element = element;
|
|
220
|
-
this.update();
|
|
221
|
-
return element;
|
|
222
|
-
}
|
|
223
226
|
getRotation(viewport) {
|
|
224
|
-
if (viewport instanceof
|
|
227
|
+
if (viewport instanceof import_core3.WebMercatorViewport) {
|
|
225
228
|
return [-viewport.bearing, viewport.pitch];
|
|
226
|
-
} else if (viewport instanceof
|
|
229
|
+
} else if (viewport instanceof import_core3._GlobeViewport) {
|
|
227
230
|
return [0, Math.max(-80, Math.min(80, viewport.latitude))];
|
|
228
231
|
}
|
|
229
232
|
return [0, 0];
|
|
230
233
|
}
|
|
231
|
-
update() {
|
|
232
|
-
var _a;
|
|
233
|
-
const viewId = this.viewId || ((_a = Object.values(this.viewports)[0]) == null ? void 0 : _a.id) || "default-view";
|
|
234
|
-
const viewport = this.viewports[viewId];
|
|
235
|
-
const [rz, rx] = this.getRotation(viewport);
|
|
236
|
-
const element = this.element;
|
|
237
|
-
if (!element) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
const ui = (0, import_jsx_runtime3.jsx)("div", { className: "deck-widget-button", style: { perspective: 100 }, children: (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: () => {
|
|
241
|
-
for (const viewport2 of Object.values(this.viewports)) {
|
|
242
|
-
this.handleCompassReset(viewport2);
|
|
243
|
-
}
|
|
244
|
-
}, title: this.props.label, style: { transform: `rotateX(${rx}deg)` }, children: (0, import_jsx_runtime3.jsx)("svg", { fill: "none", width: "100%", height: "100%", viewBox: "0 0 26 26", children: (0, import_jsx_runtime3.jsxs)("g", { transform: `rotate(${rz},13,13)`, children: [(0, import_jsx_runtime3.jsx)("path", { d: "M10 13.0001L12.9999 5L15.9997 13.0001H10Z", fill: "var(--icon-compass-north-color, #F05C44)" }), (0, import_jsx_runtime3.jsx)("path", { d: "M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z", fill: "var(--icon-compass-south-color, #C2C2CC)" })] }) }) }) });
|
|
245
|
-
(0, import_preact2.render)(ui, element);
|
|
246
|
-
}
|
|
247
|
-
onRemove() {
|
|
248
|
-
this.deck = void 0;
|
|
249
|
-
this.element = void 0;
|
|
250
|
-
}
|
|
251
234
|
handleCompassReset(viewport) {
|
|
252
235
|
const viewId = this.viewId || viewport.id || "default-view";
|
|
253
|
-
if (viewport instanceof
|
|
236
|
+
if (viewport instanceof import_core3.WebMercatorViewport) {
|
|
254
237
|
const nextViewState = {
|
|
255
238
|
...viewport,
|
|
256
239
|
bearing: 0,
|
|
257
240
|
...this.getRotation(viewport)[0] === 0 ? { pitch: 0 } : {},
|
|
258
241
|
transitionDuration: this.props.transitionDuration,
|
|
259
|
-
transitionInterpolator: new
|
|
242
|
+
transitionInterpolator: new import_core3.FlyToInterpolator()
|
|
260
243
|
};
|
|
261
244
|
this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
|
|
262
245
|
}
|
|
263
246
|
}
|
|
264
247
|
};
|
|
248
|
+
CompassWidget.defaultProps = {
|
|
249
|
+
...import_core3.Widget.defaultProps,
|
|
250
|
+
id: "compass",
|
|
251
|
+
placement: "top-left",
|
|
252
|
+
viewId: null,
|
|
253
|
+
label: "Reset Compass",
|
|
254
|
+
transitionDuration: 200
|
|
255
|
+
};
|
|
265
256
|
|
|
266
|
-
// dist/
|
|
267
|
-
var
|
|
268
|
-
var
|
|
269
|
-
var
|
|
270
|
-
var
|
|
257
|
+
// dist/gimbal-widget.js
|
|
258
|
+
var import_jsx_runtime7 = require("preact/jsx-runtime");
|
|
259
|
+
var import_core4 = require("@deck.gl/core");
|
|
260
|
+
var import_preact4 = require("preact");
|
|
261
|
+
var GimbalWidget = class extends import_core4.Widget {
|
|
271
262
|
constructor(props = {}) {
|
|
272
|
-
|
|
263
|
+
super(props, GimbalWidget.defaultProps);
|
|
264
|
+
this.className = "deck-widget-gimbal";
|
|
273
265
|
this.placement = "top-left";
|
|
274
266
|
this.viewId = null;
|
|
275
|
-
this.
|
|
276
|
-
|
|
277
|
-
|
|
267
|
+
this.setProps(this.props);
|
|
268
|
+
}
|
|
269
|
+
setProps(props) {
|
|
278
270
|
this.placement = props.placement ?? this.placement;
|
|
279
|
-
this.
|
|
280
|
-
|
|
281
|
-
...props
|
|
282
|
-
};
|
|
271
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
272
|
+
super.setProps(props);
|
|
283
273
|
}
|
|
284
|
-
|
|
285
|
-
const {
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
this.
|
|
294
|
-
|
|
274
|
+
onRenderHTML(rootElement) {
|
|
275
|
+
const { rotationOrbit, rotationX } = this.getNormalizedRotation();
|
|
276
|
+
const ui = (0, import_jsx_runtime7.jsx)("div", { className: "deck-widget-button", style: { perspective: 100, pointerEvents: "auto" }, children: (0, import_jsx_runtime7.jsxs)("button", { type: "button", onClick: () => {
|
|
277
|
+
this.resetOrbitView();
|
|
278
|
+
}, title: this.props.label, style: { position: "relative", width: 26, height: 26 }, children: [(0, import_jsx_runtime7.jsx)("svg", { className: "gimbal-outer-ring", width: "100%", height: "100%", viewBox: "0 0 26 26", style: {
|
|
279
|
+
position: "absolute",
|
|
280
|
+
top: 0,
|
|
281
|
+
left: 0,
|
|
282
|
+
transform: `rotateY(${rotationOrbit}deg)`
|
|
283
|
+
}, children: (0, import_jsx_runtime7.jsx)("circle", { cx: "13", cy: "13", r: "10", stroke: "var(--icon-gimbal-outer-color, rgb(68, 92, 204))", strokeWidth: this.props.strokeWidth, fill: "none" }) }), (0, import_jsx_runtime7.jsx)("svg", { className: "gimbal-inner-ring", width: "100%", height: "100%", viewBox: "0 0 26 26", style: {
|
|
284
|
+
position: "absolute",
|
|
285
|
+
top: 0,
|
|
286
|
+
left: 0,
|
|
287
|
+
transform: `rotateX(${rotationX}deg)`
|
|
288
|
+
}, children: (0, import_jsx_runtime7.jsx)("circle", { cx: "13", cy: "13", r: "7", stroke: "var(--icon-gimbal-inner-color, rgb(240, 92, 68))", strokeWidth: this.props.strokeWidth, fill: "none" }) })] }) });
|
|
289
|
+
(0, import_preact4.render)(ui, rootElement);
|
|
295
290
|
}
|
|
296
|
-
|
|
297
|
-
this.
|
|
298
|
-
|
|
291
|
+
onViewportChange(viewport) {
|
|
292
|
+
this.updateHTML();
|
|
293
|
+
}
|
|
294
|
+
resetOrbitView() {
|
|
295
|
+
const viewId = this.getViewId();
|
|
296
|
+
const viewState = this.getViewState(viewId);
|
|
297
|
+
if ("rotationOrbit" in viewState || "rotationX" in viewState) {
|
|
298
|
+
const nextViewState = {
|
|
299
|
+
...viewState,
|
|
300
|
+
rotationOrbit: 0,
|
|
301
|
+
rotationX: 0,
|
|
302
|
+
transitionDuration: this.props.transitionDuration,
|
|
303
|
+
transitionInterpolator: new import_core4.LinearInterpolator({
|
|
304
|
+
transitionProps: ["rotationOrbit", "rotationX"]
|
|
305
|
+
})
|
|
306
|
+
};
|
|
307
|
+
this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
getNormalizedRotation() {
|
|
311
|
+
const viewState = this.getViewState(this.getViewId());
|
|
312
|
+
const [rz, rx] = this.getRotation(viewState);
|
|
313
|
+
const rotationOrbit = normalizeAndClampAngle(rz);
|
|
314
|
+
const rotationX = normalizeAndClampAngle(rx);
|
|
315
|
+
return { rotationOrbit, rotationX };
|
|
316
|
+
}
|
|
317
|
+
getRotation(viewState) {
|
|
318
|
+
if (viewState && ("rotationOrbit" in viewState || "rotationX" in viewState)) {
|
|
319
|
+
return [-(viewState.rotationOrbit || 0), viewState.rotationX || 0];
|
|
320
|
+
}
|
|
321
|
+
return [0, 0];
|
|
322
|
+
}
|
|
323
|
+
// Move to Widget/WidgetManager?
|
|
324
|
+
getViewId() {
|
|
325
|
+
const viewId = this.viewId || "OrbitView";
|
|
326
|
+
return viewId;
|
|
327
|
+
}
|
|
328
|
+
getViewState(viewId) {
|
|
329
|
+
const viewManager = this.getViewManager();
|
|
330
|
+
const viewState = viewId && viewManager.getViewState(viewId) || viewManager.viewState;
|
|
331
|
+
return viewState;
|
|
332
|
+
}
|
|
333
|
+
getViewManager() {
|
|
334
|
+
var _a;
|
|
335
|
+
const viewManager = (_a = this.deck) == null ? void 0 : _a.viewManager;
|
|
336
|
+
if (!viewManager) {
|
|
337
|
+
throw new Error("wigdet must be added to a deck instance");
|
|
338
|
+
}
|
|
339
|
+
return viewManager;
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
GimbalWidget.defaultProps = {
|
|
343
|
+
...import_core4.Widget.defaultProps,
|
|
344
|
+
id: "gimbal",
|
|
345
|
+
placement: "top-left",
|
|
346
|
+
viewId: void 0,
|
|
347
|
+
label: "Gimbal",
|
|
348
|
+
strokeWidth: 1.5,
|
|
349
|
+
transitionDuration: 200
|
|
350
|
+
};
|
|
351
|
+
function normalizeAndClampAngle(angle) {
|
|
352
|
+
let normalized = ((angle + 180) % 360 + 360) % 360 - 180;
|
|
353
|
+
const AVOID_ANGLE_DELTA = 10;
|
|
354
|
+
const distanceFrom90 = normalized - 90;
|
|
355
|
+
if (Math.abs(distanceFrom90) < AVOID_ANGLE_DELTA) {
|
|
356
|
+
if (distanceFrom90 < AVOID_ANGLE_DELTA) {
|
|
357
|
+
normalized = 90 + AVOID_ANGLE_DELTA;
|
|
358
|
+
} else if (distanceFrom90 > -AVOID_ANGLE_DELTA) {
|
|
359
|
+
normalized = 90 - AVOID_ANGLE_DELTA;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return normalized;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// dist/scale-widget.js
|
|
366
|
+
var import_jsx_runtime8 = require("preact/jsx-runtime");
|
|
367
|
+
var import_preact5 = require("preact");
|
|
368
|
+
var import_core5 = require("@deck.gl/core");
|
|
369
|
+
var ScaleWidget = class extends import_core5.Widget {
|
|
370
|
+
constructor(props = {}) {
|
|
371
|
+
super(props, ScaleWidget.defaultProps);
|
|
372
|
+
this.className = "deck-widget-scale";
|
|
373
|
+
this.placement = "bottom-left";
|
|
374
|
+
this.scaleWidth = 10;
|
|
375
|
+
this.scaleValue = 0;
|
|
376
|
+
this.scaleText = "";
|
|
377
|
+
this.placement = props.placement ?? this.placement;
|
|
299
378
|
}
|
|
300
379
|
setProps(props) {
|
|
301
380
|
this.placement = props.placement ?? this.placement;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (props.className)
|
|
310
|
-
el.classList.add(props.className);
|
|
311
|
-
}
|
|
312
|
-
if (!(0, import_core3._deepEqual)(oldProps.style, props.style, 1)) {
|
|
313
|
-
(0, import_core3._removeStyles)(el, oldProps.style);
|
|
314
|
-
(0, import_core3._applyStyles)(el, props.style);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
Object.assign(this.props, props);
|
|
318
|
-
this.update();
|
|
381
|
+
super.setProps(props);
|
|
382
|
+
}
|
|
383
|
+
onRenderHTML(rootElement) {
|
|
384
|
+
const lineOffsetX = 50;
|
|
385
|
+
const svgWidth = lineOffsetX + this.scaleWidth;
|
|
386
|
+
const tickHeight = 10;
|
|
387
|
+
(0, import_preact5.render)((0, import_jsx_runtime8.jsxs)("svg", { className: "deck-widget-scale", width: svgWidth, height: 30, style: { overflow: "visible", background: "transparent" }, onClick: this.handleClick.bind(this), children: [(0, import_jsx_runtime8.jsx)("text", { x: lineOffsetX + 5, y: "10", textAnchor: "end", alignmentBaseline: "middle", style: { fontSize: "16px", fill: "black", fontWeight: "bold", fontFamily: "sans-serif" }, children: this.scaleText }), (0, import_jsx_runtime8.jsx)("line", { x1: lineOffsetX, y1: "15", x2: lineOffsetX + this.scaleWidth, y2: "15", stroke: "black", strokeWidth: "6" }), (0, import_jsx_runtime8.jsx)("line", { x1: lineOffsetX, y1: "15", x2: lineOffsetX, y2: 15 - tickHeight, stroke: "black", strokeWidth: "6" }), (0, import_jsx_runtime8.jsx)("line", { x1: lineOffsetX + this.scaleWidth, y1: "15", x2: lineOffsetX + this.scaleWidth, y2: 15 - tickHeight, stroke: "black", strokeWidth: "6" })] }), rootElement);
|
|
319
388
|
}
|
|
320
389
|
onViewportChange(viewport) {
|
|
321
|
-
|
|
390
|
+
if (!("latitude" in viewport))
|
|
391
|
+
return;
|
|
392
|
+
const { latitude, zoom } = viewport;
|
|
393
|
+
const metersPerPixel = getMetersPerPixel(latitude, zoom);
|
|
394
|
+
const { candidate, candidatePixels } = computeScaleCandidate(metersPerPixel);
|
|
395
|
+
this.scaleValue = candidate;
|
|
396
|
+
this.scaleWidth = candidatePixels;
|
|
397
|
+
if (candidate >= 1e3) {
|
|
398
|
+
this.scaleText = `${(candidate / 1e3).toFixed(1)} km`;
|
|
399
|
+
} else {
|
|
400
|
+
this.scaleText = `${candidate} m`;
|
|
401
|
+
}
|
|
402
|
+
this.updateHTML();
|
|
322
403
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
404
|
+
handleClick() {
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
ScaleWidget.defaultProps = {
|
|
408
|
+
...import_core5.Widget.defaultProps,
|
|
409
|
+
id: "scale",
|
|
410
|
+
placement: "bottom-left",
|
|
411
|
+
label: "Scale",
|
|
412
|
+
onCapture: void 0
|
|
413
|
+
};
|
|
414
|
+
function getMetersPerPixel(latitude, zoom) {
|
|
415
|
+
const earthCircumference = 40075016686e-3;
|
|
416
|
+
return earthCircumference * Math.cos(latitude * Math.PI / 180) / Math.pow(2, zoom + 8);
|
|
417
|
+
}
|
|
418
|
+
function computeScaleCandidate(metersPerPixel) {
|
|
419
|
+
const minPixels = 100;
|
|
420
|
+
const maxPixels = 200;
|
|
421
|
+
const targetPixels = (minPixels + maxPixels) / 2;
|
|
422
|
+
const targetDistance = targetPixels * metersPerPixel;
|
|
423
|
+
const exponent = Math.floor(Math.log10(targetDistance));
|
|
424
|
+
const base = Math.pow(10, exponent);
|
|
425
|
+
const multipliers = [1, 2, 5];
|
|
426
|
+
let candidate = multipliers[0] * base;
|
|
427
|
+
let candidatePixels = candidate / metersPerPixel;
|
|
428
|
+
for (let i = 0; i < multipliers.length; i++) {
|
|
429
|
+
const currentCandidate = multipliers[i] * base;
|
|
430
|
+
const currentPixels = currentCandidate / metersPerPixel;
|
|
431
|
+
if (currentPixels >= minPixels && currentPixels <= maxPixels) {
|
|
432
|
+
candidate = currentCandidate;
|
|
433
|
+
candidatePixels = currentPixels;
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
if (currentPixels > maxPixels) {
|
|
437
|
+
candidate = i > 0 ? multipliers[i - 1] * base : currentCandidate;
|
|
438
|
+
candidatePixels = candidate / metersPerPixel;
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
if (i === multipliers.length - 1 && currentPixels < minPixels) {
|
|
442
|
+
candidate = multipliers[0] * base * 10;
|
|
443
|
+
candidatePixels = candidate / metersPerPixel;
|
|
332
444
|
}
|
|
333
|
-
this.setViewState(viewId, nextViewState);
|
|
334
445
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
446
|
+
return { candidate, candidatePixels };
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// dist/geocoder-widget.js
|
|
450
|
+
var import_jsx_runtime10 = require("preact/jsx-runtime");
|
|
451
|
+
var import_core6 = require("@deck.gl/core");
|
|
452
|
+
var import_core7 = require("@deck.gl/core");
|
|
453
|
+
var import_preact6 = require("preact");
|
|
454
|
+
|
|
455
|
+
// dist/lib/components/dropdown-menu.js
|
|
456
|
+
var import_jsx_runtime9 = require("preact/jsx-runtime");
|
|
457
|
+
var import_hooks = require("preact/hooks");
|
|
458
|
+
var DropdownMenu = (props) => {
|
|
459
|
+
const [isOpen, setIsOpen] = (0, import_hooks.useState)(false);
|
|
460
|
+
const dropdownRef = (0, import_hooks.useRef)(null);
|
|
461
|
+
const toggleDropdown = () => setIsOpen(!isOpen);
|
|
462
|
+
const handleClickOutside = (event) => {
|
|
463
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
464
|
+
setIsOpen(false);
|
|
338
465
|
}
|
|
466
|
+
};
|
|
467
|
+
(0, import_hooks.useEffect)(() => {
|
|
468
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
469
|
+
return () => {
|
|
470
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
471
|
+
};
|
|
472
|
+
}, []);
|
|
473
|
+
const handleSelect = (value) => {
|
|
474
|
+
props.onSelect(value);
|
|
475
|
+
setIsOpen(false);
|
|
476
|
+
};
|
|
477
|
+
return (0, import_jsx_runtime9.jsxs)("div", { className: "dropdown-container", ref: dropdownRef, style: {
|
|
478
|
+
position: "relative",
|
|
479
|
+
display: "inline-block",
|
|
480
|
+
...props.style
|
|
481
|
+
}, children: [(0, import_jsx_runtime9.jsx)("button", { onClick: toggleDropdown, style: {
|
|
482
|
+
width: "30px",
|
|
483
|
+
height: "30px",
|
|
484
|
+
display: "flex",
|
|
485
|
+
alignItems: "center",
|
|
486
|
+
justifyContent: "center",
|
|
487
|
+
border: "1px solid #ccc",
|
|
488
|
+
borderRadius: "4px",
|
|
489
|
+
background: "#fff",
|
|
490
|
+
cursor: "pointer",
|
|
491
|
+
padding: 0
|
|
492
|
+
}, children: "\u25BC" }), isOpen && (0, import_jsx_runtime9.jsx)("ul", { style: {
|
|
493
|
+
position: "absolute",
|
|
494
|
+
top: "100%",
|
|
495
|
+
right: "100%",
|
|
496
|
+
background: "#fff",
|
|
497
|
+
border: "1px solid #ccc",
|
|
498
|
+
borderRadius: "4px",
|
|
499
|
+
listStyle: "none",
|
|
500
|
+
padding: "4px 0",
|
|
501
|
+
margin: 0,
|
|
502
|
+
zIndex: 1e3,
|
|
503
|
+
minWidth: "200px"
|
|
504
|
+
}, children: props.menuItems.map((item) => (0, import_jsx_runtime9.jsx)("li", { onClick: () => handleSelect(item), style: {
|
|
505
|
+
padding: "4px 8px",
|
|
506
|
+
cursor: "pointer",
|
|
507
|
+
whiteSpace: "nowrap"
|
|
508
|
+
}, children: item }, item)) })] });
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
// dist/lib/geocode/geocoder-history.js
|
|
512
|
+
var CURRENT_LOCATION = "current";
|
|
513
|
+
var LOCAL_STORAGE_KEY = "deck-geocoder-history";
|
|
514
|
+
var GeocoderHistory = class {
|
|
515
|
+
constructor(props) {
|
|
516
|
+
this.addressText = "";
|
|
517
|
+
this.errorText = "";
|
|
518
|
+
this.addressHistory = [];
|
|
519
|
+
this.props = { maxEntries: 5, ...props };
|
|
520
|
+
this.addressHistory = this.loadPreviousAddresses();
|
|
339
521
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
522
|
+
/** PErform geocoding */
|
|
523
|
+
async geocode(geocoder, address, apiKey) {
|
|
524
|
+
this.errorText = "";
|
|
525
|
+
this.addressText = address;
|
|
526
|
+
try {
|
|
527
|
+
const coordinates = await geocoder.geocode(address, apiKey);
|
|
528
|
+
if (coordinates) {
|
|
529
|
+
this.storeAddress(this.addressText);
|
|
530
|
+
return coordinates;
|
|
531
|
+
}
|
|
532
|
+
this.errorText = "Invalid address";
|
|
533
|
+
} catch (error) {
|
|
534
|
+
this.errorText = `${error.message}`;
|
|
343
535
|
}
|
|
536
|
+
return null;
|
|
344
537
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
538
|
+
loadPreviousAddresses() {
|
|
539
|
+
try {
|
|
540
|
+
const stored = window.localStorage.getItem(LOCAL_STORAGE_KEY);
|
|
541
|
+
const list = stored && JSON.parse(stored);
|
|
542
|
+
const addresses = Array.isArray(list) ? list.filter((v) => typeof v === "string") : [];
|
|
543
|
+
return addresses;
|
|
544
|
+
} catch {
|
|
545
|
+
}
|
|
546
|
+
return [];
|
|
350
547
|
}
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
if (!
|
|
548
|
+
storeAddress(address) {
|
|
549
|
+
const cleaned = address.trim();
|
|
550
|
+
if (!cleaned || cleaned === CURRENT_LOCATION) {
|
|
354
551
|
return;
|
|
355
552
|
}
|
|
356
|
-
const
|
|
357
|
-
(0,
|
|
553
|
+
const deduped = [cleaned, ...this.addressHistory.filter((a) => a !== cleaned)];
|
|
554
|
+
this.addressHistory = deduped.slice(0, this.props.maxEntries);
|
|
555
|
+
try {
|
|
556
|
+
window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.addressHistory));
|
|
557
|
+
} catch {
|
|
558
|
+
}
|
|
358
559
|
}
|
|
359
560
|
};
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
561
|
+
|
|
562
|
+
// dist/lib/geocode/geocoders.js
|
|
563
|
+
var GOOGLE_URL = "https://maps.googleapis.com/maps/api/geocode/json";
|
|
564
|
+
var MAPBOX_URL = "https://api.mapbox.com/geocoding/v5/mapbox.places";
|
|
565
|
+
var OPENCAGE_API_URL = "https://api.opencagedata.com/geocode/v1/json";
|
|
566
|
+
var GoogleGeocoder = {
|
|
567
|
+
name: "google",
|
|
568
|
+
requiresApiKey: true,
|
|
569
|
+
async geocode(address, apiKey) {
|
|
570
|
+
const encodedAddress = encodeURIComponent(address);
|
|
571
|
+
const json = await fetchJson(`${GOOGLE_URL}?address=${encodedAddress}&key=${apiKey}`);
|
|
572
|
+
switch (json.status) {
|
|
573
|
+
case "OK":
|
|
574
|
+
const loc = json.results.length > 0 && json.results[0].geometry.location;
|
|
575
|
+
return loc ? { longitude: loc.lng, latitude: loc.lat } : null;
|
|
576
|
+
default:
|
|
577
|
+
throw new Error(`Google Geocoder failed: ${json.status}`);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
var MapboxGeocoder = {
|
|
582
|
+
name: "google",
|
|
583
|
+
requiresApiKey: true,
|
|
584
|
+
async geocode(address, apiKey) {
|
|
585
|
+
const encodedAddress = encodeURIComponent(address);
|
|
586
|
+
const json = await fetchJson(`${MAPBOX_URL}/${encodedAddress}.json?access_token=${apiKey}`);
|
|
587
|
+
if (Array.isArray(json.features) && json.features.length > 0) {
|
|
588
|
+
const center = json.features[0].center;
|
|
589
|
+
if (Array.isArray(center) && center.length >= 2) {
|
|
590
|
+
return { longitude: center[0], latitude: center[1] };
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return null;
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
var OpenCageGeocoder = {
|
|
597
|
+
name: "opencage",
|
|
598
|
+
requiresApiKey: true,
|
|
599
|
+
async geocode(address, key) {
|
|
600
|
+
const encodedAddress = encodeURIComponent(address);
|
|
601
|
+
const data = await fetchJson(`${OPENCAGE_API_URL}?q=${encodedAddress}&key=${key}`);
|
|
602
|
+
if (Array.isArray(data.results) && data.results.length > 0) {
|
|
603
|
+
const geometry = data.results[0].geometry;
|
|
604
|
+
return { longitude: geometry.lng, latitude: geometry.lat };
|
|
605
|
+
}
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
var CurrentLocationGeocoder = {
|
|
610
|
+
name: "current",
|
|
611
|
+
requiresApiKey: false,
|
|
612
|
+
/** Attempt to call browsers geolocation API */
|
|
613
|
+
async geocode() {
|
|
614
|
+
if (!navigator.geolocation) {
|
|
615
|
+
throw new Error("Geolocation not supported");
|
|
616
|
+
}
|
|
617
|
+
return new Promise((resolve, reject) => {
|
|
618
|
+
navigator.geolocation.getCurrentPosition(
|
|
619
|
+
/** @see https://developer.mozilla.org/docs/Web/API/GeolocationPosition */
|
|
620
|
+
(position) => {
|
|
621
|
+
const { longitude, latitude } = position.coords;
|
|
622
|
+
resolve({ longitude, latitude });
|
|
623
|
+
},
|
|
624
|
+
/** @see https://developer.mozilla.org/docs/Web/API/GeolocationPositionError */
|
|
625
|
+
(error) => reject(new Error(error.message))
|
|
626
|
+
);
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
async function fetchJson(url) {
|
|
631
|
+
let response;
|
|
632
|
+
try {
|
|
633
|
+
response = await fetch(url);
|
|
634
|
+
} catch (error) {
|
|
635
|
+
throw new Error(`CORS error? ${error}. ${url}: `);
|
|
636
|
+
}
|
|
637
|
+
if (!response.ok) {
|
|
638
|
+
throw new Error(`${response.statusText}. ${url}: `);
|
|
639
|
+
}
|
|
640
|
+
const data = await response.json();
|
|
641
|
+
if (!data) {
|
|
642
|
+
throw new Error(`No data returned. ${url}`);
|
|
643
|
+
}
|
|
644
|
+
return data;
|
|
645
|
+
}
|
|
646
|
+
var CoordinatesGeocoder = {
|
|
647
|
+
name: "coordinates",
|
|
648
|
+
requiresApiKey: false,
|
|
649
|
+
placeholderLocation: `-122.45, 37.8 or 37\xB048'N, 122\xB027'W`,
|
|
650
|
+
async geocode(address) {
|
|
651
|
+
return parseCoordinates(address) || null;
|
|
652
|
+
}
|
|
370
653
|
};
|
|
654
|
+
function parseCoordinates(input) {
|
|
655
|
+
input = input.trim();
|
|
656
|
+
const parts = input.split(/[,;]/).map((p) => p.trim());
|
|
657
|
+
if (parts.length < 2)
|
|
658
|
+
return null;
|
|
659
|
+
const first = parseCoordinatePart(parts[0]);
|
|
660
|
+
const second = parseCoordinatePart(parts[1]);
|
|
661
|
+
if (first === null || second === null)
|
|
662
|
+
return null;
|
|
663
|
+
if (Math.abs(first) > 90 && Math.abs(second) <= 90) {
|
|
664
|
+
return { longitude: first, latitude: second };
|
|
665
|
+
} else if (Math.abs(second) > 90 && Math.abs(first) <= 90) {
|
|
666
|
+
return { longitude: second, latitude: first };
|
|
667
|
+
}
|
|
668
|
+
return { latitude: first, longitude: second };
|
|
669
|
+
}
|
|
670
|
+
function parseCoordinatePart(s) {
|
|
671
|
+
s = s.trim();
|
|
672
|
+
if (s.includes("\xB0") || s.includes("'") || s.includes('"')) {
|
|
673
|
+
const value2 = dmsToDecimal(s);
|
|
674
|
+
return isNaN(value2) ? null : value2;
|
|
675
|
+
}
|
|
676
|
+
let sign = 1;
|
|
677
|
+
if (/[SW]/i.test(s))
|
|
678
|
+
sign = -1;
|
|
679
|
+
s = s.replace(/[NSEW]/gi, "");
|
|
680
|
+
const value = parseFloat(s);
|
|
681
|
+
return isNaN(value) ? null : sign * value;
|
|
682
|
+
}
|
|
683
|
+
function dmsToDecimal(s) {
|
|
684
|
+
const regex = /(\d+)[°d]\s*(\d+)?['′m]?\s*(\d+(?:\.\d+)?)?[\"″s]?\s*([NSEW])?/i;
|
|
685
|
+
const match = s.match(regex);
|
|
686
|
+
if (!match)
|
|
687
|
+
return NaN;
|
|
688
|
+
const degrees = parseFloat(match[1]) || 0;
|
|
689
|
+
const minutes = parseFloat(match[2]) || 0;
|
|
690
|
+
const seconds = parseFloat(match[3]) || 0;
|
|
691
|
+
const direction = match[4] || "";
|
|
692
|
+
let dec = degrees + minutes / 60 + seconds / 3600;
|
|
693
|
+
if (/[SW]/i.test(direction)) {
|
|
694
|
+
dec = -dec;
|
|
695
|
+
}
|
|
696
|
+
return dec;
|
|
697
|
+
}
|
|
371
698
|
|
|
372
|
-
// dist/
|
|
373
|
-
var
|
|
699
|
+
// dist/geocoder-widget.js
|
|
700
|
+
var CURRENT_LOCATION2 = "current";
|
|
701
|
+
var GeocoderWidget = class extends import_core6.Widget {
|
|
702
|
+
constructor(props = {}) {
|
|
703
|
+
super(props, GeocoderWidget.defaultProps);
|
|
704
|
+
this.className = "deck-widget-geocoder";
|
|
705
|
+
this.placement = "top-left";
|
|
706
|
+
this.geocodeHistory = new GeocoderHistory({});
|
|
707
|
+
this.addressText = "";
|
|
708
|
+
this.geocoder = CoordinatesGeocoder;
|
|
709
|
+
this.setInput = (text) => {
|
|
710
|
+
this.addressText = text;
|
|
711
|
+
};
|
|
712
|
+
this.handleKeyPress = (e) => {
|
|
713
|
+
if (e.key === "Enter") {
|
|
714
|
+
this.handleSubmit();
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
this.handleSelect = (address) => {
|
|
718
|
+
this.setInput(address);
|
|
719
|
+
this.handleSubmit();
|
|
720
|
+
};
|
|
721
|
+
this.handleSubmit = () => {
|
|
722
|
+
this.geocode(this.addressText);
|
|
723
|
+
};
|
|
724
|
+
this.geocode = async (address) => {
|
|
725
|
+
const useGeolocation = this.props._geolocation && address === CURRENT_LOCATION2;
|
|
726
|
+
const geocoder = useGeolocation ? CurrentLocationGeocoder : this.geocoder;
|
|
727
|
+
const coordinates = await this.geocodeHistory.geocode(geocoder, this.addressText, this.props.apiKey);
|
|
728
|
+
if (coordinates) {
|
|
729
|
+
this.setViewState(coordinates);
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
this.viewports = {};
|
|
733
|
+
this.placement = props.placement ?? this.placement;
|
|
734
|
+
this.setProps(props);
|
|
735
|
+
this.geocoder = getGeocoder(props);
|
|
736
|
+
}
|
|
737
|
+
setProps(props) {
|
|
738
|
+
super.setProps(props);
|
|
739
|
+
this.placement = props.placement ?? this.placement;
|
|
740
|
+
this.geocoder = getGeocoder(this.props);
|
|
741
|
+
if (this.geocoder.requiresApiKey && !this.props.apiKey) {
|
|
742
|
+
throw new Error(`API key is required for the ${this.geocoder.name} geocoder`);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
onRenderHTML(rootElement) {
|
|
746
|
+
const menuItems = this.props._geolocation ? [CURRENT_LOCATION2, ...this.geocodeHistory.addressHistory] : [...this.geocodeHistory.addressHistory];
|
|
747
|
+
(0, import_preact6.render)((0, import_jsx_runtime10.jsxs)("div", { className: "deck-widget-geocoder", style: {
|
|
748
|
+
pointerEvents: "auto",
|
|
749
|
+
display: "flex",
|
|
750
|
+
alignItems: "center",
|
|
751
|
+
flexWrap: "wrap"
|
|
752
|
+
// Allows wrapping on smaller screens
|
|
753
|
+
}, children: [(0, import_jsx_runtime10.jsx)("input", {
|
|
754
|
+
type: "text",
|
|
755
|
+
placeholder: this.geocoder.placeholderLocation ?? "Enter address or location",
|
|
756
|
+
value: this.geocodeHistory.addressText,
|
|
757
|
+
// @ts-expect-error event type
|
|
758
|
+
onInput: (e) => {
|
|
759
|
+
var _a;
|
|
760
|
+
return this.setInput(((_a = e.target) == null ? void 0 : _a.value) || "");
|
|
761
|
+
},
|
|
762
|
+
onKeyPress: this.handleKeyPress,
|
|
763
|
+
style: {
|
|
764
|
+
flex: "1 1 auto",
|
|
765
|
+
minWidth: "200px",
|
|
766
|
+
margin: 0,
|
|
767
|
+
padding: "8px",
|
|
768
|
+
boxSizing: "border-box"
|
|
769
|
+
}
|
|
770
|
+
}), (0, import_jsx_runtime10.jsx)(DropdownMenu, { menuItems, onSelect: this.handleSelect, style: {
|
|
771
|
+
margin: 2,
|
|
772
|
+
padding: "4px 2px",
|
|
773
|
+
boxSizing: "border-box"
|
|
774
|
+
} }), this.geocodeHistory.errorText && (0, import_jsx_runtime10.jsx)("div", { className: "error", children: this.geocodeHistory.errorText })] }), rootElement);
|
|
775
|
+
}
|
|
776
|
+
// TODO - MOVE TO WIDGETIMPL?
|
|
777
|
+
setViewState(viewState) {
|
|
778
|
+
const viewId = this.props.viewId || (viewState == null ? void 0 : viewState.id) || "default-view";
|
|
779
|
+
const viewport = this.viewports[viewId] || {};
|
|
780
|
+
const nextViewState = {
|
|
781
|
+
...viewport,
|
|
782
|
+
...viewState
|
|
783
|
+
};
|
|
784
|
+
if (this.props.transitionDuration > 0) {
|
|
785
|
+
nextViewState.transitionDuration = this.props.transitionDuration;
|
|
786
|
+
nextViewState.transitionInterpolator = "latitude" in nextViewState ? new import_core7.FlyToInterpolator() : new import_core7.LinearInterpolator();
|
|
787
|
+
}
|
|
788
|
+
this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
|
|
789
|
+
}
|
|
790
|
+
onViewportChange(viewport) {
|
|
791
|
+
this.viewports[viewport.id] = viewport;
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
GeocoderWidget.defaultProps = {
|
|
795
|
+
...import_core6.Widget.defaultProps,
|
|
796
|
+
id: "geolocate",
|
|
797
|
+
viewId: void 0,
|
|
798
|
+
placement: "top-left",
|
|
799
|
+
label: "Geolocate",
|
|
800
|
+
transitionDuration: 200,
|
|
801
|
+
geocoder: "coordinates",
|
|
802
|
+
customGeocoder: CoordinatesGeocoder,
|
|
803
|
+
apiKey: "",
|
|
804
|
+
_geolocation: false
|
|
805
|
+
};
|
|
806
|
+
function getGeocoder(props) {
|
|
807
|
+
switch (props.geocoder) {
|
|
808
|
+
case "google":
|
|
809
|
+
return GoogleGeocoder;
|
|
810
|
+
case "mapbox":
|
|
811
|
+
return MapboxGeocoder;
|
|
812
|
+
case "opencage":
|
|
813
|
+
return OpenCageGeocoder;
|
|
814
|
+
case "coordinates":
|
|
815
|
+
return CoordinatesGeocoder;
|
|
816
|
+
case "custom":
|
|
817
|
+
if (!props.customGeocoder) {
|
|
818
|
+
throw new Error("Custom geocoder is not defined");
|
|
819
|
+
}
|
|
820
|
+
return props.customGeocoder;
|
|
821
|
+
default:
|
|
822
|
+
throw new Error(`Unknown geocoder: ${props.geocoder}`);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
374
825
|
|
|
375
|
-
// dist/widget
|
|
376
|
-
var
|
|
377
|
-
var
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
826
|
+
// dist/fullscreen-widget.js
|
|
827
|
+
var import_jsx_runtime11 = require("preact/jsx-runtime");
|
|
828
|
+
var import_core8 = require("@deck.gl/core");
|
|
829
|
+
var import_preact7 = require("preact");
|
|
830
|
+
var FullscreenWidget = class extends import_core8.Widget {
|
|
831
|
+
constructor(props = {}) {
|
|
832
|
+
super(props, FullscreenWidget.defaultProps);
|
|
833
|
+
this.className = "deck-widget-fullscreen";
|
|
834
|
+
this.placement = "top-left";
|
|
835
|
+
this.fullscreen = false;
|
|
836
|
+
this.placement = props.placement ?? this.placement;
|
|
381
837
|
}
|
|
382
|
-
onAdd(
|
|
383
|
-
this.
|
|
384
|
-
const { style, className } = this.props;
|
|
385
|
-
const el = this._createRootElement({
|
|
386
|
-
widgetClassName: this.className,
|
|
387
|
-
className,
|
|
388
|
-
style
|
|
389
|
-
});
|
|
390
|
-
this.element = el;
|
|
391
|
-
this.onRenderHTML();
|
|
392
|
-
return this.element;
|
|
838
|
+
onAdd() {
|
|
839
|
+
document.addEventListener("fullscreenchange", this.onFullscreenChange.bind(this));
|
|
393
840
|
}
|
|
394
841
|
onRemove() {
|
|
395
|
-
this.
|
|
396
|
-
|
|
842
|
+
document.removeEventListener("fullscreenchange", this.onFullscreenChange.bind(this));
|
|
843
|
+
}
|
|
844
|
+
onRenderHTML(rootElement) {
|
|
845
|
+
(0, import_preact7.render)((0, import_jsx_runtime11.jsx)(IconButton, { onClick: this.handleClick.bind(this), label: this.fullscreen ? this.props.exitLabel : this.props.enterLabel, className: this.fullscreen ? "deck-widget-fullscreen-exit" : "deck-widget-fullscreen-enter" }), rootElement);
|
|
397
846
|
}
|
|
398
847
|
setProps(props) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
}
|
|
848
|
+
this.placement = props.placement ?? this.placement;
|
|
849
|
+
super.setProps(props);
|
|
850
|
+
}
|
|
851
|
+
getContainer() {
|
|
852
|
+
var _a, _b;
|
|
853
|
+
return this.props.container || ((_b = (_a = this.deck) == null ? void 0 : _a.getCanvas()) == null ? void 0 : _b.parentElement);
|
|
854
|
+
}
|
|
855
|
+
onFullscreenChange() {
|
|
856
|
+
const prevFullscreen = this.fullscreen;
|
|
857
|
+
const fullscreen = document.fullscreenElement === this.getContainer();
|
|
858
|
+
if (prevFullscreen !== fullscreen) {
|
|
859
|
+
this.fullscreen = !this.fullscreen;
|
|
412
860
|
}
|
|
413
|
-
|
|
414
|
-
this.onRenderHTML();
|
|
861
|
+
this.updateHTML();
|
|
415
862
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
863
|
+
async handleClick() {
|
|
864
|
+
if (this.fullscreen) {
|
|
865
|
+
await this.exitFullscreen();
|
|
866
|
+
} else {
|
|
867
|
+
await this.requestFullscreen();
|
|
868
|
+
}
|
|
869
|
+
this.updateHTML();
|
|
870
|
+
}
|
|
871
|
+
async requestFullscreen() {
|
|
872
|
+
const container = this.getContainer();
|
|
873
|
+
if (container == null ? void 0 : container.requestFullscreen) {
|
|
874
|
+
await container.requestFullscreen({ navigationUI: "hide" });
|
|
875
|
+
} else {
|
|
876
|
+
this.togglePseudoFullscreen();
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
async exitFullscreen() {
|
|
880
|
+
if (document.exitFullscreen) {
|
|
881
|
+
await document.exitFullscreen();
|
|
882
|
+
} else {
|
|
883
|
+
this.togglePseudoFullscreen();
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
togglePseudoFullscreen() {
|
|
887
|
+
var _a;
|
|
888
|
+
(_a = this.getContainer()) == null ? void 0 : _a.classList.toggle("deck-pseudo-fullscreen");
|
|
422
889
|
}
|
|
423
890
|
};
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
891
|
+
FullscreenWidget.defaultProps = {
|
|
892
|
+
...import_core8.Widget.defaultProps,
|
|
893
|
+
id: "fullscreen",
|
|
894
|
+
placement: "top-left",
|
|
895
|
+
enterLabel: "Enter Fullscreen",
|
|
896
|
+
exitLabel: "Exit Fullscreen",
|
|
897
|
+
container: void 0
|
|
428
898
|
};
|
|
429
899
|
|
|
430
900
|
// dist/screenshot-widget.js
|
|
431
|
-
var
|
|
432
|
-
var
|
|
901
|
+
var import_jsx_runtime12 = require("preact/jsx-runtime");
|
|
902
|
+
var import_preact8 = require("preact");
|
|
903
|
+
var import_core9 = require("@deck.gl/core");
|
|
904
|
+
var ScreenshotWidget = class extends import_core9.Widget {
|
|
433
905
|
constructor(props = {}) {
|
|
434
|
-
super(
|
|
906
|
+
super(props, ScreenshotWidget.defaultProps);
|
|
435
907
|
this.className = "deck-widget-screenshot";
|
|
436
908
|
this.placement = "top-left";
|
|
437
909
|
this.placement = props.placement ?? this.placement;
|
|
@@ -440,11 +912,8 @@ var ScreenshotWidget = class extends WidgetImpl {
|
|
|
440
912
|
this.placement = props.placement ?? this.placement;
|
|
441
913
|
super.setProps(props);
|
|
442
914
|
}
|
|
443
|
-
onRenderHTML() {
|
|
444
|
-
|
|
445
|
-
if (!element)
|
|
446
|
-
return;
|
|
447
|
-
(0, import_preact4.render)((0, import_jsx_runtime5.jsx)(IconButton, { className: "deck-widget-camera", label: this.props.label, onClick: this.handleClick.bind(this) }), element);
|
|
915
|
+
onRenderHTML(rootElement) {
|
|
916
|
+
(0, import_preact8.render)((0, import_jsx_runtime12.jsx)(IconButton, { className: "deck-widget-camera", label: this.props.label, onClick: this.handleClick.bind(this) }), rootElement);
|
|
448
917
|
}
|
|
449
918
|
handleClick() {
|
|
450
919
|
if (this.props.onCapture) {
|
|
@@ -471,7 +940,7 @@ var ScreenshotWidget = class extends WidgetImpl {
|
|
|
471
940
|
}
|
|
472
941
|
};
|
|
473
942
|
ScreenshotWidget.defaultProps = {
|
|
474
|
-
...
|
|
943
|
+
...import_core9.Widget.defaultProps,
|
|
475
944
|
id: "screenshot",
|
|
476
945
|
placement: "top-left",
|
|
477
946
|
label: "Screenshot",
|
|
@@ -480,53 +949,104 @@ ScreenshotWidget.defaultProps = {
|
|
|
480
949
|
onCapture: void 0
|
|
481
950
|
};
|
|
482
951
|
|
|
483
|
-
// dist/
|
|
484
|
-
var
|
|
485
|
-
var
|
|
486
|
-
var
|
|
952
|
+
// dist/loading-widget.js
|
|
953
|
+
var import_jsx_runtime13 = require("preact/jsx-runtime");
|
|
954
|
+
var import_preact9 = require("preact");
|
|
955
|
+
var import_core10 = require("@deck.gl/core");
|
|
956
|
+
var LoadingWidget = class extends import_core10.Widget {
|
|
487
957
|
constructor(props = {}) {
|
|
488
|
-
super(
|
|
489
|
-
this.className = "deck-widget-
|
|
958
|
+
super(props, LoadingWidget.defaultProps);
|
|
959
|
+
this.className = "deck-widget-loading";
|
|
490
960
|
this.placement = "top-left";
|
|
961
|
+
this.loading = true;
|
|
491
962
|
this.placement = props.placement ?? this.placement;
|
|
492
963
|
}
|
|
493
964
|
setProps(props) {
|
|
494
965
|
this.placement = props.placement ?? this.placement;
|
|
495
966
|
super.setProps(props);
|
|
496
967
|
}
|
|
497
|
-
onRenderHTML() {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
968
|
+
onRenderHTML(rootElement) {
|
|
969
|
+
(0, import_preact9.render)(
|
|
970
|
+
// TODO(ibgreen) - this should not be a button, but styling is so nested that it is easier to reuse this component.
|
|
971
|
+
this.loading && (0, import_jsx_runtime13.jsx)(IconButton, { className: "deck-widget-spinner-icon", label: this.props.label, onClick: this.handleClick.bind(this) }),
|
|
972
|
+
rootElement
|
|
973
|
+
);
|
|
502
974
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
975
|
+
onRedraw({ layers }) {
|
|
976
|
+
const loading = !layers.some((layer) => !layer.isLoaded);
|
|
977
|
+
if (loading !== this.loading) {
|
|
978
|
+
this.loading = loading;
|
|
979
|
+
this.updateHTML();
|
|
980
|
+
}
|
|
507
981
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const nextViewState = {
|
|
511
|
-
...viewState
|
|
512
|
-
// only works for geospatial?
|
|
513
|
-
// transitionDuration: this.props.transitionDuration,
|
|
514
|
-
// transitionInterpolator: new FlyToInterpolator()
|
|
515
|
-
};
|
|
516
|
-
this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
|
|
982
|
+
// TODO(ibgreen) - this should not be a button, see above.
|
|
983
|
+
handleClick() {
|
|
517
984
|
}
|
|
518
985
|
};
|
|
519
|
-
|
|
520
|
-
...
|
|
521
|
-
id: "
|
|
986
|
+
LoadingWidget.defaultProps = {
|
|
987
|
+
...import_core10.Widget.defaultProps,
|
|
988
|
+
id: "loading",
|
|
522
989
|
placement: "top-left",
|
|
523
|
-
label: "
|
|
524
|
-
|
|
525
|
-
|
|
990
|
+
label: "Loading layer data"
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
// dist/fps-widget.js
|
|
994
|
+
var import_core11 = require("@deck.gl/core");
|
|
995
|
+
var FpsWidget = class extends import_core11.Widget {
|
|
996
|
+
constructor(props = {}) {
|
|
997
|
+
super(props, FpsWidget.defaultProps);
|
|
998
|
+
this.className = "deck-widget-fps";
|
|
999
|
+
this.placement = "top-left";
|
|
1000
|
+
this._lastFps = -1;
|
|
1001
|
+
this.placement = props.placement ?? this.placement;
|
|
1002
|
+
}
|
|
1003
|
+
setProps(props) {
|
|
1004
|
+
if (props.placement) {
|
|
1005
|
+
this.placement = props.placement;
|
|
1006
|
+
}
|
|
1007
|
+
super.setProps(props);
|
|
1008
|
+
}
|
|
1009
|
+
onRenderHTML(rootElement) {
|
|
1010
|
+
const fps = this._getFps();
|
|
1011
|
+
rootElement.innerText = `FPS:
|
|
1012
|
+
${fps}`;
|
|
1013
|
+
rootElement.style.backgroundColor = "white";
|
|
1014
|
+
rootElement.style.fontFamily = "monospace";
|
|
1015
|
+
rootElement.style.fontSize = "8px";
|
|
1016
|
+
rootElement.style.fontWeight = "700";
|
|
1017
|
+
}
|
|
1018
|
+
onRedraw({}) {
|
|
1019
|
+
const fps = this._getFps();
|
|
1020
|
+
if (fps !== this._lastFps) {
|
|
1021
|
+
this._lastFps = fps;
|
|
1022
|
+
this.updateHTML();
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
onAdd({}) {
|
|
1026
|
+
this._lastFps = this._getFps();
|
|
1027
|
+
this.updateHTML();
|
|
1028
|
+
}
|
|
1029
|
+
_getFps() {
|
|
1030
|
+
return Math.round(this.deck.metrics.fps ?? 0);
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
FpsWidget.defaultProps = {
|
|
1034
|
+
...import_core11.Widget.defaultProps,
|
|
1035
|
+
id: "fps",
|
|
1036
|
+
placement: "top-left"
|
|
526
1037
|
};
|
|
527
1038
|
|
|
1039
|
+
// dist/theme-widget.js
|
|
1040
|
+
var import_jsx_runtime14 = require("preact/jsx-runtime");
|
|
1041
|
+
var import_core12 = require("@deck.gl/core");
|
|
1042
|
+
var import_core13 = require("@deck.gl/core");
|
|
1043
|
+
var import_preact10 = require("preact");
|
|
1044
|
+
|
|
528
1045
|
// dist/themes.js
|
|
529
1046
|
var LightTheme = {
|
|
1047
|
+
"--widget-margin": "12px",
|
|
1048
|
+
"--button-size": "28px",
|
|
1049
|
+
"--button-corner-radius": "8px",
|
|
530
1050
|
"--button-background": "#fff",
|
|
531
1051
|
"--button-stroke": "rgba(255, 255, 255, 0.3)",
|
|
532
1052
|
"--button-inner-stroke": "unset",
|
|
@@ -534,10 +1054,13 @@ var LightTheme = {
|
|
|
534
1054
|
"--button-backdrop-filter": "unset",
|
|
535
1055
|
"--button-icon-idle": "rgba(97, 97, 102, 1)",
|
|
536
1056
|
"--button-icon-hover": "rgba(24, 24, 26, 1)",
|
|
537
|
-
"--icon-compass-north-color": "
|
|
538
|
-
"--icon-compass-south-color": "
|
|
1057
|
+
"--icon-compass-north-color": "rgb(240, 92, 68)",
|
|
1058
|
+
"--icon-compass-south-color": "rgb(204, 204, 204)"
|
|
539
1059
|
};
|
|
540
1060
|
var DarkTheme = {
|
|
1061
|
+
"--widget-margin": "12px",
|
|
1062
|
+
"--button-size": "28px",
|
|
1063
|
+
"--button-corner-radius": "8px",
|
|
541
1064
|
"--button-background": "rgba(18, 18, 20, 1)",
|
|
542
1065
|
"--button-stroke": "rgba(18, 18, 20, 0.30)",
|
|
543
1066
|
"--button-inner-stroke": "unset",
|
|
@@ -545,10 +1068,13 @@ var DarkTheme = {
|
|
|
545
1068
|
"--button-backdrop-filter": "unset",
|
|
546
1069
|
"--button-icon-idle": "rgba(158, 157, 168, 1)",
|
|
547
1070
|
"--button-icon-hover": "rgba(215, 214, 229, 1)",
|
|
548
|
-
"--icon-compass-north-color": "
|
|
549
|
-
"--icon-compass-south-color": "
|
|
1071
|
+
"--icon-compass-north-color": "rgb(240, 92, 68)",
|
|
1072
|
+
"--icon-compass-south-color": "rgb(200, 199, 209)"
|
|
550
1073
|
};
|
|
551
1074
|
var LightGlassTheme = {
|
|
1075
|
+
"--widget-margin": "12px",
|
|
1076
|
+
"--button-size": "28px",
|
|
1077
|
+
"--button-corner-radius": "8px",
|
|
552
1078
|
"--button-background": "rgba(255, 255, 255, 0.6)",
|
|
553
1079
|
"--button-stroke": "rgba(255, 255, 255, 0.3)",
|
|
554
1080
|
"--button-inner-stroke": "1px solid rgba(255, 255, 255, 0.6)",
|
|
@@ -556,10 +1082,13 @@ var LightGlassTheme = {
|
|
|
556
1082
|
"--button-backdrop-filter": "blur(4px)",
|
|
557
1083
|
"--button-icon-idle": "rgba(97, 97, 102, 1)",
|
|
558
1084
|
"--button-icon-hover": "rgba(24, 24, 26, 1)",
|
|
559
|
-
"--icon-compass-north-color": "
|
|
560
|
-
"--icon-compass-south-color": "
|
|
1085
|
+
"--icon-compass-north-color": "rgb(240, 92, 68)",
|
|
1086
|
+
"--icon-compass-south-color": "rgb(204, 204, 204)"
|
|
561
1087
|
};
|
|
562
1088
|
var DarkGlassTheme = {
|
|
1089
|
+
"--widget-margin": "12px",
|
|
1090
|
+
"--button-size": "28px",
|
|
1091
|
+
"--button-corner-radius": "8px",
|
|
563
1092
|
"--button-background": "rgba(18, 18, 20, 0.75)",
|
|
564
1093
|
"--button-stroke": "rgba(18, 18, 20, 0.30)",
|
|
565
1094
|
"--button-inner-stroke": "1px solid rgba(18, 18, 20, 0.75)",
|
|
@@ -567,7 +1096,724 @@ var DarkGlassTheme = {
|
|
|
567
1096
|
"--button-backdrop-filter": "blur(4px)",
|
|
568
1097
|
"--button-icon-idle": "rgba(158, 157, 168, 1)",
|
|
569
1098
|
"--button-icon-hover": "rgba(215, 214, 229, 1)",
|
|
570
|
-
"--icon-compass-north-color": "
|
|
571
|
-
"--icon-compass-south-color": "
|
|
1099
|
+
"--icon-compass-north-color": "rgb(240, 92, 68)",
|
|
1100
|
+
"--icon-compass-south-color": "rgb(200, 199, 209)"
|
|
1101
|
+
};
|
|
1102
|
+
|
|
1103
|
+
// dist/theme-widget.js
|
|
1104
|
+
var ThemeWidget = class extends import_core13.Widget {
|
|
1105
|
+
constructor(props = {}) {
|
|
1106
|
+
super(props, ThemeWidget.defaultProps);
|
|
1107
|
+
this.className = "deck-widget-theme";
|
|
1108
|
+
this.placement = "top-left";
|
|
1109
|
+
this.themeMode = "dark";
|
|
1110
|
+
this.placement = props.placement ?? this.placement;
|
|
1111
|
+
this.themeMode = this._getInitialThemeMode();
|
|
1112
|
+
}
|
|
1113
|
+
// eslint-disable-next-line complexity
|
|
1114
|
+
setProps(props) {
|
|
1115
|
+
const { lightModeTheme, darkModeTheme } = this.props;
|
|
1116
|
+
this.placement = props.placement ?? this.placement;
|
|
1117
|
+
super.setProps(props);
|
|
1118
|
+
switch (this.themeMode) {
|
|
1119
|
+
case "light":
|
|
1120
|
+
if (props.lightModeTheme && !(0, import_core12._deepEqual)(props.lightModeTheme, lightModeTheme, 1)) {
|
|
1121
|
+
this._setThemeMode("light");
|
|
1122
|
+
}
|
|
1123
|
+
break;
|
|
1124
|
+
case "dark":
|
|
1125
|
+
if (props.darkModeTheme && !(0, import_core12._deepEqual)(props.darkModeTheme, darkModeTheme, 1)) {
|
|
1126
|
+
this._setThemeMode("dark");
|
|
1127
|
+
}
|
|
1128
|
+
break;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
onRenderHTML(rootElement) {
|
|
1132
|
+
const { lightModeLabel, darkModeLabel } = this.props;
|
|
1133
|
+
(0, import_preact10.render)((0, import_jsx_runtime14.jsx)(IconButton, { onClick: this._handleClick.bind(this), label: this.themeMode === "dark" ? darkModeLabel : lightModeLabel, className: this.themeMode === "dark" ? "deck-widget-moon" : "deck-widget-sun" }), rootElement);
|
|
1134
|
+
}
|
|
1135
|
+
onAdd() {
|
|
1136
|
+
this._setThemeMode(this.themeMode);
|
|
1137
|
+
}
|
|
1138
|
+
_handleClick() {
|
|
1139
|
+
const newThemeMode = this.themeMode === "dark" ? "light" : "dark";
|
|
1140
|
+
this._setThemeMode(newThemeMode);
|
|
1141
|
+
}
|
|
1142
|
+
_setThemeMode(themeMode) {
|
|
1143
|
+
var _a;
|
|
1144
|
+
this.themeMode = themeMode;
|
|
1145
|
+
const container = (_a = this.rootElement) == null ? void 0 : _a.closest(".deck-widget-container");
|
|
1146
|
+
if (container) {
|
|
1147
|
+
const themeStyle = themeMode === "dark" ? this.props.darkModeTheme : this.props.lightModeTheme;
|
|
1148
|
+
(0, import_core12._applyStyles)(container, themeStyle);
|
|
1149
|
+
const label = this.themeMode === "dark" ? this.props.darkModeLabel : this.props.lightModeLabel;
|
|
1150
|
+
import_core12.log.log(1, `Switched theme to ${label}`, themeStyle);
|
|
1151
|
+
this.updateHTML();
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
/** Read browser preference */
|
|
1155
|
+
_getInitialThemeMode() {
|
|
1156
|
+
const { initialThemeMode } = this.props;
|
|
1157
|
+
return initialThemeMode === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : initialThemeMode;
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
ThemeWidget.defaultProps = {
|
|
1161
|
+
...import_core13.Widget.defaultProps,
|
|
1162
|
+
id: "theme",
|
|
1163
|
+
placement: "top-left",
|
|
1164
|
+
lightModeLabel: "Light Mode",
|
|
1165
|
+
lightModeTheme: LightGlassTheme,
|
|
1166
|
+
darkModeLabel: "Dark Mode",
|
|
1167
|
+
darkModeTheme: DarkGlassTheme,
|
|
1168
|
+
initialThemeMode: "auto"
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
// dist/info-widget.js
|
|
1172
|
+
var import_jsx_runtime15 = require("preact/jsx-runtime");
|
|
1173
|
+
var import_core14 = require("@deck.gl/core");
|
|
1174
|
+
var import_preact11 = require("preact");
|
|
1175
|
+
var InfoWidget = class extends import_core14.Widget {
|
|
1176
|
+
constructor(props) {
|
|
1177
|
+
super(props, InfoWidget.defaultProps);
|
|
1178
|
+
this.className = "deck-widget-info";
|
|
1179
|
+
this.placement = "fill";
|
|
1180
|
+
this.viewId = null;
|
|
1181
|
+
props.position = props.position || [0, 0];
|
|
1182
|
+
props.text = props.text || "";
|
|
1183
|
+
props.visible = props.visible || false;
|
|
1184
|
+
props.minOffset = props.minOffset ?? 0;
|
|
1185
|
+
}
|
|
1186
|
+
setProps(props) {
|
|
1187
|
+
super.setProps(props);
|
|
1188
|
+
}
|
|
1189
|
+
onViewportChange(viewport) {
|
|
1190
|
+
this.viewport = viewport;
|
|
1191
|
+
this.updateHTML();
|
|
1192
|
+
}
|
|
1193
|
+
onHover(info) {
|
|
1194
|
+
if (this.props.mode === "hover" && this.props.getTooltip) {
|
|
1195
|
+
const tooltip = this.props.getTooltip(info, this);
|
|
1196
|
+
this.setProps({
|
|
1197
|
+
visible: tooltip !== null,
|
|
1198
|
+
...tooltip,
|
|
1199
|
+
style: { zIndex: 1, ...tooltip == null ? void 0 : tooltip.style }
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
onClick(info) {
|
|
1204
|
+
var _a, _b;
|
|
1205
|
+
if (this.props.mode === "click" && this.props.getTooltip) {
|
|
1206
|
+
const tooltip = this.props.getTooltip(info, this);
|
|
1207
|
+
this.setProps({
|
|
1208
|
+
visible: tooltip !== null,
|
|
1209
|
+
...tooltip
|
|
1210
|
+
});
|
|
1211
|
+
return tooltip !== null;
|
|
1212
|
+
}
|
|
1213
|
+
return ((_b = (_a = this.props).onClick) == null ? void 0 : _b.call(_a, this, info)) || false;
|
|
1214
|
+
}
|
|
1215
|
+
// TODO - Align with onCreateRootElement
|
|
1216
|
+
onAdd({ deck, viewId }) {
|
|
1217
|
+
const { className } = this.props;
|
|
1218
|
+
const element = document.createElement("div");
|
|
1219
|
+
element.classList.add("deck-widget", "deck-widget-info");
|
|
1220
|
+
if (className)
|
|
1221
|
+
element.classList.add(className);
|
|
1222
|
+
const style = { margin: "0px", top: "0px", left: "0px", position: "absolute" };
|
|
1223
|
+
Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));
|
|
1224
|
+
this.deck = deck;
|
|
1225
|
+
if (!viewId) {
|
|
1226
|
+
this.viewport = deck.getViewports()[0];
|
|
1227
|
+
} else {
|
|
1228
|
+
this.viewport = deck.getViewports().find((viewport) => viewport.id === viewId);
|
|
1229
|
+
}
|
|
1230
|
+
this.rootElement = element;
|
|
1231
|
+
this.updateHTML();
|
|
1232
|
+
return element;
|
|
1233
|
+
}
|
|
1234
|
+
onRenderHTML(rootElement) {
|
|
1235
|
+
if (!this.viewport) {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
const [longitude, latitude] = this.props.position;
|
|
1239
|
+
const [x, y] = this.viewport.project([longitude, latitude]);
|
|
1240
|
+
const minOffset = this.props.minOffset || 0;
|
|
1241
|
+
const gap = 10;
|
|
1242
|
+
const arrowHeight = 8;
|
|
1243
|
+
const arrowWidth = 16;
|
|
1244
|
+
const isAbove = y > this.viewport.height / 2;
|
|
1245
|
+
const background = this.props.style && this.props.style.background || "rgba(255,255,255,0.9)";
|
|
1246
|
+
const ui = this.props.visible ? (0, import_jsx_runtime15.jsxs)("div", { className: "popup-container", style: { position: "absolute", left: 0, top: 0 }, children: [(0, import_jsx_runtime15.jsx)("div", { className: "popup-content", style: {
|
|
1247
|
+
background,
|
|
1248
|
+
padding: "10px",
|
|
1249
|
+
position: "relative",
|
|
1250
|
+
// Include any additional styles
|
|
1251
|
+
...this.props.style
|
|
1252
|
+
}, children: this.props.text }), (0, import_jsx_runtime15.jsx)("div", { className: "popup-arrow", style: { position: "absolute", width: "0px", height: "0px" } })] }) : null;
|
|
1253
|
+
(0, import_preact11.render)(ui, rootElement);
|
|
1254
|
+
requestAnimationFrame(() => {
|
|
1255
|
+
if (!this.props.visible || !rootElement.firstChild || !this.viewport)
|
|
1256
|
+
return;
|
|
1257
|
+
const container = rootElement.firstChild;
|
|
1258
|
+
const contentEl = container.querySelector(".popup-content");
|
|
1259
|
+
const arrowEl = container.querySelector(".popup-arrow");
|
|
1260
|
+
if (!contentEl || !arrowEl)
|
|
1261
|
+
return;
|
|
1262
|
+
const contentRect = contentEl.getBoundingClientRect();
|
|
1263
|
+
const popupWidth = contentRect.width;
|
|
1264
|
+
const popupHeight = contentRect.height;
|
|
1265
|
+
let computedLeft = x - popupWidth / 2;
|
|
1266
|
+
let computedTop;
|
|
1267
|
+
if (isAbove) {
|
|
1268
|
+
computedTop = y - gap - arrowHeight - popupHeight;
|
|
1269
|
+
} else {
|
|
1270
|
+
computedTop = y + gap + arrowHeight;
|
|
1271
|
+
}
|
|
1272
|
+
if (computedLeft < minOffset) {
|
|
1273
|
+
computedLeft = minOffset;
|
|
1274
|
+
}
|
|
1275
|
+
if (computedLeft + popupWidth > this.viewport.width - minOffset) {
|
|
1276
|
+
computedLeft = this.viewport.width - minOffset - popupWidth;
|
|
1277
|
+
}
|
|
1278
|
+
if (isAbove) {
|
|
1279
|
+
if (computedTop < minOffset) {
|
|
1280
|
+
computedTop = minOffset;
|
|
1281
|
+
}
|
|
1282
|
+
} else if (computedTop + popupHeight + arrowHeight > this.viewport.height - minOffset) {
|
|
1283
|
+
computedTop = this.viewport.height - minOffset - popupHeight - arrowHeight;
|
|
1284
|
+
}
|
|
1285
|
+
container.style.left = `${computedLeft}px`;
|
|
1286
|
+
container.style.top = `${computedTop}px`;
|
|
1287
|
+
container.style.transform = "";
|
|
1288
|
+
let arrowLeft = x - computedLeft - arrowWidth / 2;
|
|
1289
|
+
arrowLeft = Math.max(arrowLeft, 0);
|
|
1290
|
+
arrowLeft = Math.min(arrowLeft, popupWidth - arrowWidth);
|
|
1291
|
+
if (isAbove) {
|
|
1292
|
+
arrowEl.style.left = `${arrowLeft}px`;
|
|
1293
|
+
arrowEl.style.bottom = `-${arrowHeight}px`;
|
|
1294
|
+
arrowEl.style.top = "";
|
|
1295
|
+
arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;
|
|
1296
|
+
arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;
|
|
1297
|
+
arrowEl.style.borderTop = `${arrowHeight}px solid ${background}`;
|
|
1298
|
+
arrowEl.style.borderBottom = "";
|
|
1299
|
+
} else {
|
|
1300
|
+
arrowEl.style.left = `${arrowLeft}px`;
|
|
1301
|
+
arrowEl.style.top = `-${arrowHeight}px`;
|
|
1302
|
+
arrowEl.style.bottom = "";
|
|
1303
|
+
arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;
|
|
1304
|
+
arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;
|
|
1305
|
+
arrowEl.style.borderBottom = `${arrowHeight}px solid ${background}`;
|
|
1306
|
+
arrowEl.style.borderTop = "";
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
InfoWidget.defaultProps = {
|
|
1312
|
+
...import_core14.Widget.defaultProps,
|
|
1313
|
+
position: [0, 0],
|
|
1314
|
+
text: "",
|
|
1315
|
+
visible: false,
|
|
1316
|
+
// Set default minOffset if not provided
|
|
1317
|
+
minOffset: 0,
|
|
1318
|
+
viewId: null,
|
|
1319
|
+
mode: "hover",
|
|
1320
|
+
getTooltip: void 0,
|
|
1321
|
+
onClick: void 0
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
// dist/stats-widget.js
|
|
1325
|
+
var import_jsx_runtime16 = require("preact/jsx-runtime");
|
|
1326
|
+
var import_core15 = require("@deck.gl/core");
|
|
1327
|
+
var import_core16 = require("@luma.gl/core");
|
|
1328
|
+
var import_preact12 = require("preact");
|
|
1329
|
+
var RIGHT_ARROW = "\u25B6";
|
|
1330
|
+
var DOWN_ARROW = "\u2B07";
|
|
1331
|
+
var DEFAULT_COUNT_FORMATTER = (stat) => `${stat.name}: ${stat.count}`;
|
|
1332
|
+
function formatTime(time) {
|
|
1333
|
+
return time < 1e3 ? `${time.toFixed(2)}ms` : `${(time / 1e3).toFixed(2)}s`;
|
|
1334
|
+
}
|
|
1335
|
+
function formatMemory(bytes) {
|
|
1336
|
+
const mb = bytes / 1e6;
|
|
1337
|
+
return `${mb.toFixed(1)} MB`;
|
|
1338
|
+
}
|
|
1339
|
+
var DEFAULT_FORMATTERS = {
|
|
1340
|
+
count: DEFAULT_COUNT_FORMATTER,
|
|
1341
|
+
averageTime: (stat) => `${stat.name}: ${formatTime(stat.getAverageTime())}`,
|
|
1342
|
+
totalTime: (stat) => `${stat.name}: ${formatTime(stat.time)}`,
|
|
1343
|
+
fps: (stat) => `${stat.name}: ${Math.round(stat.getHz())}fps`,
|
|
1344
|
+
memory: (stat) => `${stat.name}: ${formatMemory(stat.count)}`
|
|
1345
|
+
};
|
|
1346
|
+
var StatsWidget = class extends import_core15.Widget {
|
|
1347
|
+
constructor(props = {}) {
|
|
1348
|
+
super(props, StatsWidget.defaultProps);
|
|
1349
|
+
this.className = "deck-widget-stats";
|
|
1350
|
+
this.placement = "top-left";
|
|
1351
|
+
this._counter = 0;
|
|
1352
|
+
this.collapsed = true;
|
|
1353
|
+
this._toggleCollapsed = () => {
|
|
1354
|
+
this.collapsed = !this.collapsed;
|
|
1355
|
+
this.updateHTML();
|
|
1356
|
+
};
|
|
1357
|
+
this._formatters = { ...DEFAULT_FORMATTERS };
|
|
1358
|
+
this.setProps(props);
|
|
1359
|
+
this._resetOnUpdate = { ...this.props.resetOnUpdate };
|
|
1360
|
+
this._stats = this.props.stats;
|
|
1361
|
+
}
|
|
1362
|
+
setProps(props) {
|
|
1363
|
+
super.setProps(props);
|
|
1364
|
+
this._stats = this._getStats();
|
|
1365
|
+
if (props.formatters) {
|
|
1366
|
+
for (const name in props.formatters) {
|
|
1367
|
+
const f = props.formatters[name];
|
|
1368
|
+
this._formatters[name] = typeof f === "string" ? DEFAULT_FORMATTERS[f] || DEFAULT_COUNT_FORMATTER : f;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
if (props.resetOnUpdate) {
|
|
1372
|
+
this._resetOnUpdate = { ...props.resetOnUpdate };
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
onAdd() {
|
|
1376
|
+
this._stats = this._getStats();
|
|
1377
|
+
this.updateHTML();
|
|
1378
|
+
}
|
|
1379
|
+
onRenderHTML(rootElement) {
|
|
1380
|
+
const stats = this._stats;
|
|
1381
|
+
const collapsed = this.collapsed;
|
|
1382
|
+
const title = this.props.title || (stats == null ? void 0 : stats.id) || "Stats";
|
|
1383
|
+
const items = [];
|
|
1384
|
+
if (!collapsed && stats) {
|
|
1385
|
+
stats.forEach((stat) => {
|
|
1386
|
+
const lines = this._getLines(stat);
|
|
1387
|
+
if (this._resetOnUpdate && this._resetOnUpdate[stat.name]) {
|
|
1388
|
+
stat.reset();
|
|
1389
|
+
}
|
|
1390
|
+
lines.forEach((line, i) => {
|
|
1391
|
+
items.push((0, import_jsx_runtime16.jsx)("div", { style: { whiteSpace: "pre" }, children: line }, `${stat.name}-${i}`));
|
|
1392
|
+
});
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
(0, import_preact12.render)((0, import_jsx_runtime16.jsxs)("div", { className: "deck-widget-stats-container", style: { cursor: "default" }, children: [(0, import_jsx_runtime16.jsxs)("div", { className: "deck-widget-stats-header", style: { cursor: "pointer", pointerEvents: "auto" }, onClick: this._toggleCollapsed, children: [collapsed ? RIGHT_ARROW : DOWN_ARROW, " ", title] }), !collapsed && (0, import_jsx_runtime16.jsx)("div", { className: "deck-widget-stats-content deck-widget-common", children: items })] }), rootElement);
|
|
1396
|
+
}
|
|
1397
|
+
onRedraw() {
|
|
1398
|
+
const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);
|
|
1399
|
+
if (this._counter++ % framesPerUpdate === 0) {
|
|
1400
|
+
console.log("Redrawing stats widget");
|
|
1401
|
+
this.updateHTML();
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
_getStats() {
|
|
1405
|
+
var _a, _b;
|
|
1406
|
+
switch (this.props.type) {
|
|
1407
|
+
case "deck":
|
|
1408
|
+
return (_a = this.deck) == null ? void 0 : _a.stats;
|
|
1409
|
+
case "luma":
|
|
1410
|
+
return Array.from(import_core16.luma.stats.stats.values())[0];
|
|
1411
|
+
case "device":
|
|
1412
|
+
const device = (_b = this.deck) == null ? void 0 : _b.device;
|
|
1413
|
+
const stats = device == null ? void 0 : device.statsManager.stats.values();
|
|
1414
|
+
return stats ? Array.from(stats)[0] : void 0;
|
|
1415
|
+
case "custom":
|
|
1416
|
+
return this.props.stats;
|
|
1417
|
+
default:
|
|
1418
|
+
throw new Error(`Unknown stats type: ${this.props.type}`);
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
_getLines(stat) {
|
|
1422
|
+
const formatter = this._formatters[stat.name] || this._formatters[stat.type || ""] || DEFAULT_COUNT_FORMATTER;
|
|
1423
|
+
return formatter(stat).split("\n");
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1426
|
+
StatsWidget.defaultProps = {
|
|
1427
|
+
...import_core15.Widget.defaultProps,
|
|
1428
|
+
type: "deck",
|
|
1429
|
+
stats: void 0,
|
|
1430
|
+
title: "Stats",
|
|
1431
|
+
framesPerUpdate: 1,
|
|
1432
|
+
formatters: {},
|
|
1433
|
+
resetOnUpdate: {},
|
|
1434
|
+
id: "stats"
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
// dist/context-menu-widget.js
|
|
1438
|
+
var import_jsx_runtime18 = require("preact/jsx-runtime");
|
|
1439
|
+
var import_core17 = require("@deck.gl/core");
|
|
1440
|
+
var import_preact13 = require("preact");
|
|
1441
|
+
|
|
1442
|
+
// dist/lib/components/simple-menu.js
|
|
1443
|
+
var import_jsx_runtime17 = require("preact/jsx-runtime");
|
|
1444
|
+
var MENU_STYLE = {
|
|
1445
|
+
position: "absolute",
|
|
1446
|
+
top: "100%",
|
|
1447
|
+
left: 0,
|
|
1448
|
+
background: "white",
|
|
1449
|
+
border: "1px solid #ccc",
|
|
1450
|
+
borderRadius: "4px",
|
|
1451
|
+
marginTop: "4px",
|
|
1452
|
+
zIndex: 100
|
|
1453
|
+
};
|
|
1454
|
+
var MENU_ITEM_STYLE = {
|
|
1455
|
+
background: "white",
|
|
1456
|
+
border: "none",
|
|
1457
|
+
padding: "4px",
|
|
1458
|
+
cursor: "pointer",
|
|
1459
|
+
pointerEvents: "auto"
|
|
1460
|
+
};
|
|
1461
|
+
var SimpleMenu = (props) => {
|
|
1462
|
+
const { menuItems, onItemSelected, position, style } = props;
|
|
1463
|
+
const styleOverride = {
|
|
1464
|
+
...MENU_STYLE,
|
|
1465
|
+
...style,
|
|
1466
|
+
left: `${position.x}px`,
|
|
1467
|
+
top: `${position.y}px`
|
|
1468
|
+
};
|
|
1469
|
+
return (0, import_jsx_runtime17.jsx)("div", { style: styleOverride, children: menuItems.map(({ key, label }) => (0, import_jsx_runtime17.jsx)("button", { style: { ...MENU_ITEM_STYLE, display: "block" }, onClick: (_) => onItemSelected(key), children: label }, key)) });
|
|
1470
|
+
};
|
|
1471
|
+
|
|
1472
|
+
// dist/context-menu-widget.js
|
|
1473
|
+
var MOUSE_BUTTON_RIGHT = 2;
|
|
1474
|
+
var MOUSE_WHICH_RIGHT = 3;
|
|
1475
|
+
var ContextMenuWidget = class extends import_core17.Widget {
|
|
1476
|
+
constructor(props) {
|
|
1477
|
+
super(props, ContextMenuWidget.defaultProps);
|
|
1478
|
+
this.className = "deck-widget-context-menu";
|
|
1479
|
+
this.placement = "fill";
|
|
1480
|
+
this.pickInfo = null;
|
|
1481
|
+
this.pickInfo = null;
|
|
1482
|
+
this.setProps(props);
|
|
1483
|
+
}
|
|
1484
|
+
onAdd({ deck }) {
|
|
1485
|
+
var _a, _b;
|
|
1486
|
+
const element = document.createElement("div");
|
|
1487
|
+
element.classList.add("deck-widget", "deck-widget-context-menu");
|
|
1488
|
+
const style = {
|
|
1489
|
+
margin: "0px",
|
|
1490
|
+
top: "0px",
|
|
1491
|
+
left: "0px",
|
|
1492
|
+
position: "absolute",
|
|
1493
|
+
pointerEvents: "auto"
|
|
1494
|
+
};
|
|
1495
|
+
Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));
|
|
1496
|
+
(_a = deck.getCanvas()) == null ? void 0 : _a.addEventListener("click", () => this.hide());
|
|
1497
|
+
(_b = deck.getCanvas()) == null ? void 0 : _b.addEventListener("contextmenu", (event) => this.handleContextMenu(event));
|
|
1498
|
+
return element;
|
|
1499
|
+
}
|
|
1500
|
+
onRenderHTML(rootElement) {
|
|
1501
|
+
const { visible, position, menuItems } = this.props;
|
|
1502
|
+
const ui = visible && menuItems.length ? (0, import_jsx_runtime18.jsx)(SimpleMenu, { menuItems, onItemSelected: (key) => this.props.onMenuItemSelected(key, this.pickInfo), position, style: { pointerEvents: "auto" } }) : null;
|
|
1503
|
+
(0, import_preact13.render)(ui, rootElement);
|
|
1504
|
+
}
|
|
1505
|
+
handleContextMenu(srcEvent) {
|
|
1506
|
+
var _a, _b, _c;
|
|
1507
|
+
if (srcEvent && (srcEvent.button === MOUSE_BUTTON_RIGHT || srcEvent.which === MOUSE_WHICH_RIGHT)) {
|
|
1508
|
+
this.pickInfo = ((_a = this.deck) == null ? void 0 : _a.pickObject({
|
|
1509
|
+
x: srcEvent.clientX,
|
|
1510
|
+
y: srcEvent.clientY
|
|
1511
|
+
})) || null;
|
|
1512
|
+
const menuItems = this.pickInfo && ((_c = (_b = this.props).getMenuItems) == null ? void 0 : _c.call(_b, this.pickInfo, this)) || [];
|
|
1513
|
+
const visible = menuItems.length > 0;
|
|
1514
|
+
this.setProps({
|
|
1515
|
+
visible,
|
|
1516
|
+
position: { x: srcEvent.clientX, y: srcEvent.clientY },
|
|
1517
|
+
menuItems
|
|
1518
|
+
});
|
|
1519
|
+
this.updateHTML();
|
|
1520
|
+
srcEvent.preventDefault();
|
|
1521
|
+
return visible;
|
|
1522
|
+
}
|
|
1523
|
+
return false;
|
|
1524
|
+
}
|
|
1525
|
+
hide() {
|
|
1526
|
+
this.setProps({ visible: false });
|
|
1527
|
+
}
|
|
1528
|
+
};
|
|
1529
|
+
ContextMenuWidget.defaultProps = {
|
|
1530
|
+
...import_core17.Widget.defaultProps,
|
|
1531
|
+
viewId: null,
|
|
1532
|
+
visible: false,
|
|
1533
|
+
position: { x: 0, y: 0 },
|
|
1534
|
+
getMenuItems: void 0,
|
|
1535
|
+
menuItems: [],
|
|
1536
|
+
// eslint-disable-next-line no-console
|
|
1537
|
+
onMenuItemSelected: (key, pickInfo) => console.log("Context menu item selected:", key, pickInfo)
|
|
1538
|
+
};
|
|
1539
|
+
|
|
1540
|
+
// dist/splitter-widget.js
|
|
1541
|
+
var import_jsx_runtime19 = require("preact/jsx-runtime");
|
|
1542
|
+
var import_preact14 = require("preact");
|
|
1543
|
+
var import_hooks2 = require("preact/hooks");
|
|
1544
|
+
var import_core18 = require("@deck.gl/core");
|
|
1545
|
+
var SplitterWidget = class extends import_core18.Widget {
|
|
1546
|
+
constructor(props) {
|
|
1547
|
+
super(props, SplitterWidget.defaultProps);
|
|
1548
|
+
this.className = "deck-widget-splitter";
|
|
1549
|
+
this.placement = "fill";
|
|
1550
|
+
}
|
|
1551
|
+
setProps(props) {
|
|
1552
|
+
super.setProps(props);
|
|
1553
|
+
}
|
|
1554
|
+
onRenderHTML(rootElement) {
|
|
1555
|
+
rootElement.style.position = "absolute";
|
|
1556
|
+
rootElement.style.top = "0";
|
|
1557
|
+
rootElement.style.left = "0";
|
|
1558
|
+
rootElement.style.width = "100%";
|
|
1559
|
+
rootElement.style.height = "100%";
|
|
1560
|
+
rootElement.style.margin = "0px";
|
|
1561
|
+
(0, import_preact14.render)((0, import_jsx_runtime19.jsx)(Splitter, { orientation: this.props.orientation, initialSplit: this.props.initialSplit, onChange: this.props.onChange, onDragStart: this.props.onDragStart, onDragEnd: this.props.onDragEnd }), rootElement);
|
|
1562
|
+
}
|
|
1563
|
+
};
|
|
1564
|
+
SplitterWidget.defaultProps = {
|
|
1565
|
+
...import_core18.Widget.defaultProps,
|
|
1566
|
+
id: "splitter-widget",
|
|
1567
|
+
viewId1: "",
|
|
1568
|
+
viewId2: "",
|
|
1569
|
+
orientation: "vertical",
|
|
1570
|
+
initialSplit: 0.5,
|
|
1571
|
+
onChange: () => {
|
|
1572
|
+
},
|
|
1573
|
+
onDragStart: () => {
|
|
1574
|
+
},
|
|
1575
|
+
onDragEnd: () => {
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
function Splitter({ orientation, initialSplit, onChange, onDragStart, onDragEnd }) {
|
|
1579
|
+
const [split, setSplit] = (0, import_hooks2.useState)(initialSplit);
|
|
1580
|
+
const dragging = (0, import_hooks2.useRef)(false);
|
|
1581
|
+
const containerRef = (0, import_hooks2.useRef)(null);
|
|
1582
|
+
const handleDragStart = (event) => {
|
|
1583
|
+
dragging.current = true;
|
|
1584
|
+
onDragStart == null ? void 0 : onDragStart();
|
|
1585
|
+
document.addEventListener("mousemove", handleDragging);
|
|
1586
|
+
document.addEventListener("mouseup", handleDragEnd);
|
|
1587
|
+
event.preventDefault();
|
|
1588
|
+
};
|
|
1589
|
+
const handleDragging = (event) => {
|
|
1590
|
+
if (!dragging.current || !containerRef.current)
|
|
1591
|
+
return;
|
|
1592
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
1593
|
+
let newSplit;
|
|
1594
|
+
if (orientation === "vertical") {
|
|
1595
|
+
newSplit = (event.clientX - rect.left) / rect.width;
|
|
1596
|
+
} else {
|
|
1597
|
+
newSplit = (event.clientY - rect.top) / rect.height;
|
|
1598
|
+
}
|
|
1599
|
+
newSplit = Math.min(Math.max(newSplit, 0.05), 0.95);
|
|
1600
|
+
setSplit(newSplit);
|
|
1601
|
+
onChange == null ? void 0 : onChange(newSplit);
|
|
1602
|
+
};
|
|
1603
|
+
const handleDragEnd = (event) => {
|
|
1604
|
+
if (!dragging.current)
|
|
1605
|
+
return;
|
|
1606
|
+
dragging.current = false;
|
|
1607
|
+
onDragEnd == null ? void 0 : onDragEnd();
|
|
1608
|
+
document.removeEventListener("mousemove", handleDragging);
|
|
1609
|
+
document.removeEventListener("mouseup", handleDragEnd);
|
|
1610
|
+
};
|
|
1611
|
+
const splitterStyle = orientation === "vertical" ? {
|
|
1612
|
+
position: "absolute",
|
|
1613
|
+
top: 0,
|
|
1614
|
+
bottom: 0,
|
|
1615
|
+
left: `${split * 100}%`,
|
|
1616
|
+
width: "4px",
|
|
1617
|
+
cursor: "col-resize",
|
|
1618
|
+
background: "#ccc",
|
|
1619
|
+
zIndex: 10,
|
|
1620
|
+
pointerEvents: "auto",
|
|
1621
|
+
boxShadow: "inset -1px 0 0 white, inset 1px 0 0 white"
|
|
1622
|
+
} : {
|
|
1623
|
+
position: "absolute",
|
|
1624
|
+
left: 0,
|
|
1625
|
+
right: 0,
|
|
1626
|
+
top: `${split * 100}%`,
|
|
1627
|
+
height: "4px",
|
|
1628
|
+
cursor: "row-resize",
|
|
1629
|
+
background: "#ccc",
|
|
1630
|
+
zIndex: 10,
|
|
1631
|
+
pointerEvents: "auto",
|
|
1632
|
+
boxShadow: "inset -1px 0 0 white, inset 1px 0 0 white"
|
|
1633
|
+
};
|
|
1634
|
+
const containerStyle = {
|
|
1635
|
+
position: "absolute",
|
|
1636
|
+
top: 0,
|
|
1637
|
+
left: 0,
|
|
1638
|
+
right: 0,
|
|
1639
|
+
bottom: 0
|
|
1640
|
+
};
|
|
1641
|
+
return (0, import_jsx_runtime19.jsx)("div", { ref: containerRef, style: containerStyle, children: (0, import_jsx_runtime19.jsx)("div", { style: splitterStyle, onMouseDown: handleDragStart }) });
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
// dist/timeline-widget.js
|
|
1645
|
+
var import_jsx_runtime20 = require("preact/jsx-runtime");
|
|
1646
|
+
var import_core19 = require("@deck.gl/core");
|
|
1647
|
+
var import_preact15 = require("preact");
|
|
1648
|
+
var TimelineWidget = class extends import_core19.Widget {
|
|
1649
|
+
constructor(props = {}) {
|
|
1650
|
+
super(props, TimelineWidget.defaultProps);
|
|
1651
|
+
this.id = "timeline";
|
|
1652
|
+
this.className = "deck-widget-timeline";
|
|
1653
|
+
this.placement = "bottom-left";
|
|
1654
|
+
this.playing = false;
|
|
1655
|
+
this.timerId = null;
|
|
1656
|
+
this.handlePlayPause = () => {
|
|
1657
|
+
if (this.playing) {
|
|
1658
|
+
this.stop();
|
|
1659
|
+
} else {
|
|
1660
|
+
this.start();
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
this.handleSliderChange = (e) => {
|
|
1664
|
+
const input = e.target;
|
|
1665
|
+
const val = Number(input.value);
|
|
1666
|
+
this.currentTime = val;
|
|
1667
|
+
this.props.onTimeChange(val);
|
|
1668
|
+
this.updateHTML();
|
|
1669
|
+
};
|
|
1670
|
+
this.tick = () => {
|
|
1671
|
+
const [min, max] = this.props.timeRange;
|
|
1672
|
+
let next = this.currentTime + this.props.step;
|
|
1673
|
+
if (next > max) {
|
|
1674
|
+
next = min;
|
|
1675
|
+
}
|
|
1676
|
+
this.currentTime = next;
|
|
1677
|
+
this.props.onTimeChange(next);
|
|
1678
|
+
this.updateHTML();
|
|
1679
|
+
if (this.playing) {
|
|
1680
|
+
this.timerId = window.setTimeout(this.tick, this.props.playInterval);
|
|
1681
|
+
}
|
|
1682
|
+
};
|
|
1683
|
+
this.currentTime = this.props.initialTime ?? this.props.timeRange[0];
|
|
1684
|
+
}
|
|
1685
|
+
setProps(props) {
|
|
1686
|
+
this.placement = props.placement || this.placement;
|
|
1687
|
+
super.setProps(props);
|
|
1688
|
+
}
|
|
1689
|
+
onAdd() {
|
|
1690
|
+
this.playing = false;
|
|
1691
|
+
this.timerId = null;
|
|
1692
|
+
}
|
|
1693
|
+
onRemove() {
|
|
1694
|
+
this.stop();
|
|
1695
|
+
}
|
|
1696
|
+
onRenderHTML(rootElement) {
|
|
1697
|
+
(0, import_preact15.render)((0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", pointerEvents: "auto" }, children: [(0, import_jsx_runtime20.jsx)("button", { type: "button", className: "timeline-play-pause", title: this.playing ? "Pause" : "Play", onClick: this.handlePlayPause, children: this.playing ? "\u23F8" : "\u25B6" }), (0, import_jsx_runtime20.jsx)("input", { type: "range", className: "timeline-slider", min: this.props.timeRange[0], max: this.props.timeRange[1], step: this.props.step, value: this.currentTime, onInput: this.handleSliderChange })] }), rootElement);
|
|
1698
|
+
}
|
|
1699
|
+
start() {
|
|
1700
|
+
this.playing = true;
|
|
1701
|
+
this.updateHTML();
|
|
1702
|
+
this.tick();
|
|
1703
|
+
}
|
|
1704
|
+
stop() {
|
|
1705
|
+
this.playing = false;
|
|
1706
|
+
if (this.timerId !== null) {
|
|
1707
|
+
window.clearTimeout(this.timerId);
|
|
1708
|
+
this.timerId = null;
|
|
1709
|
+
}
|
|
1710
|
+
this.updateHTML();
|
|
1711
|
+
}
|
|
1712
|
+
};
|
|
1713
|
+
TimelineWidget.defaultProps = {
|
|
1714
|
+
...import_core19.Widget.defaultProps,
|
|
1715
|
+
id: "timeline",
|
|
1716
|
+
placement: "bottom-left",
|
|
1717
|
+
timeRange: [0, 100],
|
|
1718
|
+
step: 1,
|
|
1719
|
+
initialTime: void 0,
|
|
1720
|
+
onTimeChange: () => {
|
|
1721
|
+
},
|
|
1722
|
+
playInterval: 1e3
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
// dist/view-selector-widget.js
|
|
1726
|
+
var import_jsx_runtime22 = require("preact/jsx-runtime");
|
|
1727
|
+
var import_preact16 = require("preact");
|
|
1728
|
+
var import_core20 = require("@deck.gl/core");
|
|
1729
|
+
|
|
1730
|
+
// dist/lib/components/icon-menu.js
|
|
1731
|
+
var import_jsx_runtime21 = require("preact/jsx-runtime");
|
|
1732
|
+
var import_hooks3 = require("preact/hooks");
|
|
1733
|
+
var MENU_STYLE2 = {
|
|
1734
|
+
position: "absolute",
|
|
1735
|
+
top: "100%",
|
|
1736
|
+
left: 0,
|
|
1737
|
+
background: "white",
|
|
1738
|
+
border: "1px solid #ccc",
|
|
1739
|
+
borderRadius: "4px",
|
|
1740
|
+
marginTop: "4px",
|
|
1741
|
+
zIndex: 100
|
|
1742
|
+
};
|
|
1743
|
+
var MENU_ITEM_STYLE2 = {
|
|
1744
|
+
background: "white",
|
|
1745
|
+
border: "none",
|
|
1746
|
+
padding: "4px",
|
|
1747
|
+
cursor: "pointer",
|
|
1748
|
+
pointerEvents: "auto"
|
|
1749
|
+
};
|
|
1750
|
+
function IconMenu(props) {
|
|
1751
|
+
const [menuOpen, setMenuOpen] = (0, import_hooks3.useState)(false);
|
|
1752
|
+
const containerRef = (0, import_hooks3.useRef)(null);
|
|
1753
|
+
const handleClickOutside = (event) => {
|
|
1754
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1755
|
+
setMenuOpen(false);
|
|
1756
|
+
}
|
|
1757
|
+
};
|
|
1758
|
+
(0, import_hooks3.useEffect)(() => {
|
|
1759
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1760
|
+
return () => {
|
|
1761
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1762
|
+
};
|
|
1763
|
+
}, [containerRef]);
|
|
1764
|
+
const [selectedItem, setSelectedItem] = (0, import_hooks3.useState)(props.initialItem);
|
|
1765
|
+
const handleSelectItem = (item) => {
|
|
1766
|
+
setSelectedItem(item);
|
|
1767
|
+
setMenuOpen(false);
|
|
1768
|
+
props.onItemSelected(item);
|
|
1769
|
+
};
|
|
1770
|
+
const handleButtonClick = () => setMenuOpen(!menuOpen);
|
|
1771
|
+
const selectedMenuItem = props.menuItems.find((item) => item.value === selectedItem);
|
|
1772
|
+
const label = props.label || (selectedMenuItem == null ? void 0 : selectedMenuItem.label) || "";
|
|
1773
|
+
const Icon = props.icon || (selectedMenuItem == null ? void 0 : selectedMenuItem.icon);
|
|
1774
|
+
return (0, import_jsx_runtime21.jsxs)("div", { style: { position: "relative", display: "inline-block" }, ref: containerRef, children: [(0, import_jsx_runtime21.jsx)(IconButton, { className: props.className, label, onClick: handleButtonClick, children: (0, import_jsx_runtime21.jsx)(Icon, {}) }), menuOpen && (0, import_jsx_runtime21.jsx)("div", { style: MENU_STYLE2, children: (0, import_jsx_runtime21.jsx)("div", { style: { display: "flex", flexDirection: "column" }, children: props.menuItems.map((item) => (0, import_jsx_runtime21.jsx)("button", { style: MENU_ITEM_STYLE2, title: item.label, onClick: () => handleSelectItem(item.value), children: item.icon }, item.value)) }) })] });
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
// dist/view-selector-widget.js
|
|
1778
|
+
var ViewSelectorWidget = class extends import_core20.Widget {
|
|
1779
|
+
constructor(props = {}) {
|
|
1780
|
+
super(props, ViewSelectorWidget.defaultProps);
|
|
1781
|
+
this.className = "deck-widget-view-selector";
|
|
1782
|
+
this.placement = "top-left";
|
|
1783
|
+
this.handleSelectMode = (viewMode) => {
|
|
1784
|
+
this.viewMode = viewMode;
|
|
1785
|
+
this.updateHTML();
|
|
1786
|
+
};
|
|
1787
|
+
this.placement = this.props.placement;
|
|
1788
|
+
this.viewMode = this.props.initialViewMode;
|
|
1789
|
+
}
|
|
1790
|
+
setProps(props) {
|
|
1791
|
+
super.setProps(props);
|
|
1792
|
+
this.placement = props.placement ?? this.placement;
|
|
1793
|
+
}
|
|
1794
|
+
onRenderHTML(rootElement) {
|
|
1795
|
+
(0, import_preact16.render)((0, import_jsx_runtime22.jsx)(IconMenu, { className: "deck-widget-view-selector", menuItems: MENU_ITEMS, initialItem: this.props.initialViewMode, onItemSelected: this.handleSelectMode }), rootElement);
|
|
1796
|
+
}
|
|
1797
|
+
};
|
|
1798
|
+
ViewSelectorWidget.defaultProps = {
|
|
1799
|
+
...import_core20.Widget.defaultProps,
|
|
1800
|
+
id: "view-selector-widget",
|
|
1801
|
+
placement: "top-left",
|
|
1802
|
+
label: "Split View",
|
|
1803
|
+
initialViewMode: "single",
|
|
1804
|
+
onViewModeChange: (viewMode) => {
|
|
1805
|
+
console.log(viewMode);
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1808
|
+
var ICON_STYLE = { width: "24px", height: "24px" };
|
|
1809
|
+
var ICONS = {
|
|
1810
|
+
single: () => (0, import_jsx_runtime22.jsx)("svg", { width: "24", height: "24", style: ICON_STYLE, children: (0, import_jsx_runtime22.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", stroke: "black", fill: "none", strokeWidth: "2" }) }),
|
|
1811
|
+
"split-horizontal": () => (0, import_jsx_runtime22.jsxs)("svg", { width: "24", height: "24", style: ICON_STYLE, children: [(0, import_jsx_runtime22.jsx)("rect", { x: "4", y: "4", width: "16", height: "7", stroke: "black", fill: "none", strokeWidth: "2" }), (0, import_jsx_runtime22.jsx)("rect", { x: "4", y: "13", width: "16", height: "7", stroke: "black", fill: "none", strokeWidth: "2" })] }),
|
|
1812
|
+
"split-vertical": () => (0, import_jsx_runtime22.jsxs)("svg", { width: "24", height: "24", style: ICON_STYLE, children: [(0, import_jsx_runtime22.jsx)("rect", { x: "4", y: "4", width: "7", height: "16", stroke: "black", fill: "none", strokeWidth: "2" }), (0, import_jsx_runtime22.jsx)("rect", { x: "13", y: "4", width: "7", height: "16", stroke: "black", fill: "none", strokeWidth: "2" })] })
|
|
572
1813
|
};
|
|
1814
|
+
var MENU_ITEMS = [
|
|
1815
|
+
{ value: "single", icon: ICONS.single, label: "Single View" },
|
|
1816
|
+
{ value: "split-horizontal", icon: ICONS["split-horizontal"], label: "Split Horizontal" },
|
|
1817
|
+
{ value: "split-vertical", icon: ICONS["split-vertical"], label: "Split Vertical" }
|
|
1818
|
+
];
|
|
573
1819
|
//# sourceMappingURL=index.cjs.map
|