@heycar/heycars-map 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +122 -11
  2. package/dist/api/geometry.d.ts +1 -2
  3. package/dist/business-components/DrivingLine/DrivingLine.d.ts +1 -0
  4. package/dist/business-components/DrivingRoute/DrivingRoute.d.ts +13 -0
  5. package/dist/business-components/DrivingRoute/index.d.ts +1 -0
  6. package/dist/business-components/PickupPoints/PickupPoints.d.ts +5 -0
  7. package/dist/business-components/PickupPoints/index.d.ts +1 -0
  8. package/dist/business-components/PlaceCircle/PlaceCircle.css.d.ts +28 -3
  9. package/dist/business-components/PlaceCircle/PlaceCircle.d.ts +2 -2
  10. package/dist/components/Amap/Amap.d.ts +9 -6
  11. package/dist/components/Demo/HeycarDemo.d.ts +1 -1
  12. package/dist/components/Gmap/Gmap.d.ts +7 -5
  13. package/dist/components/MapProvider/MapProvider.d.ts +6 -2
  14. package/dist/hooks/useDrivingRoute.d.ts +9 -0
  15. package/dist/hooks/useHeycarMap.d.ts +1601 -0
  16. package/dist/hooks/useMapAngle.d.ts +10 -0
  17. package/dist/hooks/useMapDrag.d.ts +33 -0
  18. package/dist/index.cjs +56 -56
  19. package/dist/index.d.ts +6 -2
  20. package/dist/index.js +1133 -838
  21. package/dist/style.css +1 -1
  22. package/dist/types/helper.d.ts +5 -2
  23. package/dist/types/interface.d.ts +3 -0
  24. package/dist/types/mapHelper.d.ts +3 -0
  25. package/dist/utils/transform.d.ts +2 -0
  26. package/package.json +1 -1
  27. package/src/api/geometry.ts +2 -1
  28. package/src/business-components/DrivingLine/DrivingLine.tsx +15 -7
  29. package/src/business-components/DrivingRoute/DrivingRoute.tsx +48 -0
  30. package/src/business-components/DrivingRoute/index.ts +1 -0
  31. package/src/business-components/PickupPoints/PickupPoints.tsx +16 -0
  32. package/src/business-components/PickupPoints/index.ts +1 -0
  33. package/src/business-components/PlaceCircle/PlaceCircle.css.ts +39 -8
  34. package/src/business-components/PlaceCircle/PlaceCircle.tsx +22 -7
  35. package/src/business-components/TaxiCar/TaxiCar.tsx +3 -2
  36. package/src/components/Amap/Amap.ts +23 -5
  37. package/src/components/AmapLoader/AmapLoader.ts +1 -1
  38. package/src/components/Demo/HeycarDemo.tsx +38 -17
  39. package/src/components/Gmap/Gmap.ts +14 -7
  40. package/src/components/MapProvider/MapProvider.tsx +30 -17
  41. package/src/hooks/useDrivingRoute.ts +73 -0
  42. package/src/hooks/useHeycarMap.ts +28 -0
  43. package/src/hooks/useMapAngle.ts +43 -0
  44. package/src/hooks/useMapDrag.ts +81 -0
  45. package/src/index.ts +6 -2
  46. package/src/types/amap/driving.d.ts +2 -0
  47. package/src/types/helper.ts +38 -8
  48. package/src/types/interface.ts +3 -0
  49. package/src/types/mapHelper.ts +1 -0
  50. package/src/utils/transform.ts +10 -0
  51. package/dist/hooks/useMapCenter.d.ts +0 -30
  52. package/src/hooks/useMapCenter.ts +0 -70
@@ -1,10 +1,9 @@
1
- import { debounce } from "lodash-es";
2
- import { ON_CHANGE_CENTER_INTERVAL } from "../../hooks/useMapCenter";
3
- import { defineLagecySetup, defineSetup } from "../../types/helper";
4
- import { vec2lnglat } from "../../utils/transform";
1
+ import type { SetMap } from "../../hooks/useHeycarMap";
2
+ import { defineLagecySetup } from "../../types/helper";
3
+ import { language2vectorMapForeign, vec2lnglat } from "../../utils/transform";
5
4
  import { Amap, AmapProps } from "../Amap";
6
5
  import { AmapLoader } from "../AmapLoader";
7
- import { GampProps, Gmap } from "../Gmap";
6
+ import { Gmap, GmapProps } from "../Gmap";
8
7
  import { GmapLoader, GmapLoaderProps } from "../GmapLoader";
9
8
  import { MapSupplierPayolad, provideMapSupplier, useMapSupplier } from "./useMapSupplier";
10
9
 
@@ -20,37 +19,45 @@ export const MapProvider = defineLagecySetup(function MapProvider(
20
19
  export interface HeycarMapProps
21
20
  extends Pick<GmapLoaderProps, "fallback" | "loading">,
22
21
  Pick<AmapProps, "center" | "zoom"> {
23
- onChangeCenter?: (value: [number, number]) => any;
22
+ language?: "en" | "zh";
23
+ mapRef?: SetMap<AMap.Map> | SetMap<google.maps.Map>;
24
+ onDragEnd?: (value: [number, number]) => any;
24
25
  }
25
- export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, { slots, emit }) {
26
+ export const HeycarMap = defineLagecySetup(function HeycarMap(
27
+ props: HeycarMapProps,
28
+ { slots, emit }
29
+ ) {
26
30
  const payload = useMapSupplier();
27
- const gmapDebouncedEmit = debounce<Required<GampProps>["onCenter_changed"]>(({ target }) => {
31
+ const gmapDebouncedEmit: GmapProps["onDragEnd"] = ({ target }) => {
28
32
  const { lng, lat } = target.getCenter() as google.maps.LatLng;
29
- emit("changeCenter", [lng(), lat()]);
30
- }, ON_CHANGE_CENTER_INTERVAL);
31
- const amapDebounceEmit = debounce<Required<AmapProps>["onMapMove"]>(({ target }) => {
33
+ emit("dragEnd", [lng(), lat()]);
34
+ };
35
+ const amapDebounceEmit: AmapProps["onDragEnd"] = ({ target }) => {
32
36
  const { lng, lat } = target.getCenter();
33
- emit("changeCenter", [lng, lat]);
34
- }, ON_CHANGE_CENTER_INTERVAL);
37
+ emit("dragEnd", [lng, lat]);
38
+ };
35
39
  return () => {
36
40
  const { gmapKey, amapKey, amapSecret, amapServiceHost, supplier, gmapId } = payload;
37
- const { fallback, loading, center, zoom } = props;
41
+ const { mapRef: setMap, center, zoom, language = "zh" } = props;
42
+ const { fallback, loading } = slots;
38
43
  const children = slots.default?.();
39
44
  switch (supplier) {
40
45
  case "gmap":
41
46
  return (
42
47
  <GmapLoader
43
48
  apiKey={gmapKey}
49
+ language={language}
44
50
  version="beta"
45
51
  libraries={["marker", "places", "geometry"]}
46
52
  loading={loading}
47
53
  fallback={fallback}
48
54
  >
49
55
  <Gmap
56
+ mapRef={setMap as SetMap<google.maps.Map>}
50
57
  mapId={gmapId}
51
58
  center={center ? vec2lnglat(center) : undefined}
52
59
  zoom={zoom}
53
- onCenter_changed={gmapDebouncedEmit}
60
+ onDragEnd={gmapDebouncedEmit}
54
61
  >
55
62
  {children}
56
63
  </Gmap>
@@ -72,11 +79,17 @@ export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, {
72
79
  loading={loading}
73
80
  fallback={fallback}
74
81
  >
75
- <Amap center={center} zoom={zoom} onMapMove={amapDebounceEmit}>
82
+ <Amap
83
+ mapRef={setMap as SetMap<AMap.Map>}
84
+ vectorMapForeign={language2vectorMapForeign(language)}
85
+ center={center}
86
+ zoom={zoom}
87
+ onDragEnd={amapDebounceEmit}
88
+ >
76
89
  {children}
77
90
  </Amap>
78
91
  </AmapLoader>
79
92
  );
80
93
  }
81
94
  };
82
- });
95
+ }).props(["center", "fallback", "loading", "mapRef", "zoom"]);
@@ -0,0 +1,73 @@
1
+ import { ShallowRef, shallowRef, watch } from "vue-demi";
2
+ import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
3
+ import type { Point } from "../types/interface";
4
+
5
+ export interface UseDrivingRouteProps {
6
+ from: Point;
7
+ to: Point;
8
+ }
9
+
10
+ export const useADrivingRoute = (props: UseDrivingRouteProps) => {
11
+ const pathRef = shallowRef<Point[]>([]);
12
+ const amapDriving = new AMap.Driving({});
13
+ watch(
14
+ [() => props.from, () => props.to],
15
+ ([from, to]) => {
16
+ amapDriving.search(
17
+ AMap.LngLat.from(from),
18
+ AMap.LngLat.from(to),
19
+ { waypoints: [] },
20
+ (status, result) => {
21
+ switch (status) {
22
+ case "complete": {
23
+ let path: Point[] = [];
24
+ const drivingResult = result as AMap.DrivingResult;
25
+ for (const route of drivingResult.routes) {
26
+ for (const step of route.steps) {
27
+ const basicStep = step as AMap.DriveStepBasic;
28
+ const stepPath = basicStep.path.map<Point>(({ lng, lat }) => [lng, lat]);
29
+ path = path.concat(stepPath);
30
+ }
31
+ }
32
+ pathRef.value = path;
33
+ return;
34
+ }
35
+ case "no_data":
36
+ return;
37
+ default:
38
+ throw result;
39
+ }
40
+ }
41
+ );
42
+ },
43
+ { immediate: true }
44
+ );
45
+ return pathRef;
46
+ };
47
+
48
+ export const useGDrivingRoute = (props: UseDrivingRouteProps) => {
49
+ const pathRef = shallowRef<Point[]>([]);
50
+ const gmapDirectionsService = new google.maps.DirectionsService();
51
+ watch([() => props.from, () => props.to], ([from, to]) => {
52
+ gmapDirectionsService
53
+ .route({
54
+ origin: { lng: from[0], lat: from[1] },
55
+ destination: { lng: to[0], lat: to[1] },
56
+ travelMode: google.maps.TravelMode.WALKING,
57
+ })
58
+ .then((result) => {
59
+ let path: Point[] = [];
60
+ result.routes.map((route) => {
61
+ const stepPath = route.overview_path.map<Point>((item) => [item.lng(), item.lat()]);
62
+ path = path.concat(stepPath);
63
+ });
64
+ pathRef.value = path;
65
+ });
66
+ });
67
+ return pathRef;
68
+ };
69
+
70
+ export const useDrivingRoute = (props: UseDrivingRouteProps): ShallowRef<Point[]> => {
71
+ const { supplier } = useMapSupplier();
72
+ return supplier === "gmap" ? useGDrivingRoute(props) : useADrivingRoute(props);
73
+ };
@@ -0,0 +1,28 @@
1
+ import { shallowRef } from "vue-demi";
2
+ import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
3
+ import { vec2lnglat } from "../utils/transform";
4
+
5
+ export type SetMap<M> = (map: M) => void;
6
+
7
+ export const useHeycarAmap = () => {
8
+ const amapRef = shallowRef<AMap.Map>();
9
+ const setMap: SetMap<AMap.Map> = (map) => {
10
+ amapRef.value = map;
11
+ };
12
+ const panTo = (value: [number, number]) => amapRef?.value?.panTo(value);
13
+ return { mapRef: amapRef, panTo, setMap };
14
+ };
15
+
16
+ export const useHeycarGamp = () => {
17
+ const gmapRef = shallowRef<google.maps.Map>();
18
+ const setMap: SetMap<google.maps.Map> = (map) => {
19
+ gmapRef.value = map;
20
+ };
21
+ const panTo = (value: [number, number]) => gmapRef?.value?.panTo(vec2lnglat(value));
22
+ return { mapRef: gmapRef, panTo, setMap };
23
+ };
24
+
25
+ export const useHeycarMap = () => {
26
+ const { supplier } = useMapSupplier();
27
+ return supplier === "gmap" ? useHeycarGamp() : useHeycarAmap();
28
+ };
@@ -0,0 +1,43 @@
1
+ import { computed, ShallowRef } from "vue";
2
+ import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
3
+ import type { MapShallowRef, Point } from "../types/interface";
4
+ import { vec2lnglat } from "../utils/transform";
5
+
6
+ const amapComputeHeading = (from: Point, to: Point, map?: AMap.Map) => {
7
+ if (!map) return 0;
8
+ const { x: xFrom, y: yFrom } = map.lngLatToContainer(from);
9
+ const { x: xTo, y: yTo } = map.lngLatToContainer(to);
10
+ console.log("yTo - yFrom, xTo - xFrom = ", yTo - yFrom, xTo - xFrom);
11
+ const theta = Math.atan2(yFrom - yTo, xTo - xFrom);
12
+ return ((Math.PI / 2 - theta) / Math.PI) * 180;
13
+ };
14
+
15
+ export interface UseMapAngleProps<T = AMap.Map | google.maps.Map> {
16
+ pathRef: ShallowRef<Point[]>;
17
+ mapRef?: MapShallowRef<T>;
18
+ }
19
+
20
+ export const useAmapAngle = (props: UseMapAngleProps<AMap.Map>) => {
21
+ return computed(() => {
22
+ const { mapRef, pathRef } = props;
23
+ const [from, to] = pathRef.value;
24
+ if (!from || !to || !mapRef) return undefined;
25
+ return amapComputeHeading(from, to, mapRef.value);
26
+ });
27
+ };
28
+
29
+ export const useGmapAngle = (props: UseMapAngleProps<google.maps.Map>) => {
30
+ return computed(() => {
31
+ const { pathRef } = props;
32
+ const [from, to] = pathRef.value;
33
+ if (!from || !to) return undefined;
34
+ return google.maps.geometry.spherical.computeHeading(vec2lnglat(from), vec2lnglat(to));
35
+ });
36
+ };
37
+
38
+ export const useMapAngle = (props: UseMapAngleProps) => {
39
+ const { supplier } = useMapSupplier();
40
+ return supplier === "gmap"
41
+ ? useGmapAngle(props as UseMapAngleProps<google.maps.Map>)
42
+ : useAmapAngle(props as UseMapAngleProps<AMap.Map>);
43
+ };
@@ -0,0 +1,81 @@
1
+ import { reactive, ref, type ShallowRef } from "vue-demi";
2
+ import type { AmapProps } from "../components/Amap";
3
+ import type { GmapProps } from "../components/Gmap";
4
+ import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
5
+ import { LANGUAGE, SetupContextEmitHandler } from "../types/helper";
6
+ import type { MapShallowRef } from "../types/interface";
7
+ import { watchPostEffectForAMapEvent, watchPostEffectForGMapEvent } from "../utils/compare";
8
+
9
+ export const ON_CHANGE_CENTER_INTERVAL = 200;
10
+ export interface UseMapCenterPlace {
11
+ lng: number;
12
+ lat: number;
13
+ name: string;
14
+ }
15
+ export const useAmapDrag = (amapRef: ShallowRef<AMap.Map | undefined>) => {
16
+ const centerPlace = reactive<UseMapCenterPlace>({ lng: 0, lat: 0, name: "" });
17
+ const isDragging = ref(false);
18
+ const emitDragStart: SetupContextEmitHandler<Pick<AmapProps, "onDragStart">> = () => {
19
+ Promise.resolve().then(() => (isDragging.value = true));
20
+ };
21
+ const emitDragEnd: SetupContextEmitHandler<Pick<AmapProps, "onDragEnd">> = (_, { target }) => {
22
+ isDragging.value = false;
23
+ const center = target.getCenter();
24
+ centerPlace.lng = center.lng;
25
+ centerPlace.lat = center.lat;
26
+ const geocoder = new AMap.Geocoder({ lang: LANGUAGE });
27
+ geocoder.getAddress(center, (status, result) => {
28
+ switch (status) {
29
+ case "complete":
30
+ centerPlace.name = (result as AMap.ReGeocoderResult).regeocode.formattedAddress;
31
+ return;
32
+ case "no_data":
33
+ return;
34
+ case "error":
35
+ throw result;
36
+ }
37
+ });
38
+ };
39
+ watchPostEffectForAMapEvent(amapRef, {} as Pick<AmapProps, "onDragStart">, emitDragStart, [
40
+ "onDragStart",
41
+ ]);
42
+ watchPostEffectForAMapEvent(amapRef, {} as Pick<AmapProps, "onDragEnd">, emitDragEnd, [
43
+ "onDragEnd",
44
+ ]);
45
+ return { centerPlace, isDragging };
46
+ };
47
+
48
+ export const useGmapDrag = (gmapRef: ShallowRef<google.maps.Map | undefined>) => {
49
+ const centerPlace = reactive<UseMapCenterPlace>({ lng: 0, lat: 0, name: "" });
50
+ const isDragging = ref(false);
51
+ const emitDragStart: SetupContextEmitHandler<Pick<GmapProps, "onDragStart">> = () => {
52
+ Promise.resolve().then(() => (isDragging.value = true));
53
+ };
54
+ const emitDragEnd: SetupContextEmitHandler<Pick<GmapProps, "onDragEnd">> = async () => {
55
+ isDragging.value = false;
56
+ const center = gmapRef.value?.getCenter();
57
+ if (!center) return;
58
+ const lng = center?.lng();
59
+ const lat = center?.lat();
60
+ if (lng) centerPlace.lng = lng;
61
+ if (lat) centerPlace.lat = lat;
62
+ const geocoder = new google.maps.Geocoder();
63
+ const { results } = await geocoder.geocode({ language: LANGUAGE, location: center });
64
+ centerPlace.name = results[0].formatted_address;
65
+ };
66
+ watchPostEffectForGMapEvent(gmapRef!, {} as Pick<GmapProps, "onDragStart">, emitDragStart, [
67
+ "onDragStart",
68
+ ]);
69
+ watchPostEffectForGMapEvent(gmapRef!, {} as Pick<GmapProps, "onDragEnd">, emitDragEnd, [
70
+ "onDragEnd",
71
+ ]);
72
+ return { centerPlace, isDragging };
73
+ };
74
+
75
+ export const useMapDrag = (mapRef: MapShallowRef) => {
76
+ const { supplier } = useMapSupplier();
77
+ // todo: 这里违反 react hook 规则,但 react 版本应该可以同时调用 useAmap 和 useGmap
78
+ return supplier === "gmap"
79
+ ? useGmapDrag(mapRef as ShallowRef<google.maps.Map | undefined>)
80
+ : useAmapDrag(mapRef as ShallowRef<AMap.Map | undefined>);
81
+ };
package/src/index.ts CHANGED
@@ -2,13 +2,17 @@ import "./style.css";
2
2
  export { AddressBox } from "./business-components/AddressBox";
3
3
  export { AddressLocator } from "./business-components/AddressLocator";
4
4
  export { DrivingLine } from "./business-components/DrivingLine";
5
+ export { DrivingRoute } from "./business-components/DrivingRoute";
5
6
  export { PassengerCircle } from "./business-components/PassengerCircle";
7
+ export { PickupPoints } from "./business-components/PickupPoints";
6
8
  export { PlaceCircle } from "./business-components/PlaceCircle";
7
9
  export { StartEndPoint } from "./business-components/StartEndPoint";
8
10
  export { TaxiCar } from "./business-components/TaxiCar";
9
11
  export { WalkingLine } from "./business-components/WalkingLine";
10
12
  export { WaveCircle } from "./business-components/WaveCircle";
11
- export * from "./components/Demo/BusinessDemo";
12
- export * from "./components/Demo/HeycarDemo";
13
13
  export * from "./components/MapProvider";
14
+ export { useDrivingRoute } from "./hooks/useDrivingRoute";
15
+ export { useHeycarMap } from "./hooks/useHeycarMap";
16
+ export { useMapAngle } from "./hooks/useMapAngle";
17
+ export { useMapDrag } from "./hooks/useMapDrag";
14
18
  export * from "./types/interface";
@@ -42,6 +42,8 @@ declare global {
42
42
  tolls_distance: number;
43
43
  // 限行结果,0 代表限行已规避或未限行,即该路线没有限行路段,1 代表限行无法规避,即该线路有限行路段
44
44
  restriction: number;
45
+ // 子路段DriveStep集合
46
+ steps: (DriveStepBasic | DriveStepDetail)[];
45
47
  }
46
48
 
47
49
  export interface DriveStepBasic {
@@ -1,4 +1,5 @@
1
1
  import "@amap/amap-jsapi-types";
2
+ import { kebabCase } from "lodash-es";
2
3
  import { DefineComponent, defineComponent, h, SetupContext, VNode } from "vue-demi";
3
4
 
4
5
  // vue2
@@ -16,7 +17,13 @@ type LagecyPropNames<N> = N extends `on${string}` ? never : N;
16
17
  export type EmitByProps<T, R = Required<T>> = {
17
18
  [K in keyof R as K extends `on${infer N}` ? Uncapitalize<N> : never]: R[K];
18
19
  };
19
-
20
+ export type EmitPayloadByProps<T, R = Required<T>> = {
21
+ [K in keyof R as K extends `on${infer N}` ? Uncapitalize<N> : never]: R[K] extends (
22
+ props: infer P
23
+ ) => any
24
+ ? P
25
+ : never;
26
+ };
20
27
  type RenderFunction = (...args: any[]) => VNodeChild;
21
28
  export type SC<P> = Omit<SetupContext<Extract<EmitByProps<P>, ObjectEmitsOptions>>, "slots"> & {
22
29
  slots: {
@@ -27,7 +34,11 @@ export type SC<P> = Omit<SetupContext<Extract<EmitByProps<P>, ObjectEmitsOptions
27
34
  : never]: P[K];
28
35
  } & { default?: Slot };
29
36
  };
30
- export type SetupContextEmit<P> = EmitFn<Extract<EmitByProps<P>, ObjectEmitsOptions>>;
37
+ // SetupContextEmitHandler 是通用处理函数的类型,不是严格意义的重载类型
38
+ export type SetupContextEmitHandler<P, E = EmitPayloadByProps<P>> = (
39
+ eventName: keyof E,
40
+ payload: E[keyof E]
41
+ ) => any;
31
42
  export type SetupOptions<P> = ComponentOptionsBase<
32
43
  P,
33
44
  Empty,
@@ -48,7 +59,13 @@ export function defineFc<P = Empty>(render: (props: P, ctx: SC<P>) => VueNode) {
48
59
  name: render.name,
49
60
  inheritAttrs: false,
50
61
  setup(_, ctx) {
51
- const { attrs, slots } = ctx;
62
+ const { attrs, slots, emit } = ctx;
63
+ const originEmit = emit as EmitFn;
64
+ const emitKebab = (eventName: string, data: any) => {
65
+ const kebabName = kebabCase(eventName);
66
+ originEmit(eventName, data);
67
+ if (eventName !== kebabName) originEmit(kebabName, data);
68
+ };
52
69
  const props = attrs as unknown as P;
53
70
  // todo: 下面是实时订阅的实现,是否不需要。
54
71
  const proxiedSlots = new Proxy(slots, {
@@ -56,7 +73,8 @@ export function defineFc<P = Empty>(render: (props: P, ctx: SC<P>) => VueNode) {
56
73
  return Reflect.get(target, name, receiver) ?? Reflect.get(props as any, name);
57
74
  },
58
75
  });
59
- return () => render(props, { ...ctx, slots: proxiedSlots } as unknown as SC<P>);
76
+ return () =>
77
+ render(props, { ...ctx, slots: proxiedSlots, emit: emitKebab } as unknown as SC<P>);
60
78
  },
61
79
  }) as DefineComponent<
62
80
  ComponentObjectPropsOptions<P>,
@@ -77,14 +95,20 @@ export function defineSetup<P>(setup: (props: P, ctx: SC<P>) => () => VueNode) {
77
95
  name: setup.name,
78
96
  inheritAttrs: false,
79
97
  setup(_, ctx) {
80
- const { attrs, slots } = ctx;
98
+ const { attrs, slots, emit } = ctx;
81
99
  const props = attrs as unknown as P;
100
+ const originEmit = emit as EmitFn;
101
+ const emitKebab = (eventName: string, data: any) => {
102
+ const kebabName = kebabCase(eventName);
103
+ originEmit(eventName, data);
104
+ if (eventName !== kebabName) originEmit(kebabName, data);
105
+ };
82
106
  const proxiedSlots = new Proxy(slots, {
83
107
  get(target, name, receiver) {
84
108
  return Reflect.get(target, name, receiver) ?? Reflect.get(props as any, name);
85
109
  },
86
110
  });
87
- return setup(props, { ...ctx, slots: proxiedSlots } as unknown as SC<P>);
111
+ return setup(props, { ...ctx, slots: proxiedSlots, emit: emitKebab } as unknown as SC<P>);
88
112
  },
89
113
  }) as DefineComponent<
90
114
  ComponentObjectPropsOptions<P>,
@@ -109,13 +133,19 @@ export function defineLagecySetup<P>(setup: (props: P, ctx: SC<P>) => () => VueN
109
133
  props: propNames as string[],
110
134
  setup(setupProps, ctx) {
111
135
  const props = setupProps as P;
112
- const { slots } = ctx;
136
+ const { slots, emit } = ctx;
137
+ const originEmit = emit as EmitFn;
138
+ const emitKebab = (eventName: string, data: any) => {
139
+ const kebabName = kebabCase(eventName);
140
+ originEmit(eventName, data);
141
+ if (eventName !== kebabName) originEmit(kebabName, data);
142
+ };
113
143
  const proxiedSlots = new Proxy(slots, {
114
144
  get(target, name, receiver) {
115
145
  return Reflect.get(target, name, receiver) ?? Reflect.get(props as any, name);
116
146
  },
117
147
  });
118
- return setup(props, { ...ctx, slots: proxiedSlots } as unknown as SC<P>);
148
+ return setup(props, { ...ctx, slots: proxiedSlots, emit: emitKebab } as unknown as SC<P>);
119
149
  },
120
150
  }) as DefineComponent<
121
151
  ComponentObjectPropsOptions<P>,
@@ -1 +1,4 @@
1
+ import type { ShallowRef } from "vue-demi";
2
+
1
3
  export type Point = [number, number];
4
+ export type MapShallowRef<M = AMap.Map | google.maps.Map> = ShallowRef<M | undefined>;
@@ -0,0 +1 @@
1
+ export type MapEventHandler<T> = (e: { target: T }) => any;
@@ -25,3 +25,13 @@ export const property2emitEventName = (propertyName: string) => {
25
25
  export const property2mapEventName = (propertyName: string) => {
26
26
  return propertyName.slice(2).toLowerCase();
27
27
  };
28
+
29
+ export type VectorMapForeign = "style_en" | "style_local" | "style_zh_cn";
30
+ export const language2vectorMapForeign = (lang: "en" | "zh"): VectorMapForeign => {
31
+ switch (lang) {
32
+ case "en":
33
+ return "style_en";
34
+ case "zh":
35
+ return "style_zh_cn";
36
+ }
37
+ };
@@ -1,30 +0,0 @@
1
- export declare const ON_CHANGE_CENTER_INTERVAL = 200;
2
- export interface UseMapCenterData {
3
- lng: number;
4
- lat: number;
5
- name: string;
6
- }
7
- export declare const useAmapCenter: () => {
8
- center: {
9
- lng: number;
10
- lat: number;
11
- name: string;
12
- };
13
- setCenter: (value: [number, number]) => void | undefined;
14
- };
15
- export declare const useGmapCenter: () => {
16
- center: {
17
- lng: number;
18
- lat: number;
19
- name: string;
20
- };
21
- setCenter: (value: [number, number]) => void | undefined;
22
- };
23
- export declare const useMapCenter: () => {
24
- center: {
25
- lng: number;
26
- lat: number;
27
- name: string;
28
- };
29
- setCenter: (value: [number, number]) => void | undefined;
30
- };
@@ -1,70 +0,0 @@
1
- import { debounce } from "lodash-es";
2
- import { reactive } from "vue-demi";
3
- import type { AmapProps } from "../components/Amap";
4
- import { useAmap } from "../components/Amap/useAmap";
5
- import type { GampProps } from "../components/Gmap";
6
- import { useGmap } from "../components/Gmap/useGmap";
7
- import { useMapSupplier } from "../components/MapProvider/useMapSupplier";
8
- import { LANGUAGE, SetupContextEmit } from "../types/helper";
9
- import { watchPostEffectForAMapEvent, watchPostEffectForGMapEvent } from "../utils/compare";
10
- import { vec2lnglat } from "../utils/transform";
11
-
12
- export const ON_CHANGE_CENTER_INTERVAL = 200;
13
- export interface UseMapCenterData {
14
- lng: number;
15
- lat: number;
16
- name: string;
17
- }
18
- export const useAmapCenter = () => {
19
- const amapRef = useAmap();
20
- const centerData = reactive<UseMapCenterData>({ lng: 0, lat: 0, name: "" });
21
- const setCenter = (value: [number, number]) => amapRef?.value?.setCenter(value);
22
- const debouncedEmit = debounce<SetupContextEmit<AmapProps>>((_, { target }) => {
23
- const center = target.getCenter();
24
- centerData.lng = center.lng;
25
- centerData.lat = center.lat;
26
- const geocoder = new AMap.Geocoder({ lang: LANGUAGE });
27
- geocoder.getAddress(center, (status, result) => {
28
- switch (status) {
29
- case "complete":
30
- centerData.name = (result as AMap.ReGeocoderResult).regeocode.formattedAddress;
31
- return;
32
- case "no_data":
33
- return;
34
- case "error":
35
- throw result;
36
- }
37
- });
38
- }, ON_CHANGE_CENTER_INTERVAL);
39
- watchPostEffectForAMapEvent(amapRef!, {} as AmapProps, debouncedEmit, ["onMapMove"]);
40
- return { center: centerData, setCenter };
41
- };
42
-
43
- export const useGmapCenter = () => {
44
- const gmapRef = useGmap();
45
- const centerData = reactive<UseMapCenterData>({ lng: 0, lat: 0, name: "" });
46
- const setCenter = (value: [number, number]) => gmapRef?.value?.setCenter(vec2lnglat(value));
47
- const debouncedEmit = debounce<SetupContextEmit<GampProps>>(async (_, { target }) => {
48
- const center = target.getCenter();
49
- const lng = center?.lng();
50
- const lat = center?.lat();
51
- if (lng) centerData.lng = lng;
52
- if (lat) centerData.lat = lat;
53
- const geocoder = new google.maps.Geocoder();
54
- const { results } = await geocoder.geocode({ language: LANGUAGE, location: center });
55
- centerData.name = results[0].formatted_address;
56
- }, ON_CHANGE_CENTER_INTERVAL);
57
- watchPostEffectForGMapEvent(gmapRef!, {} as GampProps, debouncedEmit, ["onCenter_changed"]);
58
- return { center: centerData, setCenter };
59
- };
60
-
61
- export const useMapCenter = () => {
62
- const payload = useMapSupplier();
63
- // todo: 这里违反 react hook 规则,但 react 版本应该可以同时调用 useAmap 和 useGmap
64
- switch (payload.supplier) {
65
- case "gmap":
66
- return useGmapCenter();
67
- default:
68
- return useAmapCenter();
69
- }
70
- };