@lugg/maps 0.2.0-alpha.3 → 0.2.0-alpha.30
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/README.md +21 -3
- package/android/src/main/java/com/luggmaps/LuggMapView.kt +265 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +75 -36
- package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +6 -5
- package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +136 -14
- package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +21 -0
- package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
- package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +16 -0
- package/android/src/main/java/com/luggmaps/LuggPolylineViewManager.kt +22 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +251 -241
- package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +55 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +163 -52
- package/ios/LuggMapView.h +9 -0
- package/ios/LuggMapView.mm +312 -0
- package/ios/LuggMarkerView.h +9 -0
- package/ios/LuggMarkerView.mm +79 -0
- package/ios/LuggPolylineView.h +4 -0
- package/ios/LuggPolylineView.mm +23 -0
- package/ios/core/AppleMapProvider.h +15 -0
- package/ios/core/AppleMapProvider.mm +664 -0
- package/ios/core/GMSPolylineAnimator.h +3 -0
- package/ios/core/GMSPolylineAnimator.m +175 -40
- package/ios/core/GoogleMapProvider.h +13 -0
- package/ios/core/GoogleMapProvider.mm +513 -0
- package/ios/core/MKPolylineAnimator.h +4 -0
- package/ios/core/MKPolylineAnimator.m +224 -68
- package/ios/core/MapProviderDelegate.h +72 -0
- package/ios/core/PolylineAnimatorBase.h +24 -1
- package/ios/core/PolylineAnimatorBase.m +82 -19
- package/ios/extensions/MKMapView+Zoom.h +2 -0
- package/ios/extensions/MKMapView+Zoom.m +14 -4
- package/lib/module/MapProvider.js +13 -0
- package/lib/module/MapProvider.js.map +1 -0
- package/lib/module/MapProvider.types.js +4 -0
- package/lib/module/MapProvider.types.js.map +1 -0
- package/lib/module/MapProvider.web.js +20 -0
- package/lib/module/MapProvider.web.js.map +1 -0
- package/lib/module/MapView.js +29 -16
- package/lib/module/MapView.js.map +1 -1
- package/lib/module/MapView.web.js +290 -0
- package/lib/module/MapView.web.js.map +1 -0
- package/lib/module/components/Marker.js +19 -2
- package/lib/module/components/Marker.js.map +1 -1
- package/lib/module/components/Marker.web.js +33 -0
- package/lib/module/components/Marker.web.js.map +1 -0
- package/lib/module/components/Polyline.js +17 -4
- package/lib/module/components/Polyline.js.map +1 -1
- package/lib/module/components/Polyline.web.js +229 -0
- package/lib/module/components/Polyline.web.js.map +1 -0
- package/lib/module/components/index.js +2 -2
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/index.web.js +5 -0
- package/lib/module/components/index.web.js.map +1 -0
- package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +19 -7
- package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +7 -1
- package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/lib/module/index.js +4 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +7 -0
- package/lib/module/index.web.js.map +1 -0
- package/lib/typescript/src/MapProvider.d.ts +8 -0
- package/lib/typescript/src/MapProvider.d.ts.map +1 -0
- package/lib/typescript/src/MapProvider.types.d.ts +16 -0
- package/lib/typescript/src/MapProvider.types.d.ts.map +1 -0
- package/lib/typescript/src/MapProvider.web.d.ts +11 -0
- package/lib/typescript/src/MapProvider.web.d.ts.map +1 -0
- package/lib/typescript/src/MapView.d.ts +4 -4
- package/lib/typescript/src/MapView.d.ts.map +1 -1
- package/lib/typescript/src/MapView.types.d.ts +23 -7
- package/lib/typescript/src/MapView.types.d.ts.map +1 -1
- package/lib/typescript/src/MapView.web.d.ts +3 -0
- package/lib/typescript/src/MapView.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.d.ts +25 -1
- package/lib/typescript/src/components/Marker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.web.d.ts +3 -0
- package/lib/typescript/src/components/Marker.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Polyline.d.ts +36 -1
- package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
- package/lib/typescript/src/components/Polyline.web.d.ts +3 -0
- package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +4 -2
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/components/index.web.d.ts +5 -0
- package/lib/typescript/src/components/index.web.d.ts.map +1 -0
- package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +8 -4
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +4 -1
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts +7 -0
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +8 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +10 -0
- package/lib/typescript/src/index.web.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +4 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +17 -3
- package/src/MapProvider.tsx +10 -0
- package/src/MapProvider.types.ts +16 -0
- package/src/MapProvider.web.tsx +14 -0
- package/src/MapView.tsx +28 -26
- package/src/MapView.types.ts +24 -7
- package/src/MapView.web.tsx +364 -0
- package/src/components/Marker.tsx +50 -4
- package/src/components/Marker.web.tsx +33 -0
- package/src/components/Polyline.tsx +51 -2
- package/src/components/Polyline.web.tsx +287 -0
- package/src/components/index.ts +8 -2
- package/src/components/index.web.ts +4 -0
- package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +19 -7
- package/src/fabric/LuggMarkerViewNativeComponent.ts +7 -1
- package/src/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/src/index.ts +18 -2
- package/src/index.web.ts +20 -0
- package/src/types.ts +5 -0
- package/ios/LuggAppleMapView.h +0 -16
- package/ios/LuggAppleMapView.mm +0 -580
- package/ios/LuggGoogleMapView.h +0 -13
- package/ios/LuggGoogleMapView.mm +0 -454
- package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
- package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
- package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
- package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
- package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useId,
|
|
6
|
+
useImperativeHandle,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
type CSSProperties,
|
|
10
|
+
} from 'react';
|
|
11
|
+
import type { NativeSyntheticEvent } from 'react-native';
|
|
12
|
+
import { View } from 'react-native';
|
|
13
|
+
import {
|
|
14
|
+
ColorScheme,
|
|
15
|
+
Map,
|
|
16
|
+
useMap,
|
|
17
|
+
type MapCameraChangedEvent,
|
|
18
|
+
type MapEvent,
|
|
19
|
+
} from '@vis.gl/react-google-maps';
|
|
20
|
+
import { Marker } from './components/Marker.web';
|
|
21
|
+
import { MapContext } from './MapProvider.web';
|
|
22
|
+
|
|
23
|
+
import type {
|
|
24
|
+
MapViewProps,
|
|
25
|
+
MapViewRef,
|
|
26
|
+
MoveCameraOptions,
|
|
27
|
+
FitCoordinatesOptions,
|
|
28
|
+
SetEdgeInsetsOptions,
|
|
29
|
+
CameraEventPayload,
|
|
30
|
+
} from './MapView.types';
|
|
31
|
+
import type { Coordinate, EdgeInsets } from './types';
|
|
32
|
+
|
|
33
|
+
const createSyntheticEvent = <T,>(nativeEvent: T): NativeSyntheticEvent<T> =>
|
|
34
|
+
({
|
|
35
|
+
nativeEvent,
|
|
36
|
+
currentTarget: null,
|
|
37
|
+
target: null,
|
|
38
|
+
bubbles: false,
|
|
39
|
+
cancelable: false,
|
|
40
|
+
defaultPrevented: false,
|
|
41
|
+
eventPhase: 0,
|
|
42
|
+
isTrusted: true,
|
|
43
|
+
preventDefault: () => {},
|
|
44
|
+
stopPropagation: () => {},
|
|
45
|
+
isDefaultPrevented: () => false,
|
|
46
|
+
isPropagationStopped: () => false,
|
|
47
|
+
persist: () => {},
|
|
48
|
+
timeStamp: Date.now(),
|
|
49
|
+
type: '',
|
|
50
|
+
} as unknown as NativeSyntheticEvent<T>);
|
|
51
|
+
|
|
52
|
+
const userLocationDotStyle: CSSProperties = {
|
|
53
|
+
width: 16,
|
|
54
|
+
height: 16,
|
|
55
|
+
backgroundColor: '#4285F4',
|
|
56
|
+
border: '2px solid white',
|
|
57
|
+
borderRadius: '50%',
|
|
58
|
+
boxShadow: '0 1px 4px rgba(0,0,0,0.3)',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
function UserLocationMarker({ enabled }: { enabled?: boolean }) {
|
|
62
|
+
const [coordinate, setCoordinate] = useState<Coordinate | null>(null);
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (!enabled) {
|
|
66
|
+
setCoordinate(null);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let watchId: number | null = null;
|
|
71
|
+
|
|
72
|
+
const updateLocation = (position: GeolocationPosition) => {
|
|
73
|
+
setCoordinate({
|
|
74
|
+
latitude: position.coords.latitude,
|
|
75
|
+
longitude: position.coords.longitude,
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
navigator.geolocation.getCurrentPosition(updateLocation, () => {});
|
|
80
|
+
watchId = navigator.geolocation.watchPosition(updateLocation, () => {});
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
if (watchId !== null) {
|
|
84
|
+
navigator.geolocation.clearWatch(watchId);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}, [enabled]);
|
|
88
|
+
|
|
89
|
+
if (!coordinate) return null;
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<Marker coordinate={coordinate} anchor={{ x: 0.5, y: 0.5 }}>
|
|
93
|
+
<div style={userLocationDotStyle} />
|
|
94
|
+
</Marker>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const MapView = forwardRef<MapViewRef, MapViewProps>(function MapView(
|
|
99
|
+
props,
|
|
100
|
+
ref
|
|
101
|
+
) {
|
|
102
|
+
const {
|
|
103
|
+
mapId = 'DEMO_MAP_ID',
|
|
104
|
+
initialCoordinate,
|
|
105
|
+
initialZoom = 10,
|
|
106
|
+
minZoom,
|
|
107
|
+
maxZoom,
|
|
108
|
+
zoomEnabled = true,
|
|
109
|
+
scrollEnabled = true,
|
|
110
|
+
pitchEnabled = true,
|
|
111
|
+
edgeInsets,
|
|
112
|
+
userLocationEnabled,
|
|
113
|
+
theme = 'system',
|
|
114
|
+
onCameraMove,
|
|
115
|
+
onCameraIdle,
|
|
116
|
+
onReady,
|
|
117
|
+
children,
|
|
118
|
+
style,
|
|
119
|
+
} = props;
|
|
120
|
+
|
|
121
|
+
const id = useId();
|
|
122
|
+
const map = useMap(id);
|
|
123
|
+
const containerRef = useRef<View>(null);
|
|
124
|
+
const readyFired = useRef(false);
|
|
125
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
126
|
+
const wasGesture = useRef(false);
|
|
127
|
+
const prevEdgeInsets = useRef(edgeInsets);
|
|
128
|
+
|
|
129
|
+
const offsetCenter = useCallback(
|
|
130
|
+
(coord: Coordinate, zoom: number, insets?: EdgeInsets, reverse = false) => {
|
|
131
|
+
const p = insets ?? prevEdgeInsets.current;
|
|
132
|
+
if (!p) {
|
|
133
|
+
return { lat: coord.latitude, lng: coord.longitude };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const dir = reverse ? -1 : 1;
|
|
137
|
+
const scale = 256 * Math.pow(2, zoom);
|
|
138
|
+
const offsetX = (dir * ((p.right ?? 0) - (p.left ?? 0))) / 2;
|
|
139
|
+
const offsetY = (dir * ((p.bottom ?? 0) - (p.top ?? 0))) / 2;
|
|
140
|
+
|
|
141
|
+
const latRad = (coord.latitude * Math.PI) / 180;
|
|
142
|
+
const x = ((coord.longitude + 180) / 360) * scale + offsetX;
|
|
143
|
+
const y =
|
|
144
|
+
((1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) /
|
|
145
|
+
2) *
|
|
146
|
+
scale +
|
|
147
|
+
offsetY;
|
|
148
|
+
|
|
149
|
+
const lng = (x / scale) * 360 - 180;
|
|
150
|
+
const lat =
|
|
151
|
+
(Math.atan(Math.sinh(Math.PI * (1 - (2 * y) / scale))) * 180) / Math.PI;
|
|
152
|
+
|
|
153
|
+
return { lat, lng };
|
|
154
|
+
},
|
|
155
|
+
[]
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const applyEdgeInsets = useCallback(
|
|
159
|
+
(newEdgeInsets: EdgeInsets, duration?: number) => {
|
|
160
|
+
if (!map) return;
|
|
161
|
+
|
|
162
|
+
const prev = prevEdgeInsets.current;
|
|
163
|
+
const center = map.getCenter();
|
|
164
|
+
const zoom = map.getZoom() ?? initialZoom;
|
|
165
|
+
|
|
166
|
+
if (center) {
|
|
167
|
+
const logicalCenter = offsetCenter(
|
|
168
|
+
{ latitude: center.lat(), longitude: center.lng() },
|
|
169
|
+
zoom,
|
|
170
|
+
prev,
|
|
171
|
+
true
|
|
172
|
+
);
|
|
173
|
+
const newCenter = offsetCenter(
|
|
174
|
+
{ latitude: logicalCenter.lat, longitude: logicalCenter.lng },
|
|
175
|
+
zoom,
|
|
176
|
+
newEdgeInsets,
|
|
177
|
+
false
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
if (duration === 0) {
|
|
181
|
+
map.moveCamera({ center: newCenter, zoom });
|
|
182
|
+
} else {
|
|
183
|
+
map.panTo(newCenter);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
prevEdgeInsets.current = newEdgeInsets;
|
|
188
|
+
},
|
|
189
|
+
[map, initialZoom, offsetCenter]
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
useImperativeHandle(
|
|
193
|
+
ref,
|
|
194
|
+
() => ({
|
|
195
|
+
moveCamera(coordinate: Coordinate, options?: MoveCameraOptions) {
|
|
196
|
+
if (!map) return;
|
|
197
|
+
|
|
198
|
+
const { zoom = 0, duration = -1 } = options ?? {};
|
|
199
|
+
const targetZoom = zoom || map.getZoom() || initialZoom;
|
|
200
|
+
const center = offsetCenter(coordinate, targetZoom, undefined, false);
|
|
201
|
+
|
|
202
|
+
if (duration === 0) {
|
|
203
|
+
map.moveCamera({ center, zoom: targetZoom });
|
|
204
|
+
} else {
|
|
205
|
+
const currentZoom = map.getZoom();
|
|
206
|
+
const zoomChanged = zoom !== 0 && zoom !== currentZoom;
|
|
207
|
+
|
|
208
|
+
if (zoomChanged) {
|
|
209
|
+
map.setZoom(zoom);
|
|
210
|
+
}
|
|
211
|
+
map.panTo(center);
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
fitCoordinates(
|
|
216
|
+
coordinates: Coordinate[],
|
|
217
|
+
options?: FitCoordinatesOptions
|
|
218
|
+
) {
|
|
219
|
+
const first = coordinates[0];
|
|
220
|
+
if (!map || !first) return;
|
|
221
|
+
|
|
222
|
+
const { padding: fitPadding, duration = -1 } = options ?? {};
|
|
223
|
+
|
|
224
|
+
if (coordinates.length === 1) {
|
|
225
|
+
this.moveCamera(first, { zoom: initialZoom, duration });
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const bounds = new google.maps.LatLngBounds();
|
|
230
|
+
coordinates.forEach((coord) => {
|
|
231
|
+
bounds.extend({ lat: coord.latitude, lng: coord.longitude });
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const ei = prevEdgeInsets.current;
|
|
235
|
+
map.fitBounds(bounds, {
|
|
236
|
+
top: (ei?.top ?? 0) + (fitPadding?.top ?? 0),
|
|
237
|
+
left: (ei?.left ?? 0) + (fitPadding?.left ?? 0),
|
|
238
|
+
bottom: (ei?.bottom ?? 0) + (fitPadding?.bottom ?? 0),
|
|
239
|
+
right: (ei?.right ?? 0) + (fitPadding?.right ?? 0),
|
|
240
|
+
});
|
|
241
|
+
},
|
|
242
|
+
|
|
243
|
+
setEdgeInsets(newEdgeInsets: EdgeInsets, options?: SetEdgeInsetsOptions) {
|
|
244
|
+
applyEdgeInsets(newEdgeInsets, options?.duration);
|
|
245
|
+
},
|
|
246
|
+
}),
|
|
247
|
+
[map, initialZoom, offsetCenter, applyEdgeInsets]
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
useEffect(() => {
|
|
251
|
+
if (map && !readyFired.current) {
|
|
252
|
+
readyFired.current = true;
|
|
253
|
+
onReady?.();
|
|
254
|
+
}
|
|
255
|
+
}, [map, onReady]);
|
|
256
|
+
|
|
257
|
+
useEffect(() => {
|
|
258
|
+
if (!map || !edgeInsets) return;
|
|
259
|
+
|
|
260
|
+
const prev = prevEdgeInsets.current;
|
|
261
|
+
const changed =
|
|
262
|
+
prev?.top !== edgeInsets.top ||
|
|
263
|
+
prev?.left !== edgeInsets.left ||
|
|
264
|
+
prev?.bottom !== edgeInsets.bottom ||
|
|
265
|
+
prev?.right !== edgeInsets.right;
|
|
266
|
+
|
|
267
|
+
if (changed) {
|
|
268
|
+
applyEdgeInsets(edgeInsets);
|
|
269
|
+
}
|
|
270
|
+
}, [map, edgeInsets, applyEdgeInsets]);
|
|
271
|
+
|
|
272
|
+
const handleDragStart = () => {
|
|
273
|
+
setIsDragging(true);
|
|
274
|
+
wasGesture.current = true;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const handleDragEnd = () => {
|
|
278
|
+
setIsDragging(false);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const handleCameraChanged = (event: MapCameraChangedEvent) => {
|
|
282
|
+
const logicalCenter = offsetCenter(
|
|
283
|
+
{ latitude: event.detail.center.lat, longitude: event.detail.center.lng },
|
|
284
|
+
event.detail.zoom,
|
|
285
|
+
undefined,
|
|
286
|
+
true
|
|
287
|
+
);
|
|
288
|
+
const payload: CameraEventPayload = {
|
|
289
|
+
coordinate: {
|
|
290
|
+
latitude: logicalCenter.lat,
|
|
291
|
+
longitude: logicalCenter.lng,
|
|
292
|
+
},
|
|
293
|
+
zoom: event.detail.zoom,
|
|
294
|
+
gesture: isDragging,
|
|
295
|
+
};
|
|
296
|
+
onCameraMove?.(createSyntheticEvent(payload));
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const handleIdle = (event: MapEvent) => {
|
|
300
|
+
const center = event.map.getCenter();
|
|
301
|
+
const zoom = event.map.getZoom() ?? 0;
|
|
302
|
+
const logicalCenter = offsetCenter(
|
|
303
|
+
{ latitude: center?.lat() ?? 0, longitude: center?.lng() ?? 0 },
|
|
304
|
+
zoom,
|
|
305
|
+
undefined,
|
|
306
|
+
true
|
|
307
|
+
);
|
|
308
|
+
const payload: CameraEventPayload = {
|
|
309
|
+
coordinate: {
|
|
310
|
+
latitude: logicalCenter.lat,
|
|
311
|
+
longitude: logicalCenter.lng,
|
|
312
|
+
},
|
|
313
|
+
zoom,
|
|
314
|
+
gesture: wasGesture.current,
|
|
315
|
+
};
|
|
316
|
+
onCameraIdle?.(createSyntheticEvent(payload));
|
|
317
|
+
wasGesture.current = false;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const gestureHandling =
|
|
321
|
+
scrollEnabled === false && zoomEnabled === false
|
|
322
|
+
? 'none'
|
|
323
|
+
: scrollEnabled === false
|
|
324
|
+
? 'cooperative'
|
|
325
|
+
: 'auto';
|
|
326
|
+
|
|
327
|
+
const colorScheme =
|
|
328
|
+
theme === 'dark'
|
|
329
|
+
? ColorScheme.DARK
|
|
330
|
+
: theme === 'light'
|
|
331
|
+
? ColorScheme.LIGHT
|
|
332
|
+
: ColorScheme.FOLLOW_SYSTEM;
|
|
333
|
+
|
|
334
|
+
const defaultCenter = initialCoordinate
|
|
335
|
+
? { lat: initialCoordinate.latitude, lng: initialCoordinate.longitude }
|
|
336
|
+
: undefined;
|
|
337
|
+
|
|
338
|
+
return (
|
|
339
|
+
<MapContext.Provider value={{ map, isDragging }}>
|
|
340
|
+
<View ref={containerRef} style={style}>
|
|
341
|
+
<Map
|
|
342
|
+
id={id}
|
|
343
|
+
mapId={mapId}
|
|
344
|
+
defaultCenter={defaultCenter}
|
|
345
|
+
defaultZoom={initialZoom}
|
|
346
|
+
minZoom={minZoom}
|
|
347
|
+
maxZoom={maxZoom}
|
|
348
|
+
gestureHandling={gestureHandling}
|
|
349
|
+
colorScheme={colorScheme}
|
|
350
|
+
disableDefaultUI
|
|
351
|
+
isFractionalZoomEnabled
|
|
352
|
+
tilt={pitchEnabled === false ? 0 : undefined}
|
|
353
|
+
onDragstart={handleDragStart}
|
|
354
|
+
onDragend={handleDragEnd}
|
|
355
|
+
onCameraChanged={handleCameraChanged}
|
|
356
|
+
onIdle={handleIdle}
|
|
357
|
+
>
|
|
358
|
+
<UserLocationMarker enabled={userLocationEnabled} />
|
|
359
|
+
{children}
|
|
360
|
+
</Map>
|
|
361
|
+
</View>
|
|
362
|
+
</MapContext.Provider>
|
|
363
|
+
);
|
|
364
|
+
});
|
|
@@ -25,25 +25,71 @@ export interface MarkerProps {
|
|
|
25
25
|
* Anchor point for custom marker views
|
|
26
26
|
*/
|
|
27
27
|
anchor?: Point;
|
|
28
|
+
/**
|
|
29
|
+
* Z-index for marker ordering. Higher values render on top.
|
|
30
|
+
*/
|
|
31
|
+
zIndex?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Rotation angle in degrees clockwise from north.
|
|
34
|
+
* @default 0
|
|
35
|
+
*/
|
|
36
|
+
rotate?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Scale factor for the marker.
|
|
39
|
+
* @default 1
|
|
40
|
+
*/
|
|
41
|
+
scale?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Rasterize custom marker view to bitmap for better performance.
|
|
44
|
+
* Set to false if you need live view updates (e.g., animations).
|
|
45
|
+
* @platform ios, android
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
rasterize?: boolean;
|
|
28
49
|
/**
|
|
29
50
|
* Custom marker view
|
|
30
51
|
*/
|
|
31
52
|
children?: ReactNode;
|
|
32
53
|
}
|
|
33
54
|
|
|
34
|
-
export class Marker extends React.
|
|
55
|
+
export class Marker extends React.PureComponent<MarkerProps> {
|
|
56
|
+
private getStyle(zIndex: number | undefined) {
|
|
57
|
+
if (zIndex == null) return styles.marker;
|
|
58
|
+
if (zIndex !== this._cachedZIndex) {
|
|
59
|
+
this._cachedZIndex = zIndex;
|
|
60
|
+
this._cachedStyle = [{ zIndex }, styles.marker];
|
|
61
|
+
}
|
|
62
|
+
return this._cachedStyle!;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private _cachedZIndex: number | undefined;
|
|
66
|
+
private _cachedStyle: any;
|
|
67
|
+
|
|
35
68
|
render() {
|
|
36
|
-
const {
|
|
37
|
-
|
|
69
|
+
const {
|
|
70
|
+
name,
|
|
71
|
+
coordinate,
|
|
72
|
+
title,
|
|
73
|
+
description,
|
|
74
|
+
anchor,
|
|
75
|
+
zIndex,
|
|
76
|
+
rotate = 0,
|
|
77
|
+
scale = 1,
|
|
78
|
+
rasterize = true,
|
|
79
|
+
children,
|
|
80
|
+
} = this.props;
|
|
38
81
|
|
|
39
82
|
return (
|
|
40
83
|
<LuggMarkerViewNativeComponent
|
|
41
|
-
style={
|
|
84
|
+
style={this.getStyle(zIndex)}
|
|
42
85
|
name={name}
|
|
43
86
|
coordinate={coordinate}
|
|
44
87
|
title={title}
|
|
45
88
|
description={description}
|
|
46
89
|
anchor={anchor}
|
|
90
|
+
rotate={rotate}
|
|
91
|
+
scale={scale}
|
|
92
|
+
rasterize={rasterize}
|
|
47
93
|
>
|
|
48
94
|
{children}
|
|
49
95
|
</LuggMarkerViewNativeComponent>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AdvancedMarker } from '@vis.gl/react-google-maps';
|
|
2
|
+
import type { MarkerProps } from './Marker';
|
|
3
|
+
|
|
4
|
+
const toWebAnchor = (value: number) => `-${value * 100}%`;
|
|
5
|
+
|
|
6
|
+
export function Marker({
|
|
7
|
+
coordinate,
|
|
8
|
+
title,
|
|
9
|
+
anchor,
|
|
10
|
+
zIndex,
|
|
11
|
+
rotate,
|
|
12
|
+
scale,
|
|
13
|
+
children,
|
|
14
|
+
}: MarkerProps) {
|
|
15
|
+
const transforms: string[] = [];
|
|
16
|
+
if (rotate) transforms.push(`rotate(${rotate}deg)`);
|
|
17
|
+
if (scale && scale !== 1) transforms.push(`scale(${scale})`);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<AdvancedMarker
|
|
21
|
+
position={{ lat: coordinate.latitude, lng: coordinate.longitude }}
|
|
22
|
+
title={title}
|
|
23
|
+
zIndex={zIndex}
|
|
24
|
+
anchorLeft={anchor ? toWebAnchor(anchor.x) : undefined}
|
|
25
|
+
anchorTop={anchor ? toWebAnchor(anchor.y) : undefined}
|
|
26
|
+
style={
|
|
27
|
+
transforms.length > 0 ? { transform: transforms.join(' ') } : undefined
|
|
28
|
+
}
|
|
29
|
+
>
|
|
30
|
+
{children}
|
|
31
|
+
</AdvancedMarker>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -4,6 +4,32 @@ import { StyleSheet } from 'react-native';
|
|
|
4
4
|
import LuggPolylineViewNativeComponent from '../fabric/LuggPolylineViewNativeComponent';
|
|
5
5
|
import type { Coordinate } from '../types';
|
|
6
6
|
|
|
7
|
+
export type PolylineEasing = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
|
|
8
|
+
|
|
9
|
+
export interface PolylineAnimatedOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Animation duration in milliseconds
|
|
12
|
+
* @default 2150
|
|
13
|
+
*/
|
|
14
|
+
duration?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Easing function for the animation
|
|
17
|
+
* @default 'linear'
|
|
18
|
+
*/
|
|
19
|
+
easing?: PolylineEasing;
|
|
20
|
+
/**
|
|
21
|
+
* Portion of the line visible as trail (0-1)
|
|
22
|
+
* 1.0 = full snake effect, 0.2 = short worm
|
|
23
|
+
* @default 1.0
|
|
24
|
+
*/
|
|
25
|
+
trailLength?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Delay before animation starts in milliseconds
|
|
28
|
+
* @default 0
|
|
29
|
+
*/
|
|
30
|
+
delay?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
7
33
|
export interface PolylineProps {
|
|
8
34
|
/**
|
|
9
35
|
* Array of coordinates forming the polyline
|
|
@@ -21,24 +47,47 @@ export interface PolylineProps {
|
|
|
21
47
|
* Animate the polyline with a snake effect
|
|
22
48
|
*/
|
|
23
49
|
animated?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Animation configuration options
|
|
52
|
+
*/
|
|
53
|
+
animatedOptions?: PolylineAnimatedOptions;
|
|
54
|
+
/**
|
|
55
|
+
* Z-index for layering polylines
|
|
56
|
+
*/
|
|
57
|
+
zIndex?: number;
|
|
24
58
|
}
|
|
25
59
|
|
|
26
|
-
export class Polyline extends React.
|
|
60
|
+
export class Polyline extends React.PureComponent<PolylineProps> {
|
|
61
|
+
private getStyle(zIndex: number | undefined) {
|
|
62
|
+
if (zIndex == null) return styles.polyline;
|
|
63
|
+
if (zIndex !== this._cachedZIndex) {
|
|
64
|
+
this._cachedZIndex = zIndex;
|
|
65
|
+
this._cachedStyle = [{ zIndex }, styles.polyline];
|
|
66
|
+
}
|
|
67
|
+
return this._cachedStyle!;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private _cachedZIndex: number | undefined;
|
|
71
|
+
private _cachedStyle: any;
|
|
72
|
+
|
|
27
73
|
render() {
|
|
28
74
|
const {
|
|
29
75
|
coordinates,
|
|
30
76
|
strokeColors,
|
|
31
77
|
strokeWidth,
|
|
32
78
|
animated = false,
|
|
79
|
+
animatedOptions,
|
|
80
|
+
zIndex,
|
|
33
81
|
} = this.props;
|
|
34
82
|
|
|
35
83
|
return (
|
|
36
84
|
<LuggPolylineViewNativeComponent
|
|
37
|
-
style={
|
|
85
|
+
style={this.getStyle(zIndex)}
|
|
38
86
|
coordinates={coordinates}
|
|
39
87
|
strokeColors={strokeColors}
|
|
40
88
|
strokeWidth={strokeWidth}
|
|
41
89
|
animated={animated}
|
|
90
|
+
animatedOptions={animatedOptions}
|
|
42
91
|
/>
|
|
43
92
|
);
|
|
44
93
|
}
|