@lugg/maps 0.2.0-alpha.8 → 1.0.0-beta.0
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 +20 -19
- package/android/src/main/java/com/luggmaps/LuggMapView.kt +290 -0
- package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +99 -36
- package/android/src/main/java/com/luggmaps/LuggMapWrapperView.kt +13 -5
- package/android/src/main/java/com/luggmaps/LuggMarkerView.kt +157 -13
- package/android/src/main/java/com/luggmaps/LuggMarkerViewManager.kt +28 -0
- package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
- package/android/src/main/java/com/luggmaps/LuggPolygonView.kt +85 -0
- package/android/src/main/java/com/luggmaps/LuggPolygonViewManager.kt +100 -0
- 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/core/GoogleMapProvider.kt +698 -0
- package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +60 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +89 -24
- package/android/src/main/java/com/luggmaps/events/LongPressEvent.kt +29 -0
- package/android/src/main/java/com/luggmaps/events/MarkerDragEvent.kt +41 -0
- package/android/src/main/java/com/luggmaps/events/MarkerPressEvent.kt +34 -0
- package/android/src/main/java/com/luggmaps/events/PolygonPressEvent.kt +12 -0
- package/android/src/main/java/com/luggmaps/events/PressEvent.kt +29 -0
- package/ios/LuggMapView.h +9 -0
- package/ios/LuggMapView.mm +343 -0
- package/ios/LuggMarkerView.h +13 -0
- package/ios/LuggMarkerView.mm +119 -0
- package/ios/LuggPolygonView.h +31 -0
- package/ios/LuggPolygonView.mm +151 -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 +1029 -0
- package/ios/core/GMSPolylineAnimator.h +3 -0
- package/ios/core/GMSPolylineAnimator.m +101 -15
- package/ios/core/GoogleMapProvider.h +13 -0
- package/ios/core/GoogleMapProvider.mm +689 -0
- package/ios/core/MKPolylineAnimator.h +4 -0
- package/ios/core/MKPolylineAnimator.m +167 -42
- package/ios/core/MapProviderDelegate.h +84 -0
- package/ios/core/PolylineAnimatorBase.h +24 -1
- package/ios/core/PolylineAnimatorBase.m +82 -19
- package/ios/events/LongPressEvent.h +29 -0
- package/ios/events/MarkerDragEvent.h +69 -0
- package/ios/events/MarkerPressEvent.h +29 -0
- package/ios/events/PolygonPressEvent.h +20 -0
- package/ios/events/PressEvent.h +29 -0
- package/ios/extensions/MKMapView+Zoom.h +2 -0
- package/ios/extensions/MKMapView+Zoom.m +14 -4
- package/lib/module/MapProvider.js +2 -4
- package/lib/module/MapProvider.js.map +1 -1
- package/lib/module/MapProvider.web.js +12 -7
- package/lib/module/MapProvider.web.js.map +1 -1
- package/lib/module/MapView.js +33 -16
- package/lib/module/MapView.js.map +1 -1
- package/lib/module/MapView.web.js +315 -217
- package/lib/module/MapView.web.js.map +1 -1
- package/lib/module/components/GeoJson.js +159 -0
- package/lib/module/components/GeoJson.js.map +1 -0
- package/lib/module/components/GeoJson.types.js +4 -0
- package/lib/module/components/GeoJson.types.js.map +1 -0
- package/lib/module/components/Marker.js +28 -4
- package/lib/module/components/Marker.js.map +1 -1
- package/lib/module/components/Marker.types.js +4 -0
- package/lib/module/components/Marker.types.js.map +1 -0
- package/lib/module/components/Marker.web.js +98 -27
- package/lib/module/components/Marker.web.js.map +1 -1
- package/lib/module/components/Polygon.js +46 -0
- package/lib/module/components/Polygon.js.map +1 -0
- package/lib/module/components/Polygon.types.js +4 -0
- package/lib/module/components/Polygon.types.js.map +1 -0
- package/lib/module/components/Polygon.web.js +87 -0
- package/lib/module/components/Polygon.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.types.js +4 -0
- package/lib/module/components/Polyline.types.js.map +1 -0
- package/lib/module/components/Polyline.web.js +108 -31
- package/lib/module/components/Polyline.web.js.map +1 -1
- package/lib/module/components/index.js +4 -2
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/components/index.web.js +2 -0
- package/lib/module/components/index.web.js.map +1 -1
- package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +43 -7
- package/lib/module/fabric/LuggMarkerViewNativeComponent.ts +49 -1
- package/lib/module/fabric/LuggPolygonViewNativeComponent.ts +25 -0
- package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/lib/module/index.js +4 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +4 -1
- package/lib/module/index.web.js.map +1 -1
- package/lib/typescript/src/MapProvider.d.ts +1 -1
- package/lib/typescript/src/MapProvider.d.ts.map +1 -1
- package/lib/typescript/src/MapProvider.web.d.ts +17 -1
- package/lib/typescript/src/MapProvider.web.d.ts.map +1 -1
- 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 +35 -9
- package/lib/typescript/src/MapView.types.d.ts.map +1 -1
- package/lib/typescript/src/MapView.web.d.ts +2 -11
- package/lib/typescript/src/MapView.web.d.ts.map +1 -1
- package/lib/typescript/src/components/GeoJson.d.ts +4 -0
- package/lib/typescript/src/components/GeoJson.d.ts.map +1 -0
- package/lib/typescript/src/components/GeoJson.types.d.ts +79 -0
- package/lib/typescript/src/components/GeoJson.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.d.ts +6 -33
- package/lib/typescript/src/components/Marker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.types.d.ts +74 -0
- package/lib/typescript/src/components/Marker.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Marker.web.d.ts +2 -5
- package/lib/typescript/src/components/Marker.web.d.ts.map +1 -1
- package/lib/typescript/src/components/Polygon.d.ts +10 -0
- package/lib/typescript/src/components/Polygon.d.ts.map +1 -0
- package/lib/typescript/src/components/Polygon.types.d.ts +33 -0
- package/lib/typescript/src/components/Polygon.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Polygon.web.d.ts +3 -0
- package/lib/typescript/src/components/Polygon.web.d.ts.map +1 -0
- package/lib/typescript/src/components/Polyline.d.ts +6 -21
- package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
- package/lib/typescript/src/components/Polyline.types.d.ts +53 -0
- package/lib/typescript/src/components/Polyline.types.d.ts.map +1 -0
- package/lib/typescript/src/components/Polyline.web.d.ts +2 -5
- package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -1
- package/lib/typescript/src/components/index.d.ts +8 -2
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/components/index.web.d.ts +6 -2
- package/lib/typescript/src/components/index.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +30 -4
- package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts +45 -1
- package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggPolygonViewNativeComponent.d.ts +18 -0
- package/lib/typescript/src/fabric/LuggPolygonViewNativeComponent.d.ts.map +1 -0
- 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 +11 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +9 -1
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +11 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +10 -9
- package/src/MapProvider.tsx +1 -3
- package/src/MapProvider.web.tsx +12 -3
- package/src/MapView.tsx +32 -26
- package/src/MapView.types.ts +43 -9
- package/src/MapView.web.tsx +376 -244
- package/src/components/GeoJson.tsx +221 -0
- package/src/components/GeoJson.types.ts +107 -0
- package/src/components/Marker.tsx +45 -36
- package/src/components/Marker.types.ts +75 -0
- package/src/components/Marker.web.tsx +116 -28
- package/src/components/Polygon.tsx +52 -0
- package/src/components/Polygon.types.ts +33 -0
- package/src/components/Polygon.web.tsx +104 -0
- package/src/components/Polyline.tsx +23 -22
- package/src/components/Polyline.types.ts +55 -0
- package/src/components/Polyline.web.tsx +151 -37
- package/src/components/index.ts +16 -2
- package/src/components/index.web.ts +6 -2
- package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +43 -7
- package/src/fabric/LuggMarkerViewNativeComponent.ts +49 -1
- package/src/fabric/LuggPolygonViewNativeComponent.ts +25 -0
- package/src/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/src/index.ts +28 -1
- package/src/index.web.ts +15 -1
- package/src/types.ts +13 -0
- package/android/src/main/java/com/luggmaps/LuggGoogleMapView.kt +0 -511
- package/ios/LuggAppleMapView.h +0 -16
- package/ios/LuggAppleMapView.mm +0 -592
- package/ios/LuggGoogleMapView.h +0 -13
- package/ios/LuggGoogleMapView.mm +0 -455
- 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,33 @@
|
|
|
1
|
+
import type { ColorValue } from 'react-native';
|
|
2
|
+
import type { Coordinate } from '../types';
|
|
3
|
+
|
|
4
|
+
export interface PolygonProps {
|
|
5
|
+
/**
|
|
6
|
+
* Array of coordinates forming the polygon boundary
|
|
7
|
+
*/
|
|
8
|
+
coordinates: Coordinate[];
|
|
9
|
+
/**
|
|
10
|
+
* Array of coordinate arrays representing interior holes
|
|
11
|
+
*/
|
|
12
|
+
holes?: Coordinate[][];
|
|
13
|
+
/**
|
|
14
|
+
* Stroke (outline) color
|
|
15
|
+
*/
|
|
16
|
+
strokeColor?: ColorValue;
|
|
17
|
+
/**
|
|
18
|
+
* Stroke width in points
|
|
19
|
+
*/
|
|
20
|
+
strokeWidth?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Fill color of the polygon
|
|
23
|
+
*/
|
|
24
|
+
fillColor?: ColorValue;
|
|
25
|
+
/**
|
|
26
|
+
* Z-index for layering
|
|
27
|
+
*/
|
|
28
|
+
zIndex?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Called when the polygon is tapped
|
|
31
|
+
*/
|
|
32
|
+
onPress?: () => void;
|
|
33
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import { useMapContext } from '../MapProvider.web';
|
|
3
|
+
import type { PolygonProps } from './Polygon.types';
|
|
4
|
+
|
|
5
|
+
export const Polygon = ({
|
|
6
|
+
coordinates,
|
|
7
|
+
holes,
|
|
8
|
+
strokeColor = '#000000',
|
|
9
|
+
strokeWidth = 1,
|
|
10
|
+
fillColor = 'rgba(0, 0, 0, 0.3)',
|
|
11
|
+
zIndex = 0,
|
|
12
|
+
onPress,
|
|
13
|
+
}: PolygonProps) => {
|
|
14
|
+
const { map } = useMapContext();
|
|
15
|
+
const polygonRef = useRef<google.maps.Polygon | null>(null);
|
|
16
|
+
const listenersRef = useRef<google.maps.MapsEventListener[]>([]);
|
|
17
|
+
|
|
18
|
+
const handleClick = useCallback(() => {
|
|
19
|
+
onPress?.();
|
|
20
|
+
}, [onPress]);
|
|
21
|
+
|
|
22
|
+
// Cleanup on unmount
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
return () => {
|
|
25
|
+
listenersRef.current.forEach((l) => l.remove());
|
|
26
|
+
listenersRef.current = [];
|
|
27
|
+
polygonRef.current?.setMap(null);
|
|
28
|
+
polygonRef.current = null;
|
|
29
|
+
};
|
|
30
|
+
}, []);
|
|
31
|
+
|
|
32
|
+
// Sync listeners
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const polygon = polygonRef.current;
|
|
35
|
+
if (!polygon) return;
|
|
36
|
+
|
|
37
|
+
listenersRef.current.forEach((l) => l.remove());
|
|
38
|
+
listenersRef.current = [];
|
|
39
|
+
|
|
40
|
+
if (onPress) {
|
|
41
|
+
listenersRef.current.push(polygon.addListener('click', handleClick));
|
|
42
|
+
}
|
|
43
|
+
polygon.set('clickable', !!onPress);
|
|
44
|
+
}, [onPress, handleClick]);
|
|
45
|
+
|
|
46
|
+
// Sync polygon with props
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (!map || coordinates.length === 0) {
|
|
49
|
+
polygonRef.current?.setMap(null);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const outerPath = coordinates.map((c) => ({
|
|
54
|
+
lat: c.latitude,
|
|
55
|
+
lng: c.longitude,
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
const paths = [
|
|
59
|
+
outerPath,
|
|
60
|
+
...(holes ?? []).map((hole) =>
|
|
61
|
+
[...hole].reverse().map((c) => ({ lat: c.latitude, lng: c.longitude }))
|
|
62
|
+
),
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
if (polygonRef.current) {
|
|
66
|
+
polygonRef.current.setPaths(paths);
|
|
67
|
+
polygonRef.current.setOptions({
|
|
68
|
+
strokeColor: strokeColor as string,
|
|
69
|
+
strokeWeight: strokeWidth,
|
|
70
|
+
fillColor: fillColor as string,
|
|
71
|
+
zIndex,
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
const polygon = new google.maps.Polygon({
|
|
75
|
+
paths,
|
|
76
|
+
strokeColor: strokeColor as string,
|
|
77
|
+
strokeWeight: strokeWidth,
|
|
78
|
+
strokeOpacity: 1,
|
|
79
|
+
fillColor: fillColor as string,
|
|
80
|
+
fillOpacity: 1,
|
|
81
|
+
zIndex,
|
|
82
|
+
clickable: !!onPress,
|
|
83
|
+
map,
|
|
84
|
+
});
|
|
85
|
+
polygonRef.current = polygon;
|
|
86
|
+
|
|
87
|
+
if (onPress) {
|
|
88
|
+
listenersRef.current.push(polygon.addListener('click', handleClick));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, [
|
|
92
|
+
map,
|
|
93
|
+
coordinates,
|
|
94
|
+
holes,
|
|
95
|
+
strokeColor,
|
|
96
|
+
strokeWidth,
|
|
97
|
+
fillColor,
|
|
98
|
+
zIndex,
|
|
99
|
+
onPress,
|
|
100
|
+
handleClick,
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
return null;
|
|
104
|
+
};
|
|
@@ -1,44 +1,45 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ColorValue } from 'react-native';
|
|
3
2
|
import { StyleSheet } from 'react-native';
|
|
4
3
|
import LuggPolylineViewNativeComponent from '../fabric/LuggPolylineViewNativeComponent';
|
|
5
|
-
import type {
|
|
4
|
+
import type { PolylineProps } from './Polyline.types';
|
|
6
5
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
6
|
+
export type {
|
|
7
|
+
PolylineProps,
|
|
8
|
+
PolylineEasing,
|
|
9
|
+
PolylineAnimatedOptions,
|
|
10
|
+
} from './Polyline.types';
|
|
11
|
+
|
|
12
|
+
export class Polyline extends React.PureComponent<PolylineProps> {
|
|
13
|
+
private getStyle(zIndex: number | undefined) {
|
|
14
|
+
if (zIndex == null) return styles.polyline;
|
|
15
|
+
if (zIndex !== this._cachedZIndex) {
|
|
16
|
+
this._cachedZIndex = zIndex;
|
|
17
|
+
this._cachedStyle = [{ zIndex }, styles.polyline];
|
|
18
|
+
}
|
|
19
|
+
return this._cachedStyle!;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private _cachedZIndex: number | undefined;
|
|
23
|
+
private _cachedStyle: any;
|
|
25
24
|
|
|
26
|
-
export class Polyline extends React.Component<PolylineProps> {
|
|
27
25
|
render() {
|
|
28
26
|
const {
|
|
29
27
|
coordinates,
|
|
30
28
|
strokeColors,
|
|
31
29
|
strokeWidth,
|
|
32
30
|
animated = false,
|
|
31
|
+
animatedOptions,
|
|
32
|
+
zIndex,
|
|
33
33
|
} = this.props;
|
|
34
34
|
|
|
35
35
|
return (
|
|
36
36
|
<LuggPolylineViewNativeComponent
|
|
37
|
-
style={
|
|
37
|
+
style={this.getStyle(zIndex)}
|
|
38
38
|
coordinates={coordinates}
|
|
39
39
|
strokeColors={strokeColors}
|
|
40
40
|
strokeWidth={strokeWidth}
|
|
41
41
|
animated={animated}
|
|
42
|
+
animatedOptions={animatedOptions}
|
|
42
43
|
/>
|
|
43
44
|
);
|
|
44
45
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ColorValue } from 'react-native';
|
|
2
|
+
import type { Coordinate } from '../types';
|
|
3
|
+
|
|
4
|
+
export type PolylineEasing = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
|
|
5
|
+
|
|
6
|
+
export interface PolylineAnimatedOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Animation duration in milliseconds
|
|
9
|
+
* @default 2150
|
|
10
|
+
*/
|
|
11
|
+
duration?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Easing function for the animation
|
|
14
|
+
* @default 'linear'
|
|
15
|
+
*/
|
|
16
|
+
easing?: PolylineEasing;
|
|
17
|
+
/**
|
|
18
|
+
* Portion of the line visible as trail (0-1)
|
|
19
|
+
* 1.0 = full snake effect, 0.2 = short worm
|
|
20
|
+
* @default 1.0
|
|
21
|
+
*/
|
|
22
|
+
trailLength?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Delay before animation starts in milliseconds
|
|
25
|
+
* @default 0
|
|
26
|
+
*/
|
|
27
|
+
delay?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface PolylineProps {
|
|
31
|
+
/**
|
|
32
|
+
* Array of coordinates forming the polyline
|
|
33
|
+
*/
|
|
34
|
+
coordinates: Coordinate[];
|
|
35
|
+
/**
|
|
36
|
+
* Gradient colors along the polyline
|
|
37
|
+
*/
|
|
38
|
+
strokeColors?: ColorValue[];
|
|
39
|
+
/**
|
|
40
|
+
* Line width in points
|
|
41
|
+
*/
|
|
42
|
+
strokeWidth?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Animate the polyline with a snake effect
|
|
45
|
+
*/
|
|
46
|
+
animated?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Animation configuration options
|
|
49
|
+
*/
|
|
50
|
+
animatedOptions?: PolylineAnimatedOptions;
|
|
51
|
+
/**
|
|
52
|
+
* Z-index for layering polylines
|
|
53
|
+
*/
|
|
54
|
+
zIndex?: number;
|
|
55
|
+
}
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { useMapContext } from '../MapProvider.web';
|
|
3
|
+
import type { PolylineProps, PolylineEasing } from './Polyline.types';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_DURATION = 2150;
|
|
6
|
+
|
|
7
|
+
const applyEasing = (t: number, easing: PolylineEasing = 'linear'): number => {
|
|
8
|
+
switch (easing) {
|
|
9
|
+
case 'easeIn':
|
|
10
|
+
return t * t;
|
|
11
|
+
case 'easeOut':
|
|
12
|
+
return t * (2 - t);
|
|
13
|
+
case 'easeInOut':
|
|
14
|
+
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
15
|
+
default:
|
|
16
|
+
return t;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const interpolateColor = (
|
|
21
|
+
color1: string,
|
|
22
|
+
color2: string,
|
|
23
|
+
t: number
|
|
24
|
+
): string => {
|
|
15
25
|
const hex = (c: string) => parseInt(c, 16);
|
|
16
26
|
const r1 = hex(color1.slice(1, 3));
|
|
17
27
|
const g1 = hex(color1.slice(3, 5));
|
|
@@ -27,9 +37,9 @@ function interpolateColor(color1: string, color2: string, t: number): string {
|
|
|
27
37
|
return `#${r.toString(16).padStart(2, '0')}${g
|
|
28
38
|
.toString(16)
|
|
29
39
|
.padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
30
|
-
}
|
|
40
|
+
};
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
const getGradientColor = (colors: string[], position: number): string => {
|
|
33
43
|
if (colors.length === 0) return '#000000';
|
|
34
44
|
if (colors.length === 1 || position <= 0) return colors[0]!;
|
|
35
45
|
if (position >= 1) return colors[colors.length - 1]!;
|
|
@@ -39,17 +49,39 @@ function getGradientColor(colors: string[], position: number): string {
|
|
|
39
49
|
const t = scaledPos - index;
|
|
40
50
|
|
|
41
51
|
return interpolateColor(colors[index]!, colors[index + 1]!, t);
|
|
42
|
-
}
|
|
52
|
+
};
|
|
43
53
|
|
|
44
|
-
|
|
54
|
+
export const Polyline = ({
|
|
45
55
|
coordinates,
|
|
46
56
|
strokeColors,
|
|
47
57
|
strokeWidth = 1,
|
|
48
58
|
animated,
|
|
49
|
-
|
|
50
|
-
|
|
59
|
+
animatedOptions,
|
|
60
|
+
zIndex,
|
|
61
|
+
}: PolylineProps) => {
|
|
62
|
+
const resolvedZIndex = zIndex ?? (animated ? 1 : 0);
|
|
63
|
+
const { map, isDragging } = useMapContext();
|
|
64
|
+
|
|
65
|
+
const { duration, easing, trailLength, delay } = useMemo(
|
|
66
|
+
() => ({
|
|
67
|
+
duration: animatedOptions?.duration ?? DEFAULT_DURATION,
|
|
68
|
+
easing: animatedOptions?.easing ?? 'linear',
|
|
69
|
+
trailLength: Math.max(
|
|
70
|
+
0.01,
|
|
71
|
+
Math.min(1, animatedOptions?.trailLength ?? 1)
|
|
72
|
+
),
|
|
73
|
+
delay: animatedOptions?.delay ?? 0,
|
|
74
|
+
}),
|
|
75
|
+
[
|
|
76
|
+
animatedOptions?.duration,
|
|
77
|
+
animatedOptions?.easing,
|
|
78
|
+
animatedOptions?.trailLength,
|
|
79
|
+
animatedOptions?.delay,
|
|
80
|
+
]
|
|
81
|
+
);
|
|
51
82
|
const polylinesRef = useRef<google.maps.Polyline[]>([]);
|
|
52
83
|
const animationRef = useRef<number>(0);
|
|
84
|
+
const isPausedRef = useRef(false);
|
|
53
85
|
|
|
54
86
|
const colors = useMemo(
|
|
55
87
|
() =>
|
|
@@ -62,13 +94,25 @@ function PolylineImpl({
|
|
|
62
94
|
const hasGradient = colors.length > 1;
|
|
63
95
|
|
|
64
96
|
// Refs for animation loop access
|
|
65
|
-
const propsRef = useRef({
|
|
97
|
+
const propsRef = useRef({
|
|
98
|
+
map,
|
|
99
|
+
colors,
|
|
100
|
+
strokeWidth,
|
|
101
|
+
hasGradient,
|
|
102
|
+
zIndex: resolvedZIndex,
|
|
103
|
+
});
|
|
66
104
|
const [mapReady, setMapReady] = useState(!!map);
|
|
67
105
|
|
|
68
106
|
useEffect(() => {
|
|
69
|
-
propsRef.current = {
|
|
107
|
+
propsRef.current = {
|
|
108
|
+
map,
|
|
109
|
+
colors,
|
|
110
|
+
strokeWidth,
|
|
111
|
+
hasGradient,
|
|
112
|
+
zIndex: resolvedZIndex,
|
|
113
|
+
};
|
|
70
114
|
if (map && !mapReady) setMapReady(true);
|
|
71
|
-
}, [map, colors, strokeWidth, hasGradient, mapReady]);
|
|
115
|
+
}, [map, colors, strokeWidth, hasGradient, resolvedZIndex, mapReady]);
|
|
72
116
|
|
|
73
117
|
const updatePath = useCallback((path: google.maps.LatLngLiteral[]) => {
|
|
74
118
|
const {
|
|
@@ -76,11 +120,18 @@ function PolylineImpl({
|
|
|
76
120
|
colors: currentColors,
|
|
77
121
|
strokeWidth: currentStrokeWidth,
|
|
78
122
|
hasGradient: currentHasGradient,
|
|
123
|
+
zIndex: currentZIndex,
|
|
79
124
|
} = propsRef.current;
|
|
80
|
-
|
|
125
|
+
const existing = polylinesRef.current;
|
|
126
|
+
if (!currentMap) return;
|
|
127
|
+
|
|
128
|
+
if (path.length < 2) {
|
|
129
|
+
existing.forEach((p) => p.setMap(null));
|
|
130
|
+
existing.length = 0;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
81
133
|
|
|
82
134
|
const neededSegments = currentHasGradient ? path.length - 1 : 1;
|
|
83
|
-
const existing = polylinesRef.current;
|
|
84
135
|
|
|
85
136
|
// Update or create segments
|
|
86
137
|
for (let i = 0; i < neededSegments; i++) {
|
|
@@ -100,6 +151,7 @@ function PolylineImpl({
|
|
|
100
151
|
strokeColor: color,
|
|
101
152
|
strokeWeight: currentStrokeWidth,
|
|
102
153
|
strokeOpacity: 1,
|
|
154
|
+
zIndex: currentZIndex,
|
|
103
155
|
map: currentMap,
|
|
104
156
|
})
|
|
105
157
|
);
|
|
@@ -122,6 +174,11 @@ function PolylineImpl({
|
|
|
122
174
|
};
|
|
123
175
|
}, []);
|
|
124
176
|
|
|
177
|
+
// Pause/resume animation during drag
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
isPausedRef.current = isDragging;
|
|
180
|
+
}, [isDragging]);
|
|
181
|
+
|
|
125
182
|
// Main effect
|
|
126
183
|
useEffect(() => {
|
|
127
184
|
if (!propsRef.current.map || coordinates.length === 0) return;
|
|
@@ -139,12 +196,65 @@ function PolylineImpl({
|
|
|
139
196
|
}
|
|
140
197
|
|
|
141
198
|
const totalPoints = fullPath.length;
|
|
142
|
-
const
|
|
199
|
+
const useTrailMode = trailLength < 1;
|
|
200
|
+
const renderMax = useTrailMode ? 1 : 2;
|
|
201
|
+
const cycleMax = useTrailMode ? 1 : 2.15;
|
|
202
|
+
|
|
203
|
+
let startTime: number | null = null;
|
|
204
|
+
let delayRemaining = delay;
|
|
205
|
+
|
|
206
|
+
let pausedAt: number | null = null;
|
|
143
207
|
|
|
144
208
|
const animate = (time: number) => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
209
|
+
if (isPausedRef.current) {
|
|
210
|
+
if (pausedAt === null) pausedAt = time;
|
|
211
|
+
animationRef.current = requestAnimationFrame(animate);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (pausedAt !== null) {
|
|
216
|
+
if (startTime !== null) {
|
|
217
|
+
startTime += time - pausedAt;
|
|
218
|
+
}
|
|
219
|
+
pausedAt = null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (startTime === null) {
|
|
223
|
+
startTime = time;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const elapsed = time - startTime;
|
|
227
|
+
|
|
228
|
+
if (delayRemaining > 0) {
|
|
229
|
+
if (elapsed < delayRemaining) {
|
|
230
|
+
animationRef.current = requestAnimationFrame(animate);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
startTime = time - (elapsed - delayRemaining);
|
|
234
|
+
delayRemaining = 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const rawProgress = (time - startTime) / duration;
|
|
238
|
+
|
|
239
|
+
if (rawProgress >= cycleMax) {
|
|
240
|
+
delayRemaining = delay;
|
|
241
|
+
startTime = time;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const clampedProgress = Math.min(rawProgress, renderMax);
|
|
245
|
+
const easedProgress =
|
|
246
|
+
applyEasing(clampedProgress / renderMax, easing) * renderMax;
|
|
247
|
+
|
|
248
|
+
let startIdx: number;
|
|
249
|
+
let endIdx: number;
|
|
250
|
+
|
|
251
|
+
if (useTrailMode) {
|
|
252
|
+
endIdx = easedProgress * totalPoints;
|
|
253
|
+
startIdx = Math.max(0, endIdx - trailLength * totalPoints);
|
|
254
|
+
} else {
|
|
255
|
+
startIdx = easedProgress <= 1 ? 0 : (easedProgress - 1) * totalPoints;
|
|
256
|
+
endIdx = easedProgress <= 1 ? easedProgress * totalPoints : totalPoints;
|
|
257
|
+
}
|
|
148
258
|
|
|
149
259
|
const partialPath: google.maps.LatLngLiteral[] = [];
|
|
150
260
|
const startFloor = Math.floor(startIdx);
|
|
@@ -194,13 +304,17 @@ function PolylineImpl({
|
|
|
194
304
|
animationRef.current = requestAnimationFrame(animate);
|
|
195
305
|
|
|
196
306
|
return () => cancelAnimationFrame(animationRef.current);
|
|
197
|
-
}, [
|
|
307
|
+
}, [
|
|
308
|
+
coordinates,
|
|
309
|
+
animated,
|
|
310
|
+
duration,
|
|
311
|
+
easing,
|
|
312
|
+
trailLength,
|
|
313
|
+
delay,
|
|
314
|
+
hasGradient,
|
|
315
|
+
updatePath,
|
|
316
|
+
mapReady,
|
|
317
|
+
]);
|
|
198
318
|
|
|
199
319
|
return null;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export class Polyline extends Component<PolylineProps> {
|
|
203
|
-
render() {
|
|
204
|
-
return <PolylineImpl {...this.props} />;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
320
|
+
};
|
package/src/components/index.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export { Marker } from './Marker';
|
|
2
|
+
export type {
|
|
3
|
+
MarkerProps,
|
|
4
|
+
MarkerPressEvent,
|
|
5
|
+
MarkerDragEvent,
|
|
6
|
+
} from './Marker.types';
|
|
7
|
+
export { Polygon } from './Polygon';
|
|
8
|
+
export type { PolygonProps } from './Polygon.types';
|
|
9
|
+
export { Polyline } from './Polyline';
|
|
10
|
+
export type {
|
|
11
|
+
PolylineProps,
|
|
12
|
+
PolylineEasing,
|
|
13
|
+
PolylineAnimatedOptions,
|
|
14
|
+
} from './Polyline.types';
|
|
15
|
+
export { GeoJson } from './GeoJson';
|
|
16
|
+
export type { GeoJsonProps } from './GeoJson.types';
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export { Marker } from './Marker.web';
|
|
2
|
+
export { Polygon } from './Polygon.web';
|
|
2
3
|
export { Polyline } from './Polyline.web';
|
|
3
|
-
export type { MarkerProps } from './Marker';
|
|
4
|
-
export type {
|
|
4
|
+
export type { MarkerProps } from './Marker.types';
|
|
5
|
+
export type { PolygonProps } from './Polygon.types';
|
|
6
|
+
export type { PolylineProps } from './Polyline.types';
|
|
7
|
+
export { GeoJson } from './GeoJson';
|
|
8
|
+
export type { GeoJsonProps } from './GeoJson.types';
|
|
@@ -2,6 +2,7 @@ import { codegenNativeComponent, codegenNativeCommands } from 'react-native';
|
|
|
2
2
|
import type { ViewProps, HostComponent } from 'react-native';
|
|
3
3
|
import type {
|
|
4
4
|
Double,
|
|
5
|
+
WithDefault,
|
|
5
6
|
DirectEventHandler,
|
|
6
7
|
} from 'react-native/Libraries/Types/CodegenTypes';
|
|
7
8
|
|
|
@@ -35,9 +36,32 @@ export interface CameraIdleEvent {
|
|
|
35
36
|
gesture: boolean;
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
export interface PressEvent {
|
|
40
|
+
coordinate: {
|
|
41
|
+
latitude: Double;
|
|
42
|
+
longitude: Double;
|
|
43
|
+
};
|
|
44
|
+
point: {
|
|
45
|
+
x: Double;
|
|
46
|
+
y: Double;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface LongPressEvent {
|
|
51
|
+
coordinate: {
|
|
52
|
+
latitude: Double;
|
|
53
|
+
longitude: Double;
|
|
54
|
+
};
|
|
55
|
+
point: {
|
|
56
|
+
x: Double;
|
|
57
|
+
y: Double;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
export interface ReadyEvent {}
|
|
39
62
|
|
|
40
63
|
export interface NativeProps extends ViewProps {
|
|
64
|
+
provider?: WithDefault<'google' | 'apple', 'google'>;
|
|
41
65
|
mapId?: string;
|
|
42
66
|
initialCoordinate?: Coordinate;
|
|
43
67
|
initialZoom?: Double;
|
|
@@ -47,8 +71,12 @@ export interface NativeProps extends ViewProps {
|
|
|
47
71
|
scrollEnabled?: boolean;
|
|
48
72
|
rotateEnabled?: boolean;
|
|
49
73
|
pitchEnabled?: boolean;
|
|
50
|
-
|
|
74
|
+
edgeInsets?: EdgeInsets;
|
|
51
75
|
userLocationEnabled?: boolean;
|
|
76
|
+
userLocationButtonEnabled?: boolean;
|
|
77
|
+
theme?: WithDefault<'light' | 'dark' | 'system', 'system'>;
|
|
78
|
+
onMapPress?: DirectEventHandler<PressEvent>;
|
|
79
|
+
onMapLongPress?: DirectEventHandler<LongPressEvent>;
|
|
52
80
|
onCameraMove?: DirectEventHandler<CameraMoveEvent>;
|
|
53
81
|
onCameraIdle?: DirectEventHandler<CameraIdleEvent>;
|
|
54
82
|
onReady?: DirectEventHandler<ReadyEvent>;
|
|
@@ -67,18 +95,26 @@ interface NativeCommands {
|
|
|
67
95
|
fitCoordinates: (
|
|
68
96
|
viewRef: React.ElementRef<ComponentType>,
|
|
69
97
|
coordinates: Coordinate[],
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
98
|
+
edgeInsetsTop: Double,
|
|
99
|
+
edgeInsetsLeft: Double,
|
|
100
|
+
edgeInsetsBottom: Double,
|
|
101
|
+
edgeInsetsRight: Double,
|
|
102
|
+
duration: Double
|
|
103
|
+
) => void;
|
|
104
|
+
setEdgeInsets: (
|
|
105
|
+
viewRef: React.ElementRef<ComponentType>,
|
|
106
|
+
top: Double,
|
|
107
|
+
left: Double,
|
|
108
|
+
bottom: Double,
|
|
109
|
+
right: Double,
|
|
74
110
|
duration: Double
|
|
75
111
|
) => void;
|
|
76
112
|
}
|
|
77
113
|
|
|
78
114
|
export const Commands = codegenNativeCommands<NativeCommands>({
|
|
79
|
-
supportedCommands: ['moveCamera', 'fitCoordinates'],
|
|
115
|
+
supportedCommands: ['moveCamera', 'fitCoordinates', 'setEdgeInsets'],
|
|
80
116
|
});
|
|
81
117
|
|
|
82
118
|
export default codegenNativeComponent<NativeProps>(
|
|
83
|
-
'
|
|
119
|
+
'LuggMapView'
|
|
84
120
|
) as ComponentType;
|