expo-gaode-map 2.2.30-next.0 → 2.2.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/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +4 -2
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +117 -57
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +8 -15
- package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +20 -6
- package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +24 -13
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerBitmapRenderer.kt +351 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +94 -310
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerViewModule.kt +3 -3
- package/build/ExpoGaodeMapModule.d.ts +13 -5
- package/build/ExpoGaodeMapModule.d.ts.map +1 -1
- package/build/ExpoGaodeMapModule.js +166 -34
- package/build/ExpoGaodeMapModule.js.map +1 -1
- package/build/ExpoGaodeMapView.d.ts.map +1 -1
- package/build/ExpoGaodeMapView.js +12 -0
- package/build/ExpoGaodeMapView.js.map +1 -1
- package/build/components/AreaMaskOverlay.d.ts +5 -0
- package/build/components/AreaMaskOverlay.d.ts.map +1 -0
- package/build/components/AreaMaskOverlay.js +20 -0
- package/build/components/AreaMaskOverlay.js.map +1 -0
- package/build/components/FoldableMapView.d.ts.map +1 -1
- package/build/components/FoldableMapView.js +115 -104
- package/build/components/FoldableMapView.js.map +1 -1
- package/build/components/RouteOverlay.d.ts +5 -0
- package/build/components/RouteOverlay.d.ts.map +1 -0
- package/build/components/RouteOverlay.js +20 -0
- package/build/components/RouteOverlay.js.map +1 -0
- package/build/components/overlays/Cluster.d.ts.map +1 -1
- package/build/components/overlays/Cluster.js +12 -0
- package/build/components/overlays/Cluster.js.map +1 -1
- package/build/components/overlays/Marker.d.ts.map +1 -1
- package/build/components/overlays/Marker.js +86 -3
- package/build/components/overlays/Marker.js.map +1 -1
- package/build/hooks/useRoutePlayback.d.ts +4 -0
- package/build/hooks/useRoutePlayback.d.ts.map +1 -0
- package/build/hooks/useRoutePlayback.js +310 -0
- package/build/hooks/useRoutePlayback.js.map +1 -0
- package/build/index.d.ts +4 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -2
- package/build/index.js.map +1 -1
- package/build/types/common.types.d.ts +29 -5
- package/build/types/common.types.d.ts.map +1 -1
- package/build/types/common.types.js +5 -5
- package/build/types/common.types.js.map +1 -1
- package/build/types/index.d.ts +3 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js.map +1 -1
- package/build/types/location.types.d.ts +28 -0
- package/build/types/location.types.d.ts.map +1 -1
- package/build/types/location.types.js +5 -0
- package/build/types/location.types.js.map +1 -1
- package/build/types/map-view.types.d.ts +22 -22
- package/build/types/map-view.types.d.ts.map +1 -1
- package/build/types/map-view.types.js.map +1 -1
- package/build/types/native-module.types.d.ts +2 -2
- package/build/types/native-module.types.d.ts.map +1 -1
- package/build/types/native-module.types.js.map +1 -1
- package/build/types/overlays.types.d.ts +14 -0
- package/build/types/overlays.types.d.ts.map +1 -1
- package/build/types/overlays.types.js.map +1 -1
- package/build/types/route-playback.types.d.ts +118 -0
- package/build/types/route-playback.types.d.ts.map +1 -0
- package/build/types/route-playback.types.js +2 -0
- package/build/types/route-playback.types.js.map +1 -0
- package/build/utils/RouteUtils.d.ts +8 -0
- package/build/utils/RouteUtils.d.ts.map +1 -0
- package/build/utils/RouteUtils.js +140 -0
- package/build/utils/RouteUtils.js.map +1 -0
- package/ios/ExpoGaodeMapModule.swift +41 -22
- package/ios/ExpoGaodeMapView.swift +236 -241
- package/ios/ExpoGaodeMapViewModule.swift +16 -11
- package/ios/managers/UIManager.swift +5 -4
- package/ios/modules/LocationManager.swift +32 -9
- package/ios/overlays/ClusterView.swift +114 -12
- package/ios/overlays/ClusterViewModule.swift +5 -1
- package/ios/overlays/MarkerView.swift +195 -18
- package/ios/overlays/MarkerViewModule.swift +7 -7
- package/package.json +6 -6
- package/build/utils/throttle.d.ts +0 -10
- package/build/utils/throttle.d.ts.map +0 -1
- package/build/utils/throttle.js +0 -19
- package/build/utils/throttle.js.map +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { normalizeLatLngList } from '../utils/GeoUtils';
|
|
3
|
+
import { parseMultiRingPolyline } from '../utils/RouteUtils';
|
|
4
|
+
import { Polygon } from './overlays';
|
|
5
|
+
export function AreaMaskOverlay({ rings, polygonProps }) {
|
|
6
|
+
// 支持直接传多环坐标,或传高德返回的 polyline 字符串。
|
|
7
|
+
// 最终都落到 Polygon 的“带孔多边形”能力上。
|
|
8
|
+
const normalizedPoints = React.useMemo(() => {
|
|
9
|
+
if (typeof rings === 'string') {
|
|
10
|
+
return parseMultiRingPolyline(rings).rings;
|
|
11
|
+
}
|
|
12
|
+
return normalizeLatLngList(rings);
|
|
13
|
+
}, [rings]);
|
|
14
|
+
if (!normalizedPoints.length) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return (<Polygon points={normalizedPoints} fillColor={polygonProps?.fillColor ?? 'rgba(15, 23, 42, 0.45)'} strokeColor={polygonProps?.strokeColor ?? 'rgba(15, 23, 42, 0.8)'} strokeWidth={polygonProps?.strokeWidth ?? 1} {...polygonProps}/>);
|
|
18
|
+
}
|
|
19
|
+
export default AreaMaskOverlay;
|
|
20
|
+
//# sourceMappingURL=AreaMaskOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AreaMaskOverlay.js","sourceRoot":"","sources":["../../src/components/AreaMaskOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,UAAU,eAAe,CAAC,EAAE,KAAK,EAAE,YAAY,EAAwB;IAC3E,kCAAkC;IAClC,6BAA6B;IAC7B,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;QAC7C,CAAC;QAED,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,CAAC,OAAO,CACN,MAAM,CAAC,CAAC,gBAAgB,CAAC,CACzB,SAAS,CAAC,CAAC,YAAY,EAAE,SAAS,IAAI,wBAAwB,CAAC,CAC/D,WAAW,CAAC,CAAC,YAAY,EAAE,WAAW,IAAI,uBAAuB,CAAC,CAClE,WAAW,CAAC,CAAC,YAAY,EAAE,WAAW,IAAI,CAAC,CAAC,CAC5C,IAAI,YAAY,CAAC,EACjB,CACH,CAAC;AACJ,CAAC;AAED,eAAe,eAAe,CAAC","sourcesContent":["import * as React from 'react';\n\nimport type { AreaMaskOverlayProps } from '../types/route-playback.types';\nimport { normalizeLatLngList } from '../utils/GeoUtils';\nimport { parseMultiRingPolyline } from '../utils/RouteUtils';\nimport { Polygon } from './overlays';\n\nexport function AreaMaskOverlay({ rings, polygonProps }: AreaMaskOverlayProps) {\n // 支持直接传多环坐标,或传高德返回的 polyline 字符串。\n // 最终都落到 Polygon 的“带孔多边形”能力上。\n const normalizedPoints = React.useMemo(() => {\n if (typeof rings === 'string') {\n return parseMultiRingPolyline(rings).rings;\n }\n\n return normalizeLatLngList(rings);\n }, [rings]);\n\n if (!normalizedPoints.length) {\n return null;\n }\n\n return (\n <Polygon\n points={normalizedPoints}\n fillColor={polygonProps?.fillColor ?? 'rgba(15, 23, 42, 0.45)'}\n strokeColor={polygonProps?.strokeColor ?? 'rgba(15, 23, 42, 0.8)'}\n strokeWidth={polygonProps?.strokeWidth ?? 1}\n {...polygonProps}\n />\n );\n}\n\nexport default AreaMaskOverlay;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FoldableMapView.d.ts","sourceRoot":"","sources":["../../src/components/FoldableMapView.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"FoldableMapView.d.ts","sourceRoot":"","sources":["../../src/components/FoldableMapView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,EAAoB,UAAU,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe;IACf,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IACvE,eAAe;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,cAAc;IACd,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AA2ED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA6F1D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,EACnC,MAAM,CAAC,EAAE,cAAc;;;;EAgExB"}
|
|
@@ -1,108 +1,127 @@
|
|
|
1
|
-
import React, { useEffect, useRef, useState } from 'react';
|
|
1
|
+
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { Platform } from 'react-native';
|
|
3
3
|
import ExpoGaodeMapView from '../ExpoGaodeMapView';
|
|
4
4
|
import { PlatformDetector, FoldState } from '../utils/PlatformDetector';
|
|
5
|
+
const DEFAULT_FOLDABLE_CONFIG = {
|
|
6
|
+
autoAdjustZoom: true,
|
|
7
|
+
unfoldedZoomDelta: 1,
|
|
8
|
+
keepCenterOnFold: true,
|
|
9
|
+
onFoldStateChange: () => { },
|
|
10
|
+
debug: false,
|
|
11
|
+
};
|
|
12
|
+
function clampZoomLevel(zoom) {
|
|
13
|
+
return Math.max(3, Math.min(20, zoom));
|
|
14
|
+
}
|
|
15
|
+
function createFoldableConfig(config) {
|
|
16
|
+
return {
|
|
17
|
+
...DEFAULT_FOLDABLE_CONFIG,
|
|
18
|
+
...config,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async function applyFoldStateCameraAdjustment(mapRef, oldState, newState, config, debugPrefix) {
|
|
22
|
+
if (!mapRef.current || !config.autoAdjustZoom) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const currentCamera = await mapRef.current.getCameraPosition();
|
|
26
|
+
if (!currentCamera) {
|
|
27
|
+
if (config.debug) {
|
|
28
|
+
console.warn(`[${debugPrefix}] 无法获取相机位置`);
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const isUnfolding = newState === FoldState.UNFOLDED && oldState === FoldState.FOLDED;
|
|
33
|
+
const isFolding = newState === FoldState.FOLDED && oldState === FoldState.UNFOLDED;
|
|
34
|
+
if (config.debug) {
|
|
35
|
+
console.log(`[${debugPrefix}] 折叠状态变化:`, {
|
|
36
|
+
oldState,
|
|
37
|
+
newState,
|
|
38
|
+
isUnfolding,
|
|
39
|
+
isFolding,
|
|
40
|
+
currentZoom: currentCamera.zoom,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (!isUnfolding && !isFolding) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const currentZoom = currentCamera.zoom ?? 15;
|
|
47
|
+
const zoomDelta = isUnfolding ? config.unfoldedZoomDelta : -config.unfoldedZoomDelta;
|
|
48
|
+
const nextZoom = clampZoomLevel(currentZoom + zoomDelta);
|
|
49
|
+
if (config.debug) {
|
|
50
|
+
console.log(`[${debugPrefix}] 调整缩放:`, {
|
|
51
|
+
oldZoom: currentZoom,
|
|
52
|
+
newZoom: nextZoom,
|
|
53
|
+
delta: zoomDelta,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
await mapRef.current.moveCamera({
|
|
57
|
+
target: config.keepCenterOnFold ? currentCamera.target : undefined,
|
|
58
|
+
zoom: nextZoom,
|
|
59
|
+
}, 300);
|
|
60
|
+
}
|
|
5
61
|
export const FoldableMapView = ({ foldableConfig, ...mapProps }) => {
|
|
6
62
|
const mapRef = useRef(null);
|
|
7
63
|
const [currentFoldState, setCurrentFoldState] = useState(FoldState.UNKNOWN);
|
|
8
64
|
const [deviceInfo, setDeviceInfo] = useState(PlatformDetector.getDeviceInfo());
|
|
9
|
-
const config =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
65
|
+
const config = useMemo(() => createFoldableConfig(foldableConfig), [foldableConfig]);
|
|
66
|
+
const configRef = useRef(config);
|
|
67
|
+
const foldStateRef = useRef(currentFoldState);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
configRef.current = config;
|
|
70
|
+
}, [config]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
foldStateRef.current = currentFoldState;
|
|
73
|
+
}, [currentFoldState]);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
const latestDeviceInfo = PlatformDetector.getDeviceInfo();
|
|
76
|
+
setDeviceInfo(latestDeviceInfo);
|
|
77
|
+
}, []);
|
|
17
78
|
useEffect(() => {
|
|
18
79
|
// 仅在 Android 折叠屏设备上启用
|
|
19
80
|
if (Platform.OS !== 'android' || !deviceInfo.isFoldable) {
|
|
20
|
-
if (
|
|
81
|
+
if (configRef.current.debug) {
|
|
21
82
|
console.log('[FoldableMapView] 非折叠屏设备,跳过适配');
|
|
22
83
|
}
|
|
23
84
|
return;
|
|
24
85
|
}
|
|
25
|
-
|
|
86
|
+
const initialState = PlatformDetector.getFoldState();
|
|
87
|
+
foldStateRef.current = initialState;
|
|
88
|
+
setCurrentFoldState(initialState);
|
|
89
|
+
if (configRef.current.debug) {
|
|
26
90
|
console.log('[FoldableMapView] 初始化折叠屏适配');
|
|
27
91
|
console.log('设备信息:', deviceInfo);
|
|
28
|
-
console.log('初始折叠状态:',
|
|
92
|
+
console.log('初始折叠状态:', initialState);
|
|
29
93
|
}
|
|
30
94
|
// 监听屏幕尺寸变化
|
|
31
95
|
const removeListener = PlatformDetector.addDimensionChangeListener(async (newInfo) => {
|
|
32
96
|
const newFoldState = PlatformDetector.getFoldState();
|
|
33
|
-
|
|
97
|
+
const previousFoldState = foldStateRef.current;
|
|
98
|
+
const latestConfig = configRef.current;
|
|
99
|
+
if (latestConfig.debug) {
|
|
34
100
|
console.log('[FoldableMapView] 屏幕尺寸变化');
|
|
35
101
|
console.log('新设备信息:', newInfo);
|
|
36
102
|
console.log('新折叠状态:', newFoldState);
|
|
37
103
|
}
|
|
38
104
|
// 折叠状态变化时的处理
|
|
39
|
-
if (newFoldState !==
|
|
40
|
-
|
|
105
|
+
if (newFoldState !== previousFoldState && previousFoldState !== FoldState.UNKNOWN) {
|
|
106
|
+
try {
|
|
107
|
+
await applyFoldStateCameraAdjustment(mapRef, previousFoldState, newFoldState, latestConfig, 'FoldableMapView');
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (latestConfig.debug) {
|
|
111
|
+
console.error('[FoldableMapView] 处理折叠状态变化失败:', error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
41
114
|
}
|
|
115
|
+
foldStateRef.current = newFoldState;
|
|
42
116
|
setCurrentFoldState(newFoldState);
|
|
43
117
|
setDeviceInfo(newInfo);
|
|
44
118
|
// 触发回调
|
|
45
|
-
|
|
119
|
+
latestConfig.onFoldStateChange(newFoldState, newInfo);
|
|
46
120
|
});
|
|
47
|
-
// 设置初始状态
|
|
48
|
-
const initialState = PlatformDetector.getFoldState();
|
|
49
|
-
setCurrentFoldState(initialState);
|
|
50
121
|
return () => {
|
|
51
122
|
removeListener();
|
|
52
123
|
};
|
|
53
|
-
}, []);
|
|
54
|
-
/**
|
|
55
|
-
* 处理折叠状态变化
|
|
56
|
-
*/
|
|
57
|
-
const handleFoldStateChange = async (oldState, newState, newInfo) => {
|
|
58
|
-
if (!mapRef.current) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
try {
|
|
62
|
-
// 获取当前地图状态
|
|
63
|
-
const currentCamera = await mapRef.current.getCameraPosition?.();
|
|
64
|
-
if (!currentCamera) {
|
|
65
|
-
if (config.debug) {
|
|
66
|
-
console.warn('[FoldableMapView] 无法获取相机位置');
|
|
67
|
-
}
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
const isUnfolding = newState === FoldState.UNFOLDED && oldState === FoldState.FOLDED;
|
|
71
|
-
const isFolding = newState === FoldState.FOLDED && oldState === FoldState.UNFOLDED;
|
|
72
|
-
if (config.debug) {
|
|
73
|
-
console.log('[FoldableMapView] 折叠状态变化:', {
|
|
74
|
-
oldState,
|
|
75
|
-
newState,
|
|
76
|
-
isUnfolding,
|
|
77
|
-
isFolding,
|
|
78
|
-
currentZoom: currentCamera.zoom,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
// 展开时增加缩放级别,折叠时减少
|
|
82
|
-
if (config.autoAdjustZoom && (isUnfolding || isFolding)) {
|
|
83
|
-
const currentZoom = currentCamera.zoom ?? 15;
|
|
84
|
-
const zoomDelta = isUnfolding ? config.unfoldedZoomDelta : -config.unfoldedZoomDelta;
|
|
85
|
-
const newZoom = Math.max(3, Math.min(20, currentZoom + zoomDelta));
|
|
86
|
-
if (config.debug) {
|
|
87
|
-
console.log('[FoldableMapView] 调整缩放:', {
|
|
88
|
-
oldZoom: currentZoom,
|
|
89
|
-
newZoom,
|
|
90
|
-
delta: zoomDelta,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
// 保持中心点,只调整缩放
|
|
94
|
-
await mapRef.current.moveCamera({
|
|
95
|
-
target: config.keepCenterOnFold ? currentCamera.target : undefined,
|
|
96
|
-
zoom: newZoom,
|
|
97
|
-
}, 300);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
if (config.debug) {
|
|
102
|
-
console.error('[FoldableMapView] 处理折叠状态变化失败:');
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
};
|
|
124
|
+
}, [deviceInfo.isFoldable]);
|
|
106
125
|
return (<ExpoGaodeMapView ref={mapRef} {...mapProps}/>);
|
|
107
126
|
};
|
|
108
127
|
/**
|
|
@@ -113,53 +132,45 @@ export const FoldableMapView = ({ foldableConfig, ...mapProps }) => {
|
|
|
113
132
|
export function useFoldableMap(mapRef, config) {
|
|
114
133
|
const [foldState, setFoldState] = useState(FoldState.UNKNOWN);
|
|
115
134
|
const [deviceInfo, setDeviceInfo] = useState(PlatformDetector.getDeviceInfo());
|
|
116
|
-
const mergedConfig =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
135
|
+
const mergedConfig = useMemo(() => createFoldableConfig(config), [config]);
|
|
136
|
+
const foldStateRef = useRef(foldState);
|
|
137
|
+
const configRef = useRef(mergedConfig);
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
foldStateRef.current = foldState;
|
|
140
|
+
}, [foldState]);
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
configRef.current = mergedConfig;
|
|
143
|
+
}, [mergedConfig]);
|
|
124
144
|
useEffect(() => {
|
|
125
145
|
if (Platform.OS !== 'android' || !deviceInfo.isFoldable) {
|
|
126
146
|
return;
|
|
127
147
|
}
|
|
148
|
+
const initialState = PlatformDetector.getFoldState();
|
|
149
|
+
foldStateRef.current = initialState;
|
|
150
|
+
setFoldState(initialState);
|
|
128
151
|
const removeListener = PlatformDetector.addDimensionChangeListener(async (newInfo) => {
|
|
129
152
|
const newFoldState = PlatformDetector.getFoldState();
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const newZoom = Math.max(3, Math.min(20, currentZoom + zoomDelta));
|
|
140
|
-
await mapRef.current.moveCamera({
|
|
141
|
-
target: mergedConfig.keepCenterOnFold ? currentCamera.target : undefined,
|
|
142
|
-
zoom: newZoom,
|
|
143
|
-
}, 300);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
if (mergedConfig.debug) {
|
|
148
|
-
console.error('[useFoldableMap] 调整失败:');
|
|
149
|
-
}
|
|
153
|
+
const previousFoldState = foldStateRef.current;
|
|
154
|
+
const latestConfig = configRef.current;
|
|
155
|
+
if (newFoldState !== previousFoldState && previousFoldState !== FoldState.UNKNOWN) {
|
|
156
|
+
try {
|
|
157
|
+
await applyFoldStateCameraAdjustment(mapRef, previousFoldState, newFoldState, latestConfig, 'useFoldableMap');
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (latestConfig.debug) {
|
|
161
|
+
console.error('[useFoldableMap] 调整失败:', error);
|
|
150
162
|
}
|
|
151
163
|
}
|
|
152
164
|
}
|
|
165
|
+
foldStateRef.current = newFoldState;
|
|
153
166
|
setFoldState(newFoldState);
|
|
154
167
|
setDeviceInfo(newInfo);
|
|
155
|
-
|
|
168
|
+
latestConfig.onFoldStateChange(newFoldState, newInfo);
|
|
156
169
|
});
|
|
157
|
-
const initialState = PlatformDetector.getFoldState();
|
|
158
|
-
setFoldState(initialState);
|
|
159
170
|
return () => {
|
|
160
171
|
removeListener();
|
|
161
172
|
};
|
|
162
|
-
}, [
|
|
173
|
+
}, [deviceInfo.isFoldable, mapRef]);
|
|
163
174
|
return {
|
|
164
175
|
foldState,
|
|
165
176
|
deviceInfo,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FoldableMapView.js","sourceRoot":"","sources":["../../src/components/FoldableMapView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport { Platform } from 'react-native';\nimport ExpoGaodeMapView from '../ExpoGaodeMapView';\n\nimport { PlatformDetector, DeviceInfo, FoldState } from '../utils/PlatformDetector';\nimport { MapViewProps, MapViewRef } from '../types';\n\n/**\n * 折叠屏适配配置\n */\nexport interface FoldableConfig {\n /** 折叠时是否自动调整缩放级别 */\n autoAdjustZoom?: boolean;\n /** 展开时的缩放级别增量 */\n unfoldedZoomDelta?: number;\n /** 是否在折叠/展开时保持中心点 */\n keepCenterOnFold?: boolean;\n /** 折叠状态变化回调 */\n onFoldStateChange?: (state: FoldState, deviceInfo: DeviceInfo) => void;\n /** 是否启用调试日志 */\n debug?: boolean;\n}\n\n/**\n * 折叠屏地图视图组件\n * \n * 自动适配折叠屏设备的展开/折叠状态变化\n */\nexport interface FoldableMapViewProps extends MapViewProps {\n /** 折叠屏适配配置 */\n foldableConfig?: FoldableConfig;\n}\n\nexport const FoldableMapView: React.FC<FoldableMapViewProps> = ({\n foldableConfig,\n ...mapProps\n}) => {\n const mapRef = useRef<MapViewRef>(null);\n const [currentFoldState, setCurrentFoldState] = useState<FoldState>(FoldState.UNKNOWN);\n const [deviceInfo, setDeviceInfo] = useState<DeviceInfo>(PlatformDetector.getDeviceInfo());\n\n const config: Required<FoldableConfig> = {\n autoAdjustZoom: true,\n unfoldedZoomDelta: 1,\n keepCenterOnFold: true,\n onFoldStateChange: () => {},\n debug: false,\n ...foldableConfig,\n };\n\n useEffect(() => {\n // 仅在 Android 折叠屏设备上启用\n if (Platform.OS !== 'android' || !deviceInfo.isFoldable) {\n if (config.debug) {\n console.log('[FoldableMapView] 非折叠屏设备,跳过适配');\n }\n return;\n }\n\n if (config.debug) {\n console.log('[FoldableMapView] 初始化折叠屏适配');\n console.log('设备信息:', deviceInfo);\n console.log('初始折叠状态:', currentFoldState);\n }\n\n // 监听屏幕尺寸变化\n const removeListener = PlatformDetector.addDimensionChangeListener(\n async (newInfo: DeviceInfo) => {\n const newFoldState = PlatformDetector.getFoldState();\n \n if (config.debug) {\n console.log('[FoldableMapView] 屏幕尺寸变化');\n console.log('新设备信息:', newInfo);\n console.log('新折叠状态:', newFoldState);\n }\n\n // 折叠状态变化时的处理\n if (newFoldState !== currentFoldState && currentFoldState !== FoldState.UNKNOWN) {\n await handleFoldStateChange(currentFoldState, newFoldState, newInfo);\n }\n\n setCurrentFoldState(newFoldState);\n setDeviceInfo(newInfo);\n \n // 触发回调\n config.onFoldStateChange(newFoldState, newInfo);\n }\n );\n\n // 设置初始状态\n const initialState = PlatformDetector.getFoldState();\n setCurrentFoldState(initialState);\n\n return () => {\n removeListener();\n };\n }, []);\n\n /**\n * 处理折叠状态变化\n */\n const handleFoldStateChange = async (\n oldState: FoldState,\n newState: FoldState,\n newInfo: DeviceInfo\n ) => {\n if (!mapRef.current) {\n return;\n }\n\n try {\n // 获取当前地图状态\n const currentCamera = await mapRef.current.getCameraPosition?.();\n \n if (!currentCamera) {\n if (config.debug) {\n console.warn('[FoldableMapView] 无法获取相机位置');\n }\n return;\n }\n\n const isUnfolding = newState === FoldState.UNFOLDED && oldState === FoldState.FOLDED;\n const isFolding = newState === FoldState.FOLDED && oldState === FoldState.UNFOLDED;\n\n if (config.debug) {\n console.log('[FoldableMapView] 折叠状态变化:', {\n oldState,\n newState,\n isUnfolding,\n isFolding,\n currentZoom: currentCamera.zoom,\n });\n }\n\n // 展开时增加缩放级别,折叠时减少\n if (config.autoAdjustZoom && (isUnfolding || isFolding)) {\n const currentZoom = currentCamera.zoom ?? 15;\n const zoomDelta = isUnfolding ? config.unfoldedZoomDelta : -config.unfoldedZoomDelta;\n const newZoom = Math.max(3, Math.min(20, currentZoom + zoomDelta));\n\n if (config.debug) {\n console.log('[FoldableMapView] 调整缩放:', {\n oldZoom: currentZoom,\n newZoom,\n delta: zoomDelta,\n });\n }\n\n // 保持中心点,只调整缩放\n await mapRef.current.moveCamera({\n target: config.keepCenterOnFold ? currentCamera.target : undefined,\n zoom: newZoom,\n }, 300);\n }\n } catch (error) {\n if (config.debug) {\n console.error('[FoldableMapView] 处理折叠状态变化失败:');\n }\n }\n };\n\n \n\n return (\n <ExpoGaodeMapView\n ref={mapRef}\n {...mapProps}\n />\n );\n};\n\n/**\n * 折叠屏适配 Hook\n * \n * 用于在现有地图组件中添加折叠屏适配功能\n */\nexport function useFoldableMap(\n mapRef: React.RefObject<MapViewRef>,\n config?: FoldableConfig\n) {\n const [foldState, setFoldState] = useState<FoldState>(FoldState.UNKNOWN);\n const [deviceInfo, setDeviceInfo] = useState<DeviceInfo>(PlatformDetector.getDeviceInfo());\n\n const mergedConfig: Required<FoldableConfig> = {\n autoAdjustZoom: true,\n unfoldedZoomDelta: 1,\n keepCenterOnFold: true,\n onFoldStateChange: () => {},\n debug: false,\n ...config,\n };\n\n useEffect(() => {\n if (Platform.OS !== 'android' || !deviceInfo.isFoldable) {\n return;\n }\n\n const removeListener = PlatformDetector.addDimensionChangeListener(\n async (newInfo: DeviceInfo) => {\n const newFoldState = PlatformDetector.getFoldState();\n \n if (newFoldState !== foldState && foldState !== FoldState.UNKNOWN) {\n // 处理折叠状态变化\n if (mapRef.current && mergedConfig.autoAdjustZoom) {\n try {\n const currentCamera = await mapRef.current.getCameraPosition();\n if (currentCamera) {\n const currentZoom = currentCamera.zoom ?? 15;\n const isUnfolding = newFoldState === FoldState.UNFOLDED && foldState === FoldState.FOLDED;\n const zoomDelta = isUnfolding ? mergedConfig.unfoldedZoomDelta : -mergedConfig.unfoldedZoomDelta;\n const newZoom = Math.max(3, Math.min(20, currentZoom + zoomDelta));\n\n await mapRef.current.moveCamera({\n target: mergedConfig.keepCenterOnFold ? currentCamera.target : undefined,\n zoom: newZoom,\n }, 300);\n }\n } catch (error) {\n if (mergedConfig.debug) {\n console.error('[useFoldableMap] 调整失败:');\n }\n }\n }\n }\n\n setFoldState(newFoldState);\n setDeviceInfo(newInfo);\n mergedConfig.onFoldStateChange(newFoldState, newInfo);\n }\n );\n\n const initialState = PlatformDetector.getFoldState();\n setFoldState(initialState);\n\n return () => {\n removeListener();\n };\n }, [foldState, deviceInfo.isFoldable]);\n\n return {\n foldState,\n deviceInfo,\n isFoldable: deviceInfo.isFoldable,\n };\n}"]}
|
|
1
|
+
{"version":3,"file":"FoldableMapView.js","sourceRoot":"","sources":["../../src/components/FoldableMapView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,gBAAgB,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAc,SAAS,EAAE,MAAM,2BAA2B,CAAC;AA6BpF,MAAM,uBAAuB,GAA6B;IACxD,cAAc,EAAE,IAAI;IACpB,iBAAiB,EAAE,CAAC;IACpB,gBAAgB,EAAE,IAAI;IACtB,iBAAiB,EAAE,GAAG,EAAE,GAAE,CAAC;IAC3B,KAAK,EAAE,KAAK;CACb,CAAC;AAEF,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,oBAAoB,CAAC,MAAuB;IACnD,OAAO;QACL,GAAG,uBAAuB;QAC1B,GAAG,MAAM;KACV,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,8BAA8B,CAC3C,MAA0C,EAC1C,QAAmB,EACnB,QAAmB,EACnB,MAAgC,EAChC,WAAiD;IAEjD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAC/D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,IAAI,WAAW,YAAY,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,KAAK,SAAS,CAAC,QAAQ,IAAI,QAAQ,KAAK,SAAS,CAAC,MAAM,CAAC;IACrF,MAAM,SAAS,GAAG,QAAQ,KAAK,SAAS,CAAC,MAAM,IAAI,QAAQ,KAAK,SAAS,CAAC,QAAQ,CAAC;IAEnF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,WAAW,EAAE;YACtC,QAAQ;YACR,QAAQ;YACR,WAAW;YACX,SAAS;YACT,WAAW,EAAE,aAAa,CAAC,IAAI;SAChC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,IAAI,EAAE,CAAC;IAC7C,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACrF,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAEzD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,SAAS,EAAE;YACpC,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,QAAQ;YACjB,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QAC9B,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QAClE,IAAI,EAAE,QAAQ;KACf,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAmC,CAAC,EAC9D,cAAc,EACd,GAAG,QAAQ,EACZ,EAAE,EAAE;IACH,MAAM,MAAM,GAAG,MAAM,CAAa,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAY,SAAS,CAAC,OAAO,CAAC,CAAC;IACvF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAa,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,cAAc,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IACrF,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;IAC7B,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,CAAC,OAAO,GAAG,gBAAgB,CAAC;IAC1C,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,aAAa,EAAE,CAAC;QAC1D,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAClC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,sBAAsB;QACtB,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YACxD,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,gBAAgB,CAAC,YAAY,EAAE,CAAC;QACrD,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC;QACpC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAElC,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACvC,CAAC;QAED,WAAW;QACX,MAAM,cAAc,GAAG,gBAAgB,CAAC,0BAA0B,CAChE,KAAK,EAAE,OAAmB,EAAE,EAAE;YAC5B,MAAM,YAAY,GAAG,gBAAgB,CAAC,YAAY,EAAE,CAAC;YACrD,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,CAAC;YAC/C,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC;YAEvC,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YACtC,CAAC;YAED,aAAa;YACb,IAAI,YAAY,KAAK,iBAAiB,IAAI,iBAAiB,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;gBAClF,IAAI,CAAC;oBACH,MAAM,8BAA8B,CAClC,MAAM,EACN,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,iBAAiB,CAClB,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;wBACvB,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;oBACxD,CAAC;gBACH,CAAC;YACH,CAAC;YAED,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC;YACpC,mBAAmB,CAAC,YAAY,CAAC,CAAC;YAClC,aAAa,CAAC,OAAO,CAAC,CAAC;YAEvB,OAAO;YACP,YAAY,CAAC,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC,CACF,CAAC;QAEF,OAAO,GAAG,EAAE;YACV,cAAc,EAAE,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAE5B,OAAO,CACL,CAAC,gBAAgB,CACf,GAAG,CAAC,CAAC,MAAM,CAAC,CACZ,IAAI,QAAQ,CAAC,EACb,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAmC,EACnC,MAAuB;IAEvB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAY,SAAS,CAAC,OAAO,CAAC,CAAC;IACzE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAa,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3F,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAEvC,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,CAAC,OAAO,GAAG,SAAS,CAAC;IACnC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,OAAO,GAAG,YAAY,CAAC;IACnC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YACxD,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,gBAAgB,CAAC,YAAY,EAAE,CAAC;QACrD,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC;QACpC,YAAY,CAAC,YAAY,CAAC,CAAC;QAE3B,MAAM,cAAc,GAAG,gBAAgB,CAAC,0BAA0B,CAChE,KAAK,EAAE,OAAmB,EAAE,EAAE;YAC5B,MAAM,YAAY,GAAG,gBAAgB,CAAC,YAAY,EAAE,CAAC;YACrD,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,CAAC;YAC/C,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC;YAEvC,IAAI,YAAY,KAAK,iBAAiB,IAAI,iBAAiB,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;gBAClF,IAAI,CAAC;oBACH,MAAM,8BAA8B,CAClC,MAAM,EACN,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,gBAAgB,CACjB,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;wBACvB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;oBACjD,CAAC;gBACH,CAAC;YACH,CAAC;YAED,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC;YACpC,YAAY,CAAC,YAAY,CAAC,CAAC;YAC3B,aAAa,CAAC,OAAO,CAAC,CAAC;YACvB,YAAY,CAAC,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC,CACF,CAAC;QAEF,OAAO,GAAG,EAAE;YACV,cAAc,EAAE,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAEpC,OAAO;QACL,SAAS;QACT,UAAU;QACV,UAAU,EAAE,UAAU,CAAC,UAAU;KAClC,CAAC;AACJ,CAAC","sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { Platform } from 'react-native';\nimport ExpoGaodeMapView from '../ExpoGaodeMapView';\n\nimport { PlatformDetector, DeviceInfo, FoldState } from '../utils/PlatformDetector';\nimport { MapViewProps, MapViewRef } from '../types';\n\n/**\n * 折叠屏适配配置\n */\nexport interface FoldableConfig {\n /** 折叠时是否自动调整缩放级别 */\n autoAdjustZoom?: boolean;\n /** 展开时的缩放级别增量 */\n unfoldedZoomDelta?: number;\n /** 是否在折叠/展开时保持中心点 */\n keepCenterOnFold?: boolean;\n /** 折叠状态变化回调 */\n onFoldStateChange?: (state: FoldState, deviceInfo: DeviceInfo) => void;\n /** 是否启用调试日志 */\n debug?: boolean;\n}\n\n/**\n * 折叠屏地图视图组件\n * \n * 自动适配折叠屏设备的展开/折叠状态变化\n */\nexport interface FoldableMapViewProps extends MapViewProps {\n /** 折叠屏适配配置 */\n foldableConfig?: FoldableConfig;\n}\n\nconst DEFAULT_FOLDABLE_CONFIG: Required<FoldableConfig> = {\n autoAdjustZoom: true,\n unfoldedZoomDelta: 1,\n keepCenterOnFold: true,\n onFoldStateChange: () => {},\n debug: false,\n};\n\nfunction clampZoomLevel(zoom: number): number {\n return Math.max(3, Math.min(20, zoom));\n}\n\nfunction createFoldableConfig(config?: FoldableConfig): Required<FoldableConfig> {\n return {\n ...DEFAULT_FOLDABLE_CONFIG,\n ...config,\n };\n}\n\nasync function applyFoldStateCameraAdjustment(\n mapRef: React.RefObject<MapViewRef | null>,\n oldState: FoldState,\n newState: FoldState,\n config: Required<FoldableConfig>,\n debugPrefix: 'FoldableMapView' | 'useFoldableMap'\n): Promise<void> {\n if (!mapRef.current || !config.autoAdjustZoom) {\n return;\n }\n\n const currentCamera = await mapRef.current.getCameraPosition();\n if (!currentCamera) {\n if (config.debug) {\n console.warn(`[${debugPrefix}] 无法获取相机位置`);\n }\n return;\n }\n\n const isUnfolding = newState === FoldState.UNFOLDED && oldState === FoldState.FOLDED;\n const isFolding = newState === FoldState.FOLDED && oldState === FoldState.UNFOLDED;\n\n if (config.debug) {\n console.log(`[${debugPrefix}] 折叠状态变化:`, {\n oldState,\n newState,\n isUnfolding,\n isFolding,\n currentZoom: currentCamera.zoom,\n });\n }\n\n if (!isUnfolding && !isFolding) {\n return;\n }\n\n const currentZoom = currentCamera.zoom ?? 15;\n const zoomDelta = isUnfolding ? config.unfoldedZoomDelta : -config.unfoldedZoomDelta;\n const nextZoom = clampZoomLevel(currentZoom + zoomDelta);\n\n if (config.debug) {\n console.log(`[${debugPrefix}] 调整缩放:`, {\n oldZoom: currentZoom,\n newZoom: nextZoom,\n delta: zoomDelta,\n });\n }\n\n await mapRef.current.moveCamera({\n target: config.keepCenterOnFold ? currentCamera.target : undefined,\n zoom: nextZoom,\n }, 300);\n}\n\nexport const FoldableMapView: React.FC<FoldableMapViewProps> = ({\n foldableConfig,\n ...mapProps\n}) => {\n const mapRef = useRef<MapViewRef>(null);\n const [currentFoldState, setCurrentFoldState] = useState<FoldState>(FoldState.UNKNOWN);\n const [deviceInfo, setDeviceInfo] = useState<DeviceInfo>(PlatformDetector.getDeviceInfo());\n const config = useMemo(() => createFoldableConfig(foldableConfig), [foldableConfig]);\n const configRef = useRef(config);\n const foldStateRef = useRef(currentFoldState);\n\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n useEffect(() => {\n foldStateRef.current = currentFoldState;\n }, [currentFoldState]);\n\n useEffect(() => {\n const latestDeviceInfo = PlatformDetector.getDeviceInfo();\n setDeviceInfo(latestDeviceInfo);\n }, []);\n\n useEffect(() => {\n // 仅在 Android 折叠屏设备上启用\n if (Platform.OS !== 'android' || !deviceInfo.isFoldable) {\n if (configRef.current.debug) {\n console.log('[FoldableMapView] 非折叠屏设备,跳过适配');\n }\n return;\n }\n\n const initialState = PlatformDetector.getFoldState();\n foldStateRef.current = initialState;\n setCurrentFoldState(initialState);\n\n if (configRef.current.debug) {\n console.log('[FoldableMapView] 初始化折叠屏适配');\n console.log('设备信息:', deviceInfo);\n console.log('初始折叠状态:', initialState);\n }\n\n // 监听屏幕尺寸变化\n const removeListener = PlatformDetector.addDimensionChangeListener(\n async (newInfo: DeviceInfo) => {\n const newFoldState = PlatformDetector.getFoldState();\n const previousFoldState = foldStateRef.current;\n const latestConfig = configRef.current;\n \n if (latestConfig.debug) {\n console.log('[FoldableMapView] 屏幕尺寸变化');\n console.log('新设备信息:', newInfo);\n console.log('新折叠状态:', newFoldState);\n }\n\n // 折叠状态变化时的处理\n if (newFoldState !== previousFoldState && previousFoldState !== FoldState.UNKNOWN) {\n try {\n await applyFoldStateCameraAdjustment(\n mapRef,\n previousFoldState,\n newFoldState,\n latestConfig,\n 'FoldableMapView'\n );\n } catch (error) {\n if (latestConfig.debug) {\n console.error('[FoldableMapView] 处理折叠状态变化失败:', error);\n }\n }\n }\n\n foldStateRef.current = newFoldState;\n setCurrentFoldState(newFoldState);\n setDeviceInfo(newInfo);\n \n // 触发回调\n latestConfig.onFoldStateChange(newFoldState, newInfo);\n }\n );\n\n return () => {\n removeListener();\n };\n }, [deviceInfo.isFoldable]);\n\n return (\n <ExpoGaodeMapView\n ref={mapRef}\n {...mapProps}\n />\n );\n};\n\n/**\n * 折叠屏适配 Hook\n * \n * 用于在现有地图组件中添加折叠屏适配功能\n */\nexport function useFoldableMap(\n mapRef: React.RefObject<MapViewRef>,\n config?: FoldableConfig\n) {\n const [foldState, setFoldState] = useState<FoldState>(FoldState.UNKNOWN);\n const [deviceInfo, setDeviceInfo] = useState<DeviceInfo>(PlatformDetector.getDeviceInfo());\n const mergedConfig = useMemo(() => createFoldableConfig(config), [config]);\n const foldStateRef = useRef(foldState);\n const configRef = useRef(mergedConfig);\n\n useEffect(() => {\n foldStateRef.current = foldState;\n }, [foldState]);\n\n useEffect(() => {\n configRef.current = mergedConfig;\n }, [mergedConfig]);\n\n useEffect(() => {\n if (Platform.OS !== 'android' || !deviceInfo.isFoldable) {\n return;\n }\n\n const initialState = PlatformDetector.getFoldState();\n foldStateRef.current = initialState;\n setFoldState(initialState);\n\n const removeListener = PlatformDetector.addDimensionChangeListener(\n async (newInfo: DeviceInfo) => {\n const newFoldState = PlatformDetector.getFoldState();\n const previousFoldState = foldStateRef.current;\n const latestConfig = configRef.current;\n \n if (newFoldState !== previousFoldState && previousFoldState !== FoldState.UNKNOWN) {\n try {\n await applyFoldStateCameraAdjustment(\n mapRef,\n previousFoldState,\n newFoldState,\n latestConfig,\n 'useFoldableMap'\n );\n } catch (error) {\n if (latestConfig.debug) {\n console.error('[useFoldableMap] 调整失败:', error);\n }\n }\n }\n\n foldStateRef.current = newFoldState;\n setFoldState(newFoldState);\n setDeviceInfo(newInfo);\n latestConfig.onFoldStateChange(newFoldState, newInfo);\n }\n );\n\n return () => {\n removeListener();\n };\n }, [deviceInfo.isFoldable, mapRef]);\n\n return {\n foldState,\n deviceInfo,\n isFoldable: deviceInfo.isFoldable,\n };\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { RouteOverlayProps } from '../types/route-playback.types';
|
|
3
|
+
export declare function RouteOverlay({ points, showStartMarker, showEndMarker, polylineProps, startMarkerProps, endMarkerProps, }: RouteOverlayProps): React.JSX.Element | null;
|
|
4
|
+
export default RouteOverlay;
|
|
5
|
+
//# sourceMappingURL=RouteOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouteOverlay.d.ts","sourceRoot":"","sources":["../../src/components/RouteOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,eAAsB,EACtB,aAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,cAAc,GACf,EAAE,iBAAiB,4BAuCnB;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { normalizeLatLngList } from '../utils/GeoUtils';
|
|
3
|
+
import { Marker, Polyline } from './overlays';
|
|
4
|
+
export function RouteOverlay({ points, showStartMarker = true, showEndMarker = true, polylineProps, startMarkerProps, endMarkerProps, }) {
|
|
5
|
+
// 统一封装“主路径 + 起点 + 终点”的常见展示组合,
|
|
6
|
+
// 这样业务侧不需要每次手动拼装 3 个覆盖物。
|
|
7
|
+
const normalizedPoints = React.useMemo(() => normalizeLatLngList(points), [points]);
|
|
8
|
+
if (normalizedPoints.length === 0) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const start = normalizedPoints[0];
|
|
12
|
+
const end = normalizedPoints[normalizedPoints.length - 1];
|
|
13
|
+
return (<>
|
|
14
|
+
<Polyline points={normalizedPoints} strokeWidth={polylineProps?.strokeWidth ?? 6} strokeColor={polylineProps?.strokeColor ?? '#2563eb'} {...polylineProps}/>
|
|
15
|
+
{showStartMarker ? (<Marker position={start} title={startMarkerProps?.title ?? '起点'} {...startMarkerProps}/>) : null}
|
|
16
|
+
{showEndMarker ? (<Marker position={end} title={endMarkerProps?.title ?? '终点'} {...endMarkerProps}/>) : null}
|
|
17
|
+
</>);
|
|
18
|
+
}
|
|
19
|
+
export default RouteOverlay;
|
|
20
|
+
//# sourceMappingURL=RouteOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouteOverlay.js","sourceRoot":"","sources":["../../src/components/RouteOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,UAAU,YAAY,CAAC,EAC3B,MAAM,EACN,eAAe,GAAG,IAAI,EACtB,aAAa,GAAG,IAAI,EACpB,aAAa,EACb,gBAAgB,EAChB,cAAc,GACI;IAClB,8BAA8B;IAC9B,yBAAyB;IACzB,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CACpC,GAAG,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,EACjC,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE1D,OAAO,CACL,EACE;MAAA,CAAC,QAAQ,CACP,MAAM,CAAC,CAAC,gBAAgB,CAAC,CACzB,WAAW,CAAC,CAAC,aAAa,EAAE,WAAW,IAAI,CAAC,CAAC,CAC7C,WAAW,CAAC,CAAC,aAAa,EAAE,WAAW,IAAI,SAAS,CAAC,CACrD,IAAI,aAAa,CAAC,EAEpB;MAAA,CAAC,eAAe,CAAC,CAAC,CAAC,CACjB,CAAC,MAAM,CACL,QAAQ,CAAC,CAAC,KAAK,CAAC,CAChB,KAAK,CAAC,CAAC,gBAAgB,EAAE,KAAK,IAAI,IAAI,CAAC,CACvC,IAAI,gBAAgB,CAAC,EACrB,CACH,CAAC,CAAC,CAAC,IAAI,CACR;MAAA,CAAC,aAAa,CAAC,CAAC,CAAC,CACf,CAAC,MAAM,CACL,QAAQ,CAAC,CAAC,GAAG,CAAC,CACd,KAAK,CAAC,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI,CAAC,CACrC,IAAI,cAAc,CAAC,EACnB,CACH,CAAC,CAAC,CAAC,IAAI,CACV;IAAA,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC","sourcesContent":["import * as React from 'react';\n\nimport type { RouteOverlayProps } from '../types/route-playback.types';\nimport { normalizeLatLngList } from '../utils/GeoUtils';\nimport { Marker, Polyline } from './overlays';\n\nexport function RouteOverlay({\n points,\n showStartMarker = true,\n showEndMarker = true,\n polylineProps,\n startMarkerProps,\n endMarkerProps,\n}: RouteOverlayProps) {\n // 统一封装“主路径 + 起点 + 终点”的常见展示组合,\n // 这样业务侧不需要每次手动拼装 3 个覆盖物。\n const normalizedPoints = React.useMemo(\n () => normalizeLatLngList(points),\n [points]\n );\n\n if (normalizedPoints.length === 0) {\n return null;\n }\n\n const start = normalizedPoints[0];\n const end = normalizedPoints[normalizedPoints.length - 1];\n\n return (\n <>\n <Polyline\n points={normalizedPoints}\n strokeWidth={polylineProps?.strokeWidth ?? 6}\n strokeColor={polylineProps?.strokeColor ?? '#2563eb'}\n {...polylineProps}\n />\n {showStartMarker ? (\n <Marker\n position={start}\n title={startMarkerProps?.title ?? '起点'}\n {...startMarkerProps}\n />\n ) : null}\n {showEndMarker ? (\n <Marker\n position={end}\n title={endMarkerProps?.title ?? '终点'}\n {...endMarkerProps}\n />\n ) : null}\n </>\n );\n}\n\nexport default RouteOverlay;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Cluster.d.ts","sourceRoot":"","sources":["../../../src/components/overlays/Cluster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD;;;;;GAKG;AACH,iBAAS,OAAO,CAAC,KAAK,EAAE,YAAY,qBAGnC;;
|
|
1
|
+
{"version":3,"file":"Cluster.d.ts","sourceRoot":"","sources":["../../../src/components/overlays/Cluster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD;;;;;GAKG;AACH,iBAAS,OAAO,CAAC,KAAK,EAAE,YAAY,qBAGnC;;AAoDD,wBAAkD"}
|
|
@@ -24,10 +24,22 @@ function arePropsEqual(prevProps, nextProps) {
|
|
|
24
24
|
if (prevProps.radius !== nextProps.radius) {
|
|
25
25
|
return false;
|
|
26
26
|
}
|
|
27
|
+
// 比较基础图标
|
|
28
|
+
if (prevProps.icon !== nextProps.icon) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
27
31
|
// 比较 minClusterSize
|
|
28
32
|
if (prevProps.minClusterSize !== nextProps.minClusterSize) {
|
|
29
33
|
return false;
|
|
30
34
|
}
|
|
35
|
+
// 比较聚合样式
|
|
36
|
+
if (prevProps.clusterStyle !== nextProps.clusterStyle) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
// 比较聚合文本样式
|
|
40
|
+
if (prevProps.clusterTextStyle !== nextProps.clusterTextStyle) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
31
43
|
// 比较 clusterBuckets
|
|
32
44
|
if (prevProps.clusterBuckets !== nextProps.clusterBuckets) {
|
|
33
45
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Cluster.js","sourceRoot":"","sources":["../../../src/components/overlays/Cluster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAEhF,MAAM,gBAAgB,GAAG,2BAA2B,CAAe,aAAa,CAAC,CAAC;AAElF;;;;;GAKG;AACH,SAAS,OAAO,CAAC,KAAmB;IAClC,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,SAAuB,EAAE,SAAuB;IACrE,uBAAuB;IACvB,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY;IACZ,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB;IACpB,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB;IACpB,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uBAAuB;IACvB,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,eAAe;IACf,OAAO,IAAI,CAAC;AACd,CAAC;AAED,WAAW;AACX,eAAe,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport type { ClusterProps } from '../../types';\nimport { createLazyNativeViewManager } from '../../utils/lazyNativeViewManager';\n\nconst getNativeCluster = createLazyNativeViewManager<ClusterProps>('ClusterView');\n\n/**\n * 高德地图点聚合组件\n *\n * @param props 点聚合组件的属性配置\n * @returns 渲染原生点聚合组件\n */\nfunction Cluster(props: ClusterProps) {\n const NativeCluster = React.useMemo(() => getNativeCluster(), []);\n return <NativeCluster {...props} />;\n}\n\n/**\n * 🔑 性能优化:浅比较关键属性\n * 只检查最常变化的属性,避免深度比较开销\n */\nfunction arePropsEqual(prevProps: ClusterProps, nextProps: ClusterProps): boolean {\n // 比较 points 数组引用(最常变化)\n if (prevProps.points !== nextProps.points) {\n return false;\n }\n \n // 比较 radius\n if (prevProps.radius !== nextProps.radius) {\n return false;\n }\n \n // 比较 minClusterSize\n if (prevProps.minClusterSize !== nextProps.minClusterSize) {\n return false;\n }\n \n // 比较 clusterBuckets\n if (prevProps.clusterBuckets !== nextProps.clusterBuckets) {\n return false;\n }\n \n // 比较 onClusterPress 回调\n if (prevProps.onClusterPress !== nextProps.onClusterPress) {\n return false;\n }\n \n // 其他属性相同,不重新渲染\n return true;\n}\n\n// 导出优化后的组件\nexport default React.memo(Cluster, arePropsEqual);\n"]}
|
|
1
|
+
{"version":3,"file":"Cluster.js","sourceRoot":"","sources":["../../../src/components/overlays/Cluster.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAEhF,MAAM,gBAAgB,GAAG,2BAA2B,CAAe,aAAa,CAAC,CAAC;AAElF;;;;;GAKG;AACH,SAAS,OAAO,CAAC,KAAmB;IAClC,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,SAAuB,EAAE,SAAuB;IACrE,uBAAuB;IACvB,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY;IACZ,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS;IACT,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB;IACpB,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS;IACT,IAAI,SAAS,CAAC,YAAY,KAAK,SAAS,CAAC,YAAY,EAAE,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,WAAW;IACX,IAAI,SAAS,CAAC,gBAAgB,KAAK,SAAS,CAAC,gBAAgB,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB;IACpB,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uBAAuB;IACvB,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,eAAe;IACf,OAAO,IAAI,CAAC;AACd,CAAC;AAED,WAAW;AACX,eAAe,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport type { ClusterProps } from '../../types';\nimport { createLazyNativeViewManager } from '../../utils/lazyNativeViewManager';\n\nconst getNativeCluster = createLazyNativeViewManager<ClusterProps>('ClusterView');\n\n/**\n * 高德地图点聚合组件\n *\n * @param props 点聚合组件的属性配置\n * @returns 渲染原生点聚合组件\n */\nfunction Cluster(props: ClusterProps) {\n const NativeCluster = React.useMemo(() => getNativeCluster(), []);\n return <NativeCluster {...props} />;\n}\n\n/**\n * 🔑 性能优化:浅比较关键属性\n * 只检查最常变化的属性,避免深度比较开销\n */\nfunction arePropsEqual(prevProps: ClusterProps, nextProps: ClusterProps): boolean {\n // 比较 points 数组引用(最常变化)\n if (prevProps.points !== nextProps.points) {\n return false;\n }\n \n // 比较 radius\n if (prevProps.radius !== nextProps.radius) {\n return false;\n }\n\n // 比较基础图标\n if (prevProps.icon !== nextProps.icon) {\n return false;\n }\n \n // 比较 minClusterSize\n if (prevProps.minClusterSize !== nextProps.minClusterSize) {\n return false;\n }\n\n // 比较聚合样式\n if (prevProps.clusterStyle !== nextProps.clusterStyle) {\n return false;\n }\n\n // 比较聚合文本样式\n if (prevProps.clusterTextStyle !== nextProps.clusterTextStyle) {\n return false;\n }\n \n // 比较 clusterBuckets\n if (prevProps.clusterBuckets !== nextProps.clusterBuckets) {\n return false;\n }\n \n // 比较 onClusterPress 回调\n if (prevProps.onClusterPress !== nextProps.onClusterPress) {\n return false;\n }\n \n // 其他属性相同,不重新渲染\n return true;\n}\n\n// 导出优化后的组件\nexport default React.memo(Cluster, arePropsEqual);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Marker.d.ts","sourceRoot":"","sources":["../../../src/components/overlays/Marker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"Marker.d.ts","sourceRoot":"","sources":["../../../src/components/overlays/Marker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA6C/C;;;;;;;;;GASG;AACH,iBAAS,MAAM,CAAC,KAAK,EAAE,WAAW,qBAyJjC;;AAsDD,wBAAiD"}
|
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Platform, StyleSheet, View } from 'react-native';
|
|
3
|
+
import ExpoGaodeMapModule from '../../ExpoGaodeMapModule';
|
|
3
4
|
import { normalizeLatLng, normalizeLatLngList } from '../../utils/GeoUtils';
|
|
4
5
|
import { createLazyNativeViewManager } from '../../utils/lazyNativeViewManager';
|
|
5
6
|
const getNativeMarkerView = createLazyNativeViewManager('MarkerView');
|
|
6
7
|
const AUTO_SIZE_FALLBACK = { width: 0, height: 0 };
|
|
8
|
+
function areSmoothMovePathsEqual(prevPath, nextPath) {
|
|
9
|
+
if (prevPath === nextPath) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (!prevPath || !nextPath) {
|
|
13
|
+
return prevPath === nextPath;
|
|
14
|
+
}
|
|
15
|
+
if (prevPath.length !== nextPath.length) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
for (let index = 0; index < prevPath.length; index += 1) {
|
|
19
|
+
const prevPoint = normalizeLatLng(prevPath[index]);
|
|
20
|
+
const nextPoint = normalizeLatLng(nextPath[index]);
|
|
21
|
+
if (prevPoint.latitude !== nextPoint.latitude ||
|
|
22
|
+
prevPoint.longitude !== nextPoint.longitude) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
7
28
|
/**
|
|
8
29
|
* Marker 组件 - 完全声明式 API
|
|
9
30
|
*
|
|
@@ -18,7 +39,7 @@ function Marker(props) {
|
|
|
18
39
|
const NativeMarkerView = React.useMemo(() => getNativeMarkerView(), []);
|
|
19
40
|
const [measuredSize, setMeasuredSize] = React.useState(AUTO_SIZE_FALLBACK);
|
|
20
41
|
// 从 props 中排除 position 属性,避免传递到原生层
|
|
21
|
-
const { position, customViewWidth, customViewHeight, iconWidth, iconHeight, children, smoothMovePath, ...restProps } = props;
|
|
42
|
+
const { position, customViewWidth, customViewHeight, iconWidth, iconHeight, children, smoothMovePath, cacheKey, ...restProps } = props;
|
|
22
43
|
// 归一化坐标处理
|
|
23
44
|
const normalizedPosition = normalizeLatLng(position);
|
|
24
45
|
const normalizedSmoothMovePath = smoothMovePath ? normalizeLatLngList(smoothMovePath) : undefined;
|
|
@@ -32,6 +53,67 @@ function Marker(props) {
|
|
|
32
53
|
const resolvedCustomViewHeight = customViewHeight && customViewHeight > 0
|
|
33
54
|
? customViewHeight
|
|
34
55
|
: (shouldUseAutoMeasuredSize ? measuredSize.height : 0);
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
if (!normalizedSmoothMovePath ||
|
|
58
|
+
normalizedSmoothMovePath.length < 2 ||
|
|
59
|
+
!props.smoothMoveDuration ||
|
|
60
|
+
props.smoothMoveDuration <= 0) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const totalDistance = ExpoGaodeMapModule.calculatePathLength(normalizedSmoothMovePath);
|
|
64
|
+
if (totalDistance <= 0) {
|
|
65
|
+
props.onSmoothMoveEnd?.({
|
|
66
|
+
nativeEvent: {
|
|
67
|
+
position: normalizedSmoothMovePath[normalizedSmoothMovePath.length - 1],
|
|
68
|
+
angle: 0,
|
|
69
|
+
totalDistance,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const durationMs = props.smoothMoveDuration * 1000;
|
|
75
|
+
const startedAt = Date.now();
|
|
76
|
+
const tick = () => {
|
|
77
|
+
const progress = Math.min(1, (Date.now() - startedAt) / durationMs);
|
|
78
|
+
const distance = totalDistance * progress;
|
|
79
|
+
const pointInfo = ExpoGaodeMapModule.getPointAtDistance(normalizedSmoothMovePath, distance);
|
|
80
|
+
const point = pointInfo
|
|
81
|
+
? { latitude: pointInfo.latitude, longitude: pointInfo.longitude }
|
|
82
|
+
: normalizedSmoothMovePath[normalizedSmoothMovePath.length - 1];
|
|
83
|
+
const angle = pointInfo?.angle ?? 0;
|
|
84
|
+
props.onSmoothMoveProgress?.({
|
|
85
|
+
nativeEvent: {
|
|
86
|
+
position: point,
|
|
87
|
+
angle,
|
|
88
|
+
progress,
|
|
89
|
+
distance,
|
|
90
|
+
totalDistance,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
if (progress >= 1) {
|
|
94
|
+
props.onSmoothMoveEnd?.({
|
|
95
|
+
nativeEvent: {
|
|
96
|
+
position: point,
|
|
97
|
+
angle,
|
|
98
|
+
totalDistance,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
tick();
|
|
104
|
+
const intervalId = setInterval(() => {
|
|
105
|
+
tick();
|
|
106
|
+
if (Date.now() - startedAt >= durationMs) {
|
|
107
|
+
clearInterval(intervalId);
|
|
108
|
+
}
|
|
109
|
+
}, 100);
|
|
110
|
+
return () => clearInterval(intervalId);
|
|
111
|
+
}, [
|
|
112
|
+
normalizedSmoothMovePath,
|
|
113
|
+
props.onSmoothMoveEnd,
|
|
114
|
+
props.onSmoothMoveProgress,
|
|
115
|
+
props.smoothMoveDuration,
|
|
116
|
+
]);
|
|
35
117
|
const handleAutoMeasure = (event) => {
|
|
36
118
|
const nextWidth = customViewWidth && customViewWidth > 0
|
|
37
119
|
? customViewWidth
|
|
@@ -54,7 +136,8 @@ function Marker(props) {
|
|
|
54
136
|
const finalIconHeight = hasChildren
|
|
55
137
|
? resolvedCustomViewHeight
|
|
56
138
|
: (iconHeight && iconHeight > 0 ? iconHeight : 40);
|
|
57
|
-
|
|
139
|
+
const optionalNativeProps = cacheKey != null ? { cacheKey } : undefined;
|
|
140
|
+
return (<NativeMarkerView latitude={normalizedPosition.latitude} longitude={normalizedPosition.longitude} iconWidth={finalIconWidth} iconHeight={finalIconHeight} customViewWidth={finalIconWidth} customViewHeight={finalIconHeight} smoothMovePath={normalizedSmoothMovePath} {...optionalNativeProps} {...restProps}>
|
|
58
141
|
{hasChildren && shouldWrapChildrenForMeasurement ? (<View collapsable={false} onLayout={Platform.OS === 'ios' ? handleAutoMeasure : undefined} style={styles.measureContainer}>
|
|
59
142
|
{children}
|
|
60
143
|
</View>) : children}
|
|
@@ -89,7 +172,7 @@ function arePropsEqual(prevProps, nextProps) {
|
|
|
89
172
|
return false;
|
|
90
173
|
}
|
|
91
174
|
// 比较 smoothMovePath (平滑移动路径)
|
|
92
|
-
if (
|
|
175
|
+
if (!areSmoothMovePathsEqual(prevProps.smoothMovePath, nextProps.smoothMovePath)) {
|
|
93
176
|
return false;
|
|
94
177
|
}
|
|
95
178
|
// 比较 smoothMoveDuration (平滑移动时长)
|