forked from visgl/hubble.gl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhooks.ts
More file actions
109 lines (100 loc) · 3.07 KB
/
hooks.ts
File metadata and controls
109 lines (100 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// hubble.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import {useState, useCallback, useMemo, RefObject} from 'react';
import {DeckAdapter, DeckAnimation, DeckAnimationConstructor} from '@hubble.gl/core';
import {MapboxOverlay as MapboxLayer} from '@deck.gl/mapbox';
import type {Layer, MapViewState} from '@deck.gl/core';
import type {DeckGLRef} from '@deck.gl/react';
import {MapRef} from 'react-map-gl';
export function useNextFrame() {
const [, updateState] = useState({});
return useCallback(() => updateState({}), []);
}
export function useDeckAdapter(
deckAnimation: DeckAnimation,
initialViewState: MapViewState = undefined
) {
const [layers, setLayers] = useState<Layer[]>([]);
const [cameraFrame, setCameraFrame] = useState<MapViewState>(initialViewState);
const adapter = useMemo(() => {
const a = new DeckAdapter({});
deckAnimation.setOnLayersUpdate(setLayers);
if (initialViewState) {
deckAnimation.setOnCameraUpdate(setCameraFrame);
}
a.animationManager.attachAnimation(deckAnimation);
deckAnimation.draw();
return a;
}, []);
return {adapter, layers, cameraFrame, setCameraFrame};
}
export function useDeckAnimation(params: DeckAnimationConstructor) {
return useMemo(() => new DeckAnimation(params), []);
}
export function useHubbleGl({
deckRef,
staticMapRef = undefined,
deckAnimation,
initialViewState = undefined
}: {
deckRef: RefObject<DeckGLRef>;
staticMapRef?: RefObject<MapRef>;
deckAnimation: DeckAnimation;
initialViewState?: MapViewState;
}) {
const deck = useMemo(() => deckRef.current && deckRef.current.deck, [deckRef.current]);
const nextFrame = useNextFrame();
const {adapter, layers, cameraFrame, setCameraFrame} = useDeckAdapter(
deckAnimation,
initialViewState
);
const onStaticMapLoad = useCallback(() => {
if (staticMapRef) {
const map = staticMapRef.current.getMap();
// If there aren't any layers, combine map and deck with a fake layer.
if (!layers.length) {
map.addLayer(new MapboxLayer({id: '%%blank-layer', ...deck}));
}
for (let i = 0; i < layers.length; i++) {
// Adds DeckGL layers to Mapbox so Mapbox can be the bottom layer. Removing this clips DeckGL layers
map.addLayer(new MapboxLayer({id: layers[i].id, ...deck}));
}
map.on('render', () => adapter.onAfterRender(nextFrame, map.areTilesLoaded()));
}
}, [deck]);
const [glContext, setGLContext] = useState<WebGLRenderingContext>();
if (!staticMapRef) {
return {
adapter,
cameraFrame,
setCameraFrame,
staticMapProps: {},
deckProps: adapter.getProps({
deck,
onNextFrame: nextFrame,
extraProps: {
layers
}
})
};
}
return {
adapter,
cameraFrame,
setCameraFrame,
onStaticMapLoad,
staticMapProps: {
gl: glContext,
onLoad: onStaticMapLoad,
preventStyleDiffing: true
},
deckProps: adapter.getProps({
deck,
extraProps: {
onWebGLInitialized: setGLContext,
layers
}
})
};
}