@deck.gl/widgets 9.2.0-beta.2 → 9.2.0-beta.4
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 +1 -1
- package/dist/compass-widget.d.ts.map +1 -1
- package/dist/compass-widget.js +0 -1
- package/dist/compass-widget.js.map +1 -1
- package/dist/context-menu-widget.d.ts +2 -2
- package/dist/context-menu-widget.d.ts.map +1 -1
- package/dist/context-menu-widget.js +4 -1
- package/dist/context-menu-widget.js.map +1 -1
- package/dist/dist.dev.js +965 -900
- package/dist/fps-widget.d.ts +5 -6
- package/dist/fps-widget.d.ts.map +1 -1
- package/dist/fps-widget.js +14 -15
- package/dist/fps-widget.js.map +1 -1
- package/dist/fullscreen-widget.d.ts +2 -0
- package/dist/fullscreen-widget.d.ts.map +1 -1
- package/dist/fullscreen-widget.js +7 -3
- package/dist/fullscreen-widget.js.map +1 -1
- package/dist/geocoder-widget.d.ts +4 -3
- package/dist/geocoder-widget.d.ts.map +1 -1
- package/dist/geocoder-widget.js +3 -4
- package/dist/geocoder-widget.js.map +1 -1
- package/dist/gimbal-widget.d.ts +7 -5
- package/dist/gimbal-widget.d.ts.map +1 -1
- package/dist/gimbal-widget.js +15 -10
- package/dist/gimbal-widget.js.map +1 -1
- package/dist/index.cjs +685 -668
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -9
- package/dist/index.js.map +1 -1
- package/dist/info-widget.d.ts +9 -9
- package/dist/info-widget.d.ts.map +1 -1
- package/dist/info-widget.js +7 -9
- package/dist/info-widget.js.map +1 -1
- package/dist/lib/components/button-group.d.ts +1 -1
- package/dist/lib/components/button-group.d.ts.map +1 -1
- package/dist/lib/components/button-group.js +1 -1
- package/dist/lib/components/button-group.js.map +1 -1
- package/dist/lib/components/grouped-icon-button.d.ts +5 -3
- package/dist/lib/components/grouped-icon-button.d.ts.map +1 -1
- package/dist/lib/components/grouped-icon-button.js +3 -3
- package/dist/lib/components/grouped-icon-button.js.map +1 -1
- package/dist/lib/components/icon-button.d.ts +5 -6
- package/dist/lib/components/icon-button.d.ts.map +1 -1
- package/dist/lib/components/icon-button.js +1 -1
- package/dist/lib/components/icon-button.js.map +1 -1
- package/dist/lib/components/icon-menu.d.ts +2 -2
- package/dist/lib/components/icon-menu.d.ts.map +1 -1
- package/dist/lib/components/icon-menu.js +4 -19
- package/dist/lib/components/icon-menu.js.map +1 -1
- package/dist/lib/components/simple-menu.js +1 -1
- package/dist/lib/components/simple-menu.js.map +1 -1
- package/dist/loading-widget.d.ts +4 -2
- package/dist/loading-widget.d.ts.map +1 -1
- package/dist/loading-widget.js +5 -3
- package/dist/loading-widget.js.map +1 -1
- package/dist/reset-view-widget.d.ts +9 -11
- package/dist/reset-view-widget.d.ts.map +1 -1
- package/dist/reset-view-widget.js +5 -4
- package/dist/reset-view-widget.js.map +1 -1
- package/dist/scale-widget.d.ts +6 -3
- package/dist/scale-widget.d.ts.map +1 -1
- package/dist/scale-widget.js +3 -2
- package/dist/scale-widget.js.map +1 -1
- package/dist/screenshot-widget.d.ts +4 -2
- package/dist/screenshot-widget.d.ts.map +1 -1
- package/dist/screenshot-widget.js +3 -1
- package/dist/screenshot-widget.js.map +1 -1
- package/dist/splitter-widget.d.ts +1 -1
- package/dist/splitter-widget.d.ts.map +1 -1
- package/dist/splitter-widget.js +0 -2
- package/dist/splitter-widget.js.map +1 -1
- package/dist/stats-widget.d.ts +6 -1
- package/dist/stats-widget.d.ts.map +1 -1
- package/dist/stats-widget.js +11 -4
- package/dist/stats-widget.js.map +1 -1
- package/dist/stylesheet.css +53 -35
- package/dist/theme-widget.d.ts +3 -1
- package/dist/theme-widget.d.ts.map +1 -1
- package/dist/theme-widget.js +6 -3
- package/dist/theme-widget.js.map +1 -1
- package/dist/themes.d.ts +10 -0
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +12 -4
- package/dist/themes.js.map +1 -1
- package/dist/timeline-widget.d.ts +10 -32
- package/dist/timeline-widget.d.ts.map +1 -1
- package/dist/timeline-widget.js +6 -2
- package/dist/timeline-widget.js.map +1 -1
- package/dist/view-selector-widget.d.ts +2 -0
- package/dist/view-selector-widget.d.ts.map +1 -1
- package/dist/view-selector-widget.js +14 -13
- package/dist/view-selector-widget.js.map +1 -1
- package/dist/zoom-widget.d.ts +1 -2
- package/dist/zoom-widget.d.ts.map +1 -1
- package/dist/zoom-widget.js +7 -5
- package/dist/zoom-widget.js.map +1 -1
- package/dist.min.js +2 -3
- package/package.json +2 -2
- package/src/compass-widget.tsx +1 -1
- package/src/context-menu-widget.tsx +7 -3
- package/src/fps-widget.tsx +26 -17
- package/src/fullscreen-widget.tsx +9 -3
- package/src/geocoder-widget.tsx +7 -7
- package/src/gimbal-widget.tsx +16 -11
- package/src/index.ts +15 -10
- package/src/info-widget.tsx +17 -17
- package/src/lib/components/button-group.tsx +2 -2
- package/src/lib/components/grouped-icon-button.tsx +9 -6
- package/src/lib/components/icon-button.tsx +5 -6
- package/src/lib/components/icon-menu.tsx +12 -30
- package/src/lib/components/simple-menu.tsx +1 -1
- package/src/loading-widget.tsx +9 -5
- package/src/reset-view-widget.tsx +18 -16
- package/src/scale-widget.tsx +9 -5
- package/src/screenshot-widget.tsx +7 -3
- package/src/splitter-widget.tsx +1 -3
- package/src/stats-widget.tsx +18 -5
- package/src/stylesheet.css +53 -35
- package/src/theme-widget.tsx +9 -4
- package/src/themes.ts +15 -4
- package/src/timeline-widget.tsx +19 -42
- package/src/view-selector-widget.tsx +58 -15
- package/src/zoom-widget.tsx +8 -6
package/src/compass-widget.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';
|
|
|
7
7
|
import {render} from 'preact';
|
|
8
8
|
|
|
9
9
|
export type CompassWidgetProps = WidgetProps & {
|
|
10
|
+
/** Widget positioning within the view. Default 'top-left'. */
|
|
10
11
|
placement?: WidgetPlacement;
|
|
11
12
|
/** View to attach to and interact with. Required when using multiple views. */
|
|
12
13
|
viewId?: string | null;
|
|
@@ -28,7 +29,6 @@ export class CompassWidget extends Widget<CompassWidgetProps> {
|
|
|
28
29
|
|
|
29
30
|
className = 'deck-widget-compass';
|
|
30
31
|
placement: WidgetPlacement = 'top-left';
|
|
31
|
-
viewId?: string | null = null;
|
|
32
32
|
viewports: {[id: string]: Viewport} = {};
|
|
33
33
|
|
|
34
34
|
constructor(props: CompassWidgetProps = {}) {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
// deck.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
1
5
|
/* global document */
|
|
2
|
-
import {Widget
|
|
3
|
-
import type {Deck, PickingInfo} from '@deck.gl/core';
|
|
6
|
+
import {Widget} from '@deck.gl/core';
|
|
7
|
+
import type {Deck, PickingInfo, WidgetProps} from '@deck.gl/core';
|
|
4
8
|
import {render} from 'preact';
|
|
5
9
|
import {SimpleMenu} from './lib/components/simple-menu';
|
|
6
10
|
|
|
@@ -50,7 +54,7 @@ export class ContextMenuWidget extends Widget<ContextMenuWidgetProps> {
|
|
|
50
54
|
constructor(props: ContextMenuWidgetProps) {
|
|
51
55
|
super(props, ContextMenuWidget.defaultProps);
|
|
52
56
|
this.pickInfo = null;
|
|
53
|
-
this.setProps(props);
|
|
57
|
+
this.setProps(this.props);
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
onAdd({deck}: {deck: Deck<any>}): HTMLDivElement {
|
package/src/fps-widget.tsx
CHANGED
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {Widget
|
|
6
|
-
import
|
|
5
|
+
import {Widget} from '@deck.gl/core';
|
|
6
|
+
import {render} from 'preact';
|
|
7
|
+
import type {WidgetPlacement, Deck, WidgetProps} from '@deck.gl/core';
|
|
8
|
+
import {IconButton} from './lib/components/icon-button';
|
|
7
9
|
|
|
8
10
|
/** Properties for the FpsWidget. */
|
|
9
11
|
export type FpsWidgetProps = WidgetProps & {
|
|
10
12
|
/** Widget positioning within the view. Default 'top-left'. */
|
|
11
13
|
placement?: WidgetPlacement;
|
|
14
|
+
/** View to attach to and interact with. Required when using multiple views. */
|
|
15
|
+
viewId?: string | null;
|
|
12
16
|
};
|
|
13
17
|
|
|
14
18
|
/**
|
|
@@ -18,7 +22,8 @@ export class FpsWidget extends Widget<FpsWidgetProps> {
|
|
|
18
22
|
static defaultProps: Required<FpsWidgetProps> = {
|
|
19
23
|
...Widget.defaultProps,
|
|
20
24
|
id: 'fps',
|
|
21
|
-
placement: 'top-left'
|
|
25
|
+
placement: 'top-left',
|
|
26
|
+
viewId: null
|
|
22
27
|
};
|
|
23
28
|
|
|
24
29
|
className = 'deck-widget-fps';
|
|
@@ -28,41 +33,45 @@ export class FpsWidget extends Widget<FpsWidgetProps> {
|
|
|
28
33
|
|
|
29
34
|
constructor(props: FpsWidgetProps = {}) {
|
|
30
35
|
super(props, FpsWidget.defaultProps);
|
|
31
|
-
this.
|
|
36
|
+
this.setProps(this.props);
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
setProps(props: Partial<FpsWidgetProps>): void {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
40
|
+
this.placement = props.placement ?? this.placement;
|
|
41
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
38
42
|
super.setProps(props);
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
onAdd({}: {deck: Deck<any>; viewId: string | null}): void {
|
|
42
46
|
this._lastFps = this._getFps();
|
|
43
|
-
this.
|
|
47
|
+
requestAnimationFrame(() => this._animate());
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
onRenderHTML(rootElement: HTMLElement): void {
|
|
47
51
|
const fps = this._getFps();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
render(
|
|
53
|
+
<IconButton>
|
|
54
|
+
<div className="text">
|
|
55
|
+
FPS
|
|
56
|
+
<br />
|
|
57
|
+
{fps}
|
|
58
|
+
</div>
|
|
59
|
+
</IconButton>,
|
|
60
|
+
rootElement
|
|
61
|
+
);
|
|
54
62
|
}
|
|
55
63
|
|
|
56
|
-
|
|
64
|
+
_animate(): void {
|
|
57
65
|
const fps = this._getFps();
|
|
58
|
-
if (
|
|
66
|
+
if (this._lastFps !== fps) {
|
|
59
67
|
this._lastFps = fps;
|
|
60
68
|
this.updateHTML();
|
|
61
69
|
}
|
|
70
|
+
requestAnimationFrame(() => this._animate());
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
_getFps(): number {
|
|
65
74
|
// @ts-expect-error protected
|
|
66
|
-
return Math.round(this.deck
|
|
75
|
+
return Math.round(this.deck?.metrics.fps ?? 0);
|
|
67
76
|
}
|
|
68
77
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
/* global document */
|
|
6
|
-
import {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';
|
|
6
|
+
import {log, Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';
|
|
7
7
|
import {render} from 'preact';
|
|
8
8
|
import {IconButton} from './lib/components/icon-button';
|
|
9
9
|
|
|
@@ -13,6 +13,8 @@ export type FullscreenWidgetProps = WidgetProps & {
|
|
|
13
13
|
id?: string;
|
|
14
14
|
/** Widget positioning within the view. Default 'top-left'. */
|
|
15
15
|
placement?: WidgetPlacement;
|
|
16
|
+
/** View to attach to and interact with. Required when using multiple views. */
|
|
17
|
+
viewId?: string | null;
|
|
16
18
|
/** Tooltip message when out of fullscreen. */
|
|
17
19
|
enterLabel?: string;
|
|
18
20
|
/** Tooltip message when fullscreen. */
|
|
@@ -29,6 +31,7 @@ export class FullscreenWidget extends Widget<FullscreenWidgetProps> {
|
|
|
29
31
|
...Widget.defaultProps,
|
|
30
32
|
id: 'fullscreen',
|
|
31
33
|
placement: 'top-left',
|
|
34
|
+
viewId: null,
|
|
32
35
|
enterLabel: 'Enter Fullscreen',
|
|
33
36
|
exitLabel: 'Exit Fullscreen',
|
|
34
37
|
container: undefined!
|
|
@@ -40,7 +43,7 @@ export class FullscreenWidget extends Widget<FullscreenWidgetProps> {
|
|
|
40
43
|
|
|
41
44
|
constructor(props: FullscreenWidgetProps = {}) {
|
|
42
45
|
super(props, FullscreenWidget.defaultProps);
|
|
43
|
-
this.
|
|
46
|
+
this.setProps(this.props);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
onAdd(): void {
|
|
@@ -54,7 +57,9 @@ export class FullscreenWidget extends Widget<FullscreenWidgetProps> {
|
|
|
54
57
|
onRenderHTML(rootElement: HTMLElement): void {
|
|
55
58
|
render(
|
|
56
59
|
<IconButton
|
|
57
|
-
onClick={
|
|
60
|
+
onClick={() => {
|
|
61
|
+
this.handleClick().catch(err => log.error(err)());
|
|
62
|
+
}}
|
|
58
63
|
label={this.fullscreen ? this.props.exitLabel : this.props.enterLabel}
|
|
59
64
|
className={this.fullscreen ? 'deck-widget-fullscreen-exit' : 'deck-widget-fullscreen-enter'}
|
|
60
65
|
/>,
|
|
@@ -64,6 +69,7 @@ export class FullscreenWidget extends Widget<FullscreenWidgetProps> {
|
|
|
64
69
|
|
|
65
70
|
setProps(props: Partial<FullscreenWidgetProps>) {
|
|
66
71
|
this.placement = props.placement ?? this.placement;
|
|
72
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
67
73
|
super.setProps(props);
|
|
68
74
|
}
|
|
69
75
|
|
package/src/geocoder-widget.tsx
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {Widget
|
|
6
|
-
import type {WidgetPlacement, Viewport} from '@deck.gl/core';
|
|
5
|
+
import {Widget} from '@deck.gl/core';
|
|
6
|
+
import type {WidgetPlacement, Viewport, WidgetProps} from '@deck.gl/core';
|
|
7
7
|
import {FlyToInterpolator, LinearInterpolator} from '@deck.gl/core';
|
|
8
8
|
import {render} from 'preact';
|
|
9
9
|
import {DropdownMenu} from './lib/components/dropdown-menu';
|
|
@@ -24,11 +24,12 @@ const CURRENT_LOCATION = 'current';
|
|
|
24
24
|
|
|
25
25
|
/** Properties for the GeocoderWidget */
|
|
26
26
|
export type GeocoderWidgetProps = WidgetProps & {
|
|
27
|
-
viewId?: string;
|
|
27
|
+
viewId?: string | null;
|
|
28
28
|
/** Widget positioning within the view. Default 'top-left'. */
|
|
29
29
|
placement?: WidgetPlacement;
|
|
30
30
|
/** Tooltip message */
|
|
31
31
|
label?: string;
|
|
32
|
+
/** View state reset transition duration in ms. 0 disables the transition */
|
|
32
33
|
transitionDuration?: number;
|
|
33
34
|
/** Geocoding service selector, for declarative usage */
|
|
34
35
|
geocoder?: 'google' | 'mapbox' | 'opencage' | 'coordinates' | 'custom';
|
|
@@ -49,7 +50,7 @@ export class GeocoderWidget extends Widget<GeocoderWidgetProps> {
|
|
|
49
50
|
static defaultProps: Required<GeocoderWidgetProps> = {
|
|
50
51
|
...Widget.defaultProps,
|
|
51
52
|
id: 'geocoder',
|
|
52
|
-
viewId:
|
|
53
|
+
viewId: null,
|
|
53
54
|
placement: 'top-left',
|
|
54
55
|
label: 'Geocoder',
|
|
55
56
|
transitionDuration: 200,
|
|
@@ -68,18 +69,17 @@ export class GeocoderWidget extends Widget<GeocoderWidgetProps> {
|
|
|
68
69
|
|
|
69
70
|
constructor(props: GeocoderWidgetProps = {}) {
|
|
70
71
|
super(props, GeocoderWidget.defaultProps);
|
|
71
|
-
this.placement = this.props.placement ?? this.placement;
|
|
72
72
|
this.setProps(this.props);
|
|
73
|
-
this.geocoder = getGeocoder(this.props);
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
setProps(props: Partial<GeocoderWidgetProps>): void {
|
|
77
|
-
super.setProps(props);
|
|
78
76
|
this.placement = props.placement ?? this.placement;
|
|
77
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
79
78
|
this.geocoder = getGeocoder(this.props);
|
|
80
79
|
if (this.geocoder.requiresApiKey && !this.props.apiKey) {
|
|
81
80
|
throw new Error(`API key is required for the ${this.geocoder.name} geocoder`);
|
|
82
81
|
}
|
|
82
|
+
super.setProps(props);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
onRenderHTML(rootElement: HTMLElement): void {
|
package/src/gimbal-widget.tsx
CHANGED
|
@@ -12,7 +12,7 @@ export type GimbalWidgetProps = WidgetProps & {
|
|
|
12
12
|
viewId?: string | null;
|
|
13
13
|
/** Tooltip message. */
|
|
14
14
|
label?: string;
|
|
15
|
-
/** Width of gimbal lines */
|
|
15
|
+
/** Width of gimbal lines. */
|
|
16
16
|
strokeWidth?: number;
|
|
17
17
|
/** Transition duration in ms when resetting rotation. */
|
|
18
18
|
transitionDuration?: number;
|
|
@@ -23,7 +23,7 @@ export class GimbalWidget extends Widget<GimbalWidgetProps> {
|
|
|
23
23
|
...Widget.defaultProps,
|
|
24
24
|
id: 'gimbal',
|
|
25
25
|
placement: 'top-left',
|
|
26
|
-
viewId:
|
|
26
|
+
viewId: null,
|
|
27
27
|
label: 'Gimbal',
|
|
28
28
|
strokeWidth: 1.5,
|
|
29
29
|
transitionDuration: 200
|
|
@@ -31,7 +31,7 @@ export class GimbalWidget extends Widget<GimbalWidgetProps> {
|
|
|
31
31
|
|
|
32
32
|
className = 'deck-widget-gimbal';
|
|
33
33
|
placement: WidgetPlacement = 'top-left';
|
|
34
|
-
|
|
34
|
+
viewports: {[id: string]: Viewport} = {};
|
|
35
35
|
|
|
36
36
|
constructor(props: GimbalWidgetProps = {}) {
|
|
37
37
|
super(props, GimbalWidget.defaultProps);
|
|
@@ -45,14 +45,18 @@ export class GimbalWidget extends Widget<GimbalWidgetProps> {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
onRenderHTML(rootElement: HTMLElement): void {
|
|
48
|
-
const
|
|
48
|
+
const viewId = this.viewId || Object.values(this.viewports)[0]?.id || 'default-view';
|
|
49
|
+
const widgetViewport = this.viewports[viewId];
|
|
50
|
+
const {rotationOrbit, rotationX} = this.getNormalizedRotation(widgetViewport);
|
|
49
51
|
// Note - we use CSS 3D transforms instead of SVG 2D transforms
|
|
50
52
|
const ui = (
|
|
51
53
|
<div className="deck-widget-button" style={{perspective: 100, pointerEvents: 'auto'}}>
|
|
52
54
|
<button
|
|
53
55
|
type="button"
|
|
54
56
|
onClick={() => {
|
|
55
|
-
this.
|
|
57
|
+
for (const viewport of Object.values(this.viewports)) {
|
|
58
|
+
this.resetOrbitView(viewport);
|
|
59
|
+
}
|
|
56
60
|
}}
|
|
57
61
|
title={this.props.label}
|
|
58
62
|
style={{position: 'relative', width: 26, height: 26}}
|
|
@@ -110,11 +114,12 @@ export class GimbalWidget extends Widget<GimbalWidgetProps> {
|
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
onViewportChange(viewport: Viewport) {
|
|
117
|
+
this.viewports[viewport.id] = viewport;
|
|
113
118
|
this.updateHTML();
|
|
114
119
|
}
|
|
115
120
|
|
|
116
|
-
resetOrbitView() {
|
|
117
|
-
const viewId = this.getViewId();
|
|
121
|
+
resetOrbitView(viewport?: Viewport) {
|
|
122
|
+
const viewId = this.getViewId(viewport);
|
|
118
123
|
const viewState = this.getViewState(viewId);
|
|
119
124
|
if ('rotationOrbit' in viewState || 'rotationX' in viewState) {
|
|
120
125
|
const nextViewState = {
|
|
@@ -131,8 +136,8 @@ export class GimbalWidget extends Widget<GimbalWidgetProps> {
|
|
|
131
136
|
}
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
getNormalizedRotation() {
|
|
135
|
-
const viewState = this.getViewState(this.getViewId());
|
|
139
|
+
getNormalizedRotation(viewport?: Viewport): {rotationOrbit: number; rotationX: number} {
|
|
140
|
+
const viewState = this.getViewState(this.getViewId(viewport));
|
|
136
141
|
const [rz, rx] = this.getRotation(viewState);
|
|
137
142
|
const rotationOrbit = normalizeAndClampAngle(rz);
|
|
138
143
|
const rotationX = normalizeAndClampAngle(rx);
|
|
@@ -148,8 +153,8 @@ export class GimbalWidget extends Widget<GimbalWidgetProps> {
|
|
|
148
153
|
|
|
149
154
|
// Move to Widget/WidgetManager?
|
|
150
155
|
|
|
151
|
-
getViewId() {
|
|
152
|
-
const viewId = this.viewId || 'OrbitView';
|
|
156
|
+
getViewId(viewport?: Viewport) {
|
|
157
|
+
const viewId = this.viewId || viewport?.id || 'OrbitView';
|
|
153
158
|
return viewId;
|
|
154
159
|
}
|
|
155
160
|
|
package/src/index.ts
CHANGED
|
@@ -5,25 +5,31 @@
|
|
|
5
5
|
// Navigation widgets
|
|
6
6
|
export {ZoomWidget} from './zoom-widget';
|
|
7
7
|
export {ResetViewWidget} from './reset-view-widget';
|
|
8
|
+
export {GimbalWidget} from './gimbal-widget';
|
|
8
9
|
|
|
9
10
|
// Geospatial widgets
|
|
10
11
|
export {CompassWidget} from './compass-widget';
|
|
11
|
-
export {GimbalWidget} from './gimbal-widget';
|
|
12
12
|
export {ScaleWidget as _ScaleWidget} from './scale-widget';
|
|
13
13
|
export {GeocoderWidget as _GeocoderWidget} from './geocoder-widget';
|
|
14
14
|
|
|
15
|
-
//
|
|
15
|
+
// View widgets
|
|
16
16
|
export {FullscreenWidget} from './fullscreen-widget';
|
|
17
|
+
export {SplitterWidget as _SplitterWidget} from './splitter-widget';
|
|
18
|
+
export {ViewSelectorWidget as _ViewSelectorWidget} from './view-selector-widget';
|
|
19
|
+
|
|
20
|
+
// Information widgets
|
|
21
|
+
export {InfoWidget as _InfoWidget} from './info-widget';
|
|
22
|
+
export {ContextMenuWidget as _ContextMenuWidget} from './context-menu-widget';
|
|
23
|
+
|
|
24
|
+
// Control widgets
|
|
25
|
+
export {TimelineWidget as _TimelineWidget} from './timeline-widget';
|
|
26
|
+
|
|
27
|
+
// Utility widgets
|
|
17
28
|
export {ScreenshotWidget} from './screenshot-widget';
|
|
29
|
+
export {ThemeWidget as _ThemeWidget} from './theme-widget';
|
|
18
30
|
export {LoadingWidget as _LoadingWidget} from './loading-widget';
|
|
19
31
|
export {FpsWidget as _FpsWidget} from './fps-widget';
|
|
20
|
-
export {ThemeWidget as _ThemeWidget} from './theme-widget';
|
|
21
|
-
export {InfoWidget as _InfoWidget} from './info-widget';
|
|
22
32
|
export {StatsWidget as _StatsWidget} from './stats-widget';
|
|
23
|
-
export {ContextMenuWidget as _ContextMenuWidget} from './context-menu-widget';
|
|
24
|
-
export {SplitterWidget as _SplitterWidget} from './splitter-widget';
|
|
25
|
-
export {TimelineWidget as _TimelineWidget} from './timeline-widget';
|
|
26
|
-
export {ViewSelectorWidget as _ViewSelectorWidget} from './view-selector-widget';
|
|
27
33
|
|
|
28
34
|
export type {FullscreenWidgetProps} from './fullscreen-widget';
|
|
29
35
|
export type {CompassWidgetProps} from './compass-widget';
|
|
@@ -46,8 +52,7 @@ export type {GimbalWidgetProps} from './gimbal-widget';
|
|
|
46
52
|
export {LightTheme, DarkTheme, LightGlassTheme, DarkGlassTheme} from './themes';
|
|
47
53
|
export type {DeckWidgetTheme} from './themes';
|
|
48
54
|
|
|
49
|
-
// Experimental
|
|
50
|
-
|
|
55
|
+
// Experimental preact components
|
|
51
56
|
export {ButtonGroup as _ButtonGroup, type ButtonGroupProps} from './lib/components/button-group';
|
|
52
57
|
export {IconButton as _IconButton, type IconButtonProps} from './lib/components/icon-button';
|
|
53
58
|
export {
|
package/src/info-widget.tsx
CHANGED
|
@@ -1,33 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// deck.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {Widget} from '@deck.gl/core';
|
|
6
|
+
import type {Deck, PickingInfo, Viewport, WidgetProps} from '@deck.gl/core';
|
|
4
7
|
import {render, JSX} from 'preact';
|
|
5
8
|
|
|
6
9
|
export type InfoWidgetProps = WidgetProps & {
|
|
7
|
-
/** View to attach to and interact with. Required when using multiple views
|
|
10
|
+
/** View to attach to and interact with. Required when using multiple views */
|
|
8
11
|
viewId?: string | null;
|
|
9
|
-
/**
|
|
12
|
+
/** Determines the interaction mode of the widget */
|
|
10
13
|
mode: 'click' | 'hover' | 'static';
|
|
11
|
-
/**
|
|
12
|
-
getTooltip?: (info: PickingInfo, widget: InfoWidget) =>
|
|
13
|
-
/** Position at which to place popup (clicked point: [longitude, latitude])
|
|
14
|
+
/** Function to generate the popup contents from the selected element */
|
|
15
|
+
getTooltip?: (info: PickingInfo, widget: InfoWidget) => InfoWidgetProps | null;
|
|
16
|
+
/** Position at which to place popup (clicked point: [longitude, latitude]) */
|
|
14
17
|
position: [number, number];
|
|
15
|
-
/** Text of popup */
|
|
18
|
+
/** Text content of popup */
|
|
16
19
|
text?: string;
|
|
17
20
|
/** Visibility of info widget */
|
|
18
21
|
visible?: boolean;
|
|
19
22
|
/** Minimum offset (in pixels) to keep the popup away from the canvas edges. */
|
|
20
23
|
minOffset?: number;
|
|
24
|
+
/** Callback triggered when the widget is clicked. */
|
|
21
25
|
onClick?: (widget: InfoWidget, info: PickingInfo) => boolean;
|
|
22
26
|
};
|
|
23
27
|
|
|
24
28
|
export class InfoWidget extends Widget<InfoWidgetProps> {
|
|
25
29
|
static defaultProps: Required<InfoWidgetProps> = {
|
|
26
30
|
...Widget.defaultProps,
|
|
31
|
+
id: 'info',
|
|
27
32
|
position: [0, 0],
|
|
28
33
|
text: '',
|
|
29
34
|
visible: false,
|
|
30
|
-
// Set default minOffset if not provided
|
|
31
35
|
minOffset: 0,
|
|
32
36
|
viewId: null,
|
|
33
37
|
mode: 'hover',
|
|
@@ -37,19 +41,15 @@ export class InfoWidget extends Widget<InfoWidgetProps> {
|
|
|
37
41
|
|
|
38
42
|
className = 'deck-widget-info';
|
|
39
43
|
placement = 'fill' as const;
|
|
40
|
-
viewId?: string | null = null;
|
|
41
44
|
viewport?: Viewport;
|
|
42
45
|
|
|
43
46
|
constructor(props: InfoWidgetProps) {
|
|
44
47
|
super(props, InfoWidget.defaultProps);
|
|
45
|
-
|
|
46
|
-
props.text = props.text || '';
|
|
47
|
-
props.visible = props.visible || false;
|
|
48
|
-
// Set default minOffset if not provided
|
|
49
|
-
props.minOffset = props.minOffset ?? 0;
|
|
48
|
+
this.setProps(this.props);
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
setProps(props: Partial<InfoWidgetProps>) {
|
|
52
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
53
53
|
super.setProps(props);
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -72,7 +72,7 @@ export class InfoWidget extends Widget<InfoWidgetProps> {
|
|
|
72
72
|
this.setProps({
|
|
73
73
|
visible: tooltip !== null,
|
|
74
74
|
...tooltip,
|
|
75
|
-
style: {zIndex: 1, ...tooltip?.style}
|
|
75
|
+
style: {zIndex: '1', ...tooltip?.style}
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -6,11 +6,11 @@ import type {ComponentChildren} from 'preact';
|
|
|
6
6
|
|
|
7
7
|
export type ButtonGroupProps = {
|
|
8
8
|
children: ComponentChildren;
|
|
9
|
-
orientation;
|
|
9
|
+
orientation: 'vertical' | 'horizontal';
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
/** Renders a group of buttons with Widget CSS */
|
|
13
13
|
export const ButtonGroup = (props: ButtonGroupProps) => {
|
|
14
|
-
const {children, orientation} = props;
|
|
14
|
+
const {children, orientation = 'horizontal'} = props;
|
|
15
15
|
return <div className={`deck-widget-button-group ${orientation}`}>{children}</div>;
|
|
16
16
|
};
|
|
@@ -2,23 +2,26 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
import type {ComponentChildren, JSX} from 'preact';
|
|
6
|
+
|
|
5
7
|
export type GroupedIconButtonProps = {
|
|
6
8
|
className?: string;
|
|
7
|
-
label
|
|
8
|
-
onClick
|
|
9
|
+
label?: string;
|
|
10
|
+
onClick?: JSX.MouseEventHandler<HTMLButtonElement>;
|
|
11
|
+
children?: ComponentChildren;
|
|
9
12
|
};
|
|
10
13
|
|
|
11
14
|
/** Renders an icon button as part of a ButtonGroup */
|
|
12
|
-
export const GroupedIconButton = props => {
|
|
13
|
-
const {className, label, onClick} = props;
|
|
15
|
+
export const GroupedIconButton = (props: GroupedIconButtonProps) => {
|
|
16
|
+
const {className = '', label, onClick, children} = props;
|
|
14
17
|
return (
|
|
15
18
|
<button
|
|
16
|
-
className={`deck-widget-icon-button ${className
|
|
19
|
+
className={`deck-widget-icon-button ${className}`}
|
|
17
20
|
type="button"
|
|
18
21
|
onClick={onClick}
|
|
19
22
|
title={label}
|
|
20
23
|
>
|
|
21
|
-
<div className="deck-widget-icon" />
|
|
24
|
+
{children ? children : <div className="deck-widget-icon" />}
|
|
22
25
|
</button>
|
|
23
26
|
);
|
|
24
27
|
};
|
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {ComponentChildren} from 'preact';
|
|
5
|
+
import type {ComponentChildren, JSX} from 'preact';
|
|
6
6
|
|
|
7
7
|
export type IconButtonProps = {
|
|
8
|
-
className
|
|
9
|
-
label
|
|
10
|
-
onClick
|
|
11
|
-
/** Optional icon or element to render inside the button */
|
|
8
|
+
className?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
onClick?: JSX.MouseEventHandler<HTMLButtonElement>;
|
|
12
11
|
children?: ComponentChildren;
|
|
13
12
|
};
|
|
14
13
|
|
|
15
14
|
/** Renders a button component with widget CSS */
|
|
16
15
|
export const IconButton = (props: IconButtonProps) => {
|
|
17
|
-
const {className, label, onClick, children} = props;
|
|
16
|
+
const {className = '', label, onClick, children} = props;
|
|
18
17
|
return (
|
|
19
18
|
<div className="deck-widget-button">
|
|
20
19
|
<button
|
|
@@ -1,31 +1,14 @@
|
|
|
1
1
|
import type {JSX} from 'preact';
|
|
2
2
|
import {useState, useRef, useEffect} from 'preact/hooks';
|
|
3
3
|
import {IconButton} from './icon-button';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
position: 'absolute',
|
|
7
|
-
top: '100%',
|
|
8
|
-
left: 0,
|
|
9
|
-
background: 'white',
|
|
10
|
-
border: '1px solid #ccc',
|
|
11
|
-
borderRadius: '4px',
|
|
12
|
-
marginTop: '4px',
|
|
13
|
-
zIndex: 100
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const MENU_ITEM_STYLE: JSX.CSSProperties = {
|
|
17
|
-
background: 'white',
|
|
18
|
-
border: 'none',
|
|
19
|
-
padding: '4px',
|
|
20
|
-
cursor: 'pointer',
|
|
21
|
-
pointerEvents: 'auto'
|
|
22
|
-
};
|
|
4
|
+
import {ButtonGroup} from './button-group';
|
|
5
|
+
import {GroupedIconButton} from './grouped-icon-button';
|
|
23
6
|
|
|
24
7
|
export type IconMenuProps<KeyType = string> = {
|
|
25
8
|
className: string;
|
|
26
|
-
icon?:
|
|
9
|
+
icon?: JSX.Element;
|
|
27
10
|
label?: string;
|
|
28
|
-
menuItems: {value: KeyType; icon:
|
|
11
|
+
menuItems: {value: KeyType; icon: JSX.Element; label: string}[];
|
|
29
12
|
initialItem: KeyType;
|
|
30
13
|
onItemSelected: (item: KeyType) => void;
|
|
31
14
|
};
|
|
@@ -61,27 +44,26 @@ export function IconMenu<KeyType extends string>(props: IconMenuProps<KeyType>)
|
|
|
61
44
|
|
|
62
45
|
const selectedMenuItem = props.menuItems.find(item => item.value === selectedItem);
|
|
63
46
|
const label = props.label || selectedMenuItem?.label || '';
|
|
64
|
-
const
|
|
47
|
+
const icon = (props.icon || selectedMenuItem?.icon)!;
|
|
65
48
|
|
|
66
49
|
return (
|
|
67
50
|
<div style={{position: 'relative', display: 'inline-block'}} ref={containerRef}>
|
|
68
51
|
<IconButton className={props.className} label={label} onClick={handleButtonClick}>
|
|
69
|
-
|
|
52
|
+
{icon}
|
|
70
53
|
</IconButton>
|
|
71
54
|
{menuOpen && (
|
|
72
|
-
<div
|
|
73
|
-
<
|
|
55
|
+
<div className="deck-widget-icon-menu">
|
|
56
|
+
<ButtonGroup orientation="vertical">
|
|
74
57
|
{props.menuItems.map(item => (
|
|
75
|
-
<
|
|
58
|
+
<GroupedIconButton
|
|
76
59
|
key={item.value}
|
|
77
|
-
|
|
78
|
-
title={item.label}
|
|
60
|
+
label={item.label}
|
|
79
61
|
onClick={() => handleSelectItem(item.value)}
|
|
80
62
|
>
|
|
81
63
|
{item.icon}
|
|
82
|
-
</
|
|
64
|
+
</GroupedIconButton>
|
|
83
65
|
))}
|
|
84
|
-
</
|
|
66
|
+
</ButtonGroup>
|
|
85
67
|
</div>
|
|
86
68
|
)}
|
|
87
69
|
</div>
|
package/src/loading-widget.tsx
CHANGED
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {WidgetPlacement, Layer} from '@deck.gl/core';
|
|
5
|
+
import type {WidgetPlacement, Layer, WidgetProps} from '@deck.gl/core';
|
|
6
6
|
import {render} from 'preact';
|
|
7
|
-
import {Widget
|
|
7
|
+
import {Widget} from '@deck.gl/core';
|
|
8
8
|
import {IconButton} from './lib/components/icon-button';
|
|
9
9
|
|
|
10
10
|
/** Properties for the LoadingWidget */
|
|
11
11
|
export type LoadingWidgetProps = WidgetProps & {
|
|
12
12
|
/** Widget positioning within the view. Default 'top-left'. */
|
|
13
13
|
placement?: WidgetPlacement;
|
|
14
|
+
/** View to attach to and interact with. Required when using multiple views */
|
|
15
|
+
viewId?: string | null;
|
|
14
16
|
/** Tooltip message when loading */
|
|
15
17
|
label?: string;
|
|
16
18
|
};
|
|
@@ -23,6 +25,7 @@ export class LoadingWidget extends Widget<LoadingWidgetProps> {
|
|
|
23
25
|
...Widget.defaultProps,
|
|
24
26
|
id: 'loading',
|
|
25
27
|
placement: 'top-left',
|
|
28
|
+
viewId: null,
|
|
26
29
|
label: 'Loading layer data'
|
|
27
30
|
};
|
|
28
31
|
|
|
@@ -32,11 +35,12 @@ export class LoadingWidget extends Widget<LoadingWidgetProps> {
|
|
|
32
35
|
|
|
33
36
|
constructor(props: LoadingWidgetProps = {}) {
|
|
34
37
|
super(props, LoadingWidget.defaultProps);
|
|
35
|
-
this.
|
|
38
|
+
this.setProps(this.props);
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
setProps(props: Partial<LoadingWidgetProps>) {
|
|
39
42
|
this.placement = props.placement ?? this.placement;
|
|
43
|
+
this.viewId = props.viewId ?? this.viewId;
|
|
40
44
|
super.setProps(props);
|
|
41
45
|
}
|
|
42
46
|
|
|
@@ -45,7 +49,7 @@ export class LoadingWidget extends Widget<LoadingWidgetProps> {
|
|
|
45
49
|
// TODO(ibgreen) - this should not be a button, but styling is so nested that it is easier to reuse this component.
|
|
46
50
|
this.loading && (
|
|
47
51
|
<IconButton
|
|
48
|
-
className="deck-widget-spinner
|
|
52
|
+
className="deck-widget-spinner"
|
|
49
53
|
label={this.props.label}
|
|
50
54
|
onClick={this.handleClick.bind(this)}
|
|
51
55
|
/>
|
|
@@ -55,7 +59,7 @@ export class LoadingWidget extends Widget<LoadingWidgetProps> {
|
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
onRedraw({layers}: {layers: Layer[]}): void {
|
|
58
|
-
const loading =
|
|
62
|
+
const loading = layers.some(layer => !layer.isLoaded);
|
|
59
63
|
if (loading !== this.loading) {
|
|
60
64
|
this.loading = loading;
|
|
61
65
|
this.updateHTML();
|