@heycar/heycars-map 0.1.2 → 0.1.3

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 (49) 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 +6 -5
  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 +5 -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 +52 -52
  19. package/dist/index.d.ts +6 -2
  20. package/dist/index.js +1108 -842
  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/package.json +1 -1
  26. package/src/api/geometry.ts +2 -1
  27. package/src/business-components/DrivingLine/DrivingLine.tsx +14 -7
  28. package/src/business-components/DrivingRoute/DrivingRoute.tsx +43 -0
  29. package/src/business-components/DrivingRoute/index.ts +1 -0
  30. package/src/business-components/PickupPoints/PickupPoints.tsx +16 -0
  31. package/src/business-components/PickupPoints/index.ts +1 -0
  32. package/src/business-components/PlaceCircle/PlaceCircle.css.ts +39 -8
  33. package/src/business-components/PlaceCircle/PlaceCircle.tsx +22 -7
  34. package/src/business-components/TaxiCar/TaxiCar.tsx +3 -2
  35. package/src/components/Amap/Amap.ts +10 -4
  36. package/src/components/Demo/HeycarDemo.tsx +38 -17
  37. package/src/components/Gmap/Gmap.ts +14 -7
  38. package/src/components/MapProvider/MapProvider.tsx +25 -16
  39. package/src/hooks/useDrivingRoute.ts +74 -0
  40. package/src/hooks/useHeycarMap.ts +28 -0
  41. package/src/hooks/useMapAngle.ts +43 -0
  42. package/src/hooks/useMapDrag.ts +81 -0
  43. package/src/index.ts +6 -2
  44. package/src/types/amap/driving.d.ts +2 -0
  45. package/src/types/helper.ts +38 -8
  46. package/src/types/interface.ts +3 -0
  47. package/src/types/mapHelper.ts +1 -0
  48. package/dist/hooks/useMapCenter.d.ts +0 -30
  49. package/src/hooks/useMapCenter.ts +0 -70
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- ._15rq2xn0{display:flex;flex-direction:column;align-items:center;margin-bottom:-1.6vw}._15rq2xn1{padding:2.13vw 4.5vw 2.67vw 4.27vw;display:flex;align-items:center;background:linear-gradient(90deg,#79AFFF 0%,#5C8DFF 32%,#507FFF 75%,#4471FF 100%);border-radius:3.2vw}._15rq2xn2{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#fff;line-height:4.8vw;white-space:nowrap}._15rq2xn3{font-size:2.93vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#eafaf8;line-height:4.27vw;white-space:nowrap;opacity:.8}._15rq2xn4{margin-left:3.2vw;width:1.44vw;height:2.4vw}._15rq2xn5{width:.8vw;height:4vw;background:#4C80FF;border-radius:0vw 0vw 26.67vw 26.67vw;z-index:1}._15rq2xn6{margin-top:-1.5vw;width:3.2vw;height:3.2vw}.rgf09w0{width:7.1045vw;height:10.93vw;display:flex}._1l6offo0{display:flex;margin-bottom:-8.135vw;width:16.27vw;height:16.27vw}.fhyw80{display:flex;align-items:center}.fhyw81{margin-left:-2.265vw}.fhyw82{margin-bottom:-2.265vw;margin-left:calc(50% - 2.265vw)}.fhyw83{display:flex;width:4.53vw;height:4.53vw}.fhyw84{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#243e66;line-height:4.53vw;white-space:nowrap}._4a4ovk0{margin-bottom:-.4vw;display:flex;flex-direction:column;align-items:center}._4a4ovk1{padding:1.07vw 2.4vw 1.6vw 2.67vw;background:#FFFFFF;box-shadow:0 .53vw 2.4vw #3f3f3f33;border-radius:2.13vw}._4a4ovk2{padding:2.67vw 2.67vw 2.4vw 3.2vw;background:#FFFFFF;box-shadow:0 0 2.67vw #4e556c26;border-radius:4.8vw;font-size:3.2vw;font-family:PingFangSC-Medium,PingFang SC;font-weight:500;color:#1e1e1e;line-height:4.53vw;white-space:nowrap}._4a4ovk3{font-size:3.2vw;font-family:PingFangSC-Medium,PingFang SC;font-weight:500;color:#1e1e1e;line-height:4.53vw;white-space:nowrap}._4a4ovk4{font-size:2.4vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#7e7e7e;line-height:3.47vw;white-space:nowrap}._4a4ovk5{color:#4471ff;font-family:PingFangSC-Medium,PingFang SC;font-weight:500}._4a4ovk6{margin-top:1.33vw;width:6.192vw;height:7.998vw}._4a4ovk7{margin-top:2.4vw;width:6.192vw;height:7.998vw}._65j3sr1{margin-top:1.87vw;margin-bottom:-5.5vw;width:6vw;height:11vw}@keyframes rrvp0y0{0%{transform:scale(0);opacity:1}33.33%{transform:scale(.5);opacity:1}66.66%{transform:scale(1);opacity:0}to{transform:scale(1);opacity:0}}@keyframes rrvp0y1{0%{transform:scale(0);opacity:0}33.33%{transform:scale(0);opacity:1}66.66%{transform:scale(.5);opacity:1}to{transform:scale(1);opacity:0}}.rrvp0y2{display:flex;margin-bottom:-30.935vw;width:61.87vw;height:61.87vw;animation-name:rrvp0y0;animation-duration:3s;animation-iteration-count:infinite;animation-timing-function:linear}.rrvp0y3{animation-name:rrvp0y1}.c8adwd0{width:100vw;height:100vh}
1
+ ._15rq2xn0{display:flex;flex-direction:column;align-items:center;margin-bottom:-1.6vw}._15rq2xn1{padding:2.13vw 4.5vw 2.67vw 4.27vw;display:flex;align-items:center;background:linear-gradient(90deg,#79AFFF 0%,#5C8DFF 32%,#507FFF 75%,#4471FF 100%);border-radius:3.2vw}._15rq2xn2{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#fff;line-height:4.8vw;white-space:nowrap}._15rq2xn3{font-size:2.93vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#eafaf8;line-height:4.27vw;white-space:nowrap;opacity:.8}._15rq2xn4{margin-left:3.2vw;width:1.44vw;height:2.4vw}._15rq2xn5{width:.8vw;height:4vw;background:#4C80FF;border-radius:0vw 0vw 26.67vw 26.67vw;z-index:1}._15rq2xn6{margin-top:-1.5vw;width:3.2vw;height:3.2vw}.rgf09w0{width:7.1045vw;height:10.93vw;display:flex}._1l6offo0{display:flex;margin-bottom:-8.135vw;width:16.27vw;height:16.27vw}.fhyw80{display:flex;align-items:center}.fhyw81{flex-direction:row-reverse}.fhyw83{margin-right:-2.265vw}.fhyw84{margin-left:-2.265vw}.fhyw85{margin-bottom:-2.265vw}.fhyw86{margin-right:calc(50% - 2.265vw)}.fhyw87{margin-left:calc(50% - 2.265vw)}.fhyw88{display:flex;width:4.53vw;height:4.53vw}.fhyw89{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#243e66;line-height:4.53vw;white-space:nowrap}._4a4ovk0{margin-bottom:-.4vw;display:flex;flex-direction:column;align-items:center}._4a4ovk1{padding:1.07vw 2.4vw 1.6vw 2.67vw;background:#FFFFFF;box-shadow:0 .53vw 2.4vw #3f3f3f33;border-radius:2.13vw}._4a4ovk2{padding:2.67vw 2.67vw 2.4vw 3.2vw;background:#FFFFFF;box-shadow:0 0 2.67vw #4e556c26;border-radius:4.8vw;font-size:3.2vw;font-family:PingFangSC-Medium,PingFang SC;font-weight:500;color:#1e1e1e;line-height:4.53vw;white-space:nowrap}._4a4ovk3{font-size:3.2vw;font-family:PingFangSC-Medium,PingFang SC;font-weight:500;color:#1e1e1e;line-height:4.53vw;white-space:nowrap}._4a4ovk4{font-size:2.4vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#7e7e7e;line-height:3.47vw;white-space:nowrap}._4a4ovk5{color:#4471ff;font-family:PingFangSC-Medium,PingFang SC;font-weight:500}._4a4ovk6{margin-top:1.33vw;width:6.192vw;height:7.998vw}._4a4ovk7{margin-top:2.4vw;width:6.192vw;height:7.998vw}._65j3sr1{margin-top:1.87vw;margin-bottom:-5.5vw;width:6vw;height:11vw}@keyframes rrvp0y0{0%{transform:scale(0);opacity:1}33.33%{transform:scale(.5);opacity:1}66.66%{transform:scale(1);opacity:0}to{transform:scale(1);opacity:0}}@keyframes rrvp0y1{0%{transform:scale(0);opacity:0}33.33%{transform:scale(0);opacity:1}66.66%{transform:scale(.5);opacity:1}to{transform:scale(1);opacity:0}}.rrvp0y2{display:flex;margin-bottom:-30.935vw;width:61.87vw;height:61.87vw;animation-name:rrvp0y0;animation-duration:3s;animation-iteration-count:infinite;animation-timing-function:linear}.rrvp0y3{animation-name:rrvp0y1}
@@ -3,13 +3,16 @@ import { DefineComponent, SetupContext, VNode } from "vue-demi";
3
3
  import type { VNodeChildren } from "vue/types/umd";
4
4
  import type { ComponentOptionsBase } from "vue/types/v3-component-options";
5
5
  import type { ComponentObjectPropsOptions } from "vue/types/v3-component-props";
6
- import type { EmitFn, ObjectEmitsOptions, Slot } from "vue/types/v3-setup-context";
6
+ import type { ObjectEmitsOptions, Slot } from "vue/types/v3-setup-context";
7
7
  export type VNodeChild = VNode | VNodeChildren;
8
8
  export type VueNode = VNode | null | undefined;
9
9
  type LagecyPropNames<N> = N extends `on${string}` ? never : N;
10
10
  export type EmitByProps<T, R = Required<T>> = {
11
11
  [K in keyof R as K extends `on${infer N}` ? Uncapitalize<N> : never]: R[K];
12
12
  };
13
+ export type EmitPayloadByProps<T, R = Required<T>> = {
14
+ [K in keyof R as K extends `on${infer N}` ? Uncapitalize<N> : never]: R[K] extends (props: infer P) => any ? P : never;
15
+ };
13
16
  type RenderFunction = (...args: any[]) => VNodeChild;
14
17
  export type SC<P> = Omit<SetupContext<Extract<EmitByProps<P>, ObjectEmitsOptions>>, "slots"> & {
15
18
  slots: {
@@ -18,7 +21,7 @@ export type SC<P> = Omit<SetupContext<Extract<EmitByProps<P>, ObjectEmitsOptions
18
21
  default?: Slot;
19
22
  };
20
23
  };
21
- export type SetupContextEmit<P> = EmitFn<Extract<EmitByProps<P>, ObjectEmitsOptions>>;
24
+ export type SetupContextEmitHandler<P, E = EmitPayloadByProps<P>> = (eventName: keyof E, payload: E[keyof E]) => any;
22
25
  export type SetupOptions<P> = ComponentOptionsBase<P, Empty, Empty, Empty, Empty, Empty, Empty, Extract<EmitByProps<P>, ObjectEmitsOptions>, Extract<keyof EmitByProps<P>, string>, Empty>;
23
26
  export type Empty = Record<string, never>;
24
27
  export declare function defineFc<P = Empty>(render: (props: P, ctx: SC<P>) => VueNode): DefineComponent<ComponentObjectPropsOptions<P>, Empty, Empty, Empty, Empty, Empty, Empty, Extract<EmitByProps<P, Required<P>>, ObjectEmitsOptions>, Extract<keyof EmitByProps<P, Required<P>>, string>, P, import("vue-demi").ExtractDefaultPropTypes<ComponentObjectPropsOptions<P>>>;
@@ -1 +1,4 @@
1
+ /// <reference types="google.maps" />
2
+ import type { ShallowRef } from "vue-demi";
1
3
  export type Point = [number, number];
4
+ export type MapShallowRef<M = AMap.Map | google.maps.Map> = ShallowRef<M | undefined>;
@@ -0,0 +1,3 @@
1
+ export type MapEventHandler<T> = (e: {
2
+ target: T;
3
+ }) => any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heycar/heycars-map",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite -c vite.config.dev.ts",
@@ -1,8 +1,9 @@
1
+ import type { Point } from "../types/interface";
2
+
1
3
  export interface ApiMapMeta {
2
4
  isGoogle: boolean;
3
5
  }
4
6
 
5
- type Point = [number, number];
6
7
  const point2latlng = ([lng, lat]: Point): google.maps.LatLngLiteral => ({ lng, lat });
7
8
 
8
9
  export interface DistanceOfLineProps extends ApiMapMeta {
@@ -6,6 +6,7 @@ import { createElement, defineSetup } from "../../types/helper";
6
6
  import { vec2lnglat } from "../../utils/transform";
7
7
 
8
8
  export interface DrivingLineProps {
9
+ done?: boolean;
9
10
  path: [number, number][];
10
11
  }
11
12
  export const ADrivingLine = defineSetup(function ADrivingLine(props: DrivingLineProps) {
@@ -16,13 +17,16 @@ export const ADrivingLine = defineSetup(function ADrivingLine(props: DrivingLine
16
17
  const dirWidth = 0.6 * vw;
17
18
  const outlineWidth = 1 * vw;
18
19
  const dashLength = 0.75 * vw;
20
+ const strokeColorInner = props.done ? "#96B2CA" : "#487BF4";
21
+ const strokeColorOuter = props.done ? "#7693AF" : "#4175F1";
22
+ const strokeColorBorder = props.done ? "#7693AF" : "#6C95F5";
19
23
  return (
20
24
  <div>
21
25
  <AmapPolyline
22
26
  path={props.path}
23
27
  strokeWeight={strokeWidth + 2 * borderWidth + 2 * outlineWidth}
24
28
  strokeOpacity={1}
25
- strokeColor={"#4175F1"}
29
+ strokeColor={strokeColorOuter}
26
30
  lineJoin={"round"}
27
31
  lineCap={"round"}
28
32
  />
@@ -30,7 +34,7 @@ export const ADrivingLine = defineSetup(function ADrivingLine(props: DrivingLine
30
34
  path={props.path}
31
35
  strokeWeight={strokeWidth + 2 * borderWidth}
32
36
  strokeOpacity={1}
33
- strokeColor={"#6C95F5"}
37
+ strokeColor={strokeColorBorder}
34
38
  lineJoin={"round"}
35
39
  lineCap={"round"}
36
40
  strokeStyle={"dashed"}
@@ -40,7 +44,7 @@ export const ADrivingLine = defineSetup(function ADrivingLine(props: DrivingLine
40
44
  path={props.path}
41
45
  strokeWeight={strokeWidth}
42
46
  strokeOpacity={1}
43
- strokeColor={"#487BF4"}
47
+ strokeColor={strokeColorInner}
44
48
  lineJoin={"round"}
45
49
  lineCap={"round"}
46
50
  />
@@ -67,13 +71,16 @@ export const GDrivingLine = defineSetup(function GDrivingLine(props: DrivingLine
67
71
  const borderWidth = 0.35 * vw;
68
72
  const dirStrokeWeight = 0.75 * vw;
69
73
  const outlineWidth = 1 * vw;
74
+ const strokeColorInner = props.done ? "#96B2CA" : "#487BF4";
75
+ const strokeColorOuter = props.done ? "#7693AF" : "#4175F1";
76
+ const strokeColorBorder = props.done ? "#7693AF" : "#6C95F5";
70
77
  return (
71
78
  <div>
72
79
  <GmapPolyline
73
80
  path={pathRef.value}
74
81
  strokeWeight={strokeWidth + 2 * borderWidth + 2 * outlineWidth}
75
82
  strokeOpacity={1}
76
- strokeColor={"#4175F1"}
83
+ strokeColor={strokeColorOuter}
77
84
  />
78
85
  <GmapPolyline
79
86
  path={pathRef.value}
@@ -82,8 +89,8 @@ export const GDrivingLine = defineSetup(function GDrivingLine(props: DrivingLine
82
89
  icon: {
83
90
  path: `M 0,-0.5 0,0.5`,
84
91
  strokeWeight: strokeWidth + 2 * borderWidth,
85
- strokeColor: "#6C95F5",
86
- fillColor: "#6C95F5",
92
+ strokeColor: strokeColorBorder,
93
+ fillColor: strokeColorBorder,
87
94
  scale: 1,
88
95
  },
89
96
  repeat: `${strokeWidth}px`,
@@ -95,7 +102,7 @@ export const GDrivingLine = defineSetup(function GDrivingLine(props: DrivingLine
95
102
  path={pathRef.value}
96
103
  strokeWeight={strokeWidth}
97
104
  strokeOpacity={1}
98
- strokeColor={"#487BF4"}
105
+ strokeColor={strokeColorInner}
99
106
  icons={[
100
107
  {
101
108
  icon: {
@@ -0,0 +1,43 @@
1
+ import type { Ref, ShallowRef } from "vue-demi";
2
+ import { useAmap } from "../../components/Amap/useAmap";
3
+ import { useGmap } from "../../components/Gmap/useGmap";
4
+ import { useMapSupplier } from "../../components/MapProvider/useMapSupplier";
5
+ import {
6
+ useADrivingRoute,
7
+ UseDrivingRouteProps,
8
+ useGDrivingRoute,
9
+ } from "../../hooks/useDrivingRoute";
10
+ import { useAmapAngle, useGmapAngle } from "../../hooks/useMapAngle";
11
+ import { createElement, defineSetup, VNodeChild } from "../../types/helper";
12
+ import type { Point } from "../../types/interface";
13
+
14
+ export interface DrivingRouteProps extends UseDrivingRouteProps {
15
+ render?: (props: {
16
+ pathRef: ShallowRef<Point[]>;
17
+ angleRef: Ref<number | undefined>;
18
+ }) => VNodeChild;
19
+ }
20
+ export const ADrivingRoute = defineSetup(function DrivingRoute(
21
+ props: DrivingRouteProps,
22
+ { slots }
23
+ ) {
24
+ const mapRef = useAmap();
25
+ const pathRef = useADrivingRoute(props);
26
+ const angleRef = useAmapAngle({ pathRef, mapRef });
27
+ return () => <div>{slots.render?.({ pathRef, angleRef })}</div>;
28
+ });
29
+
30
+ export const GDrivingRoute = defineSetup(function DrivingRoute(
31
+ props: DrivingRouteProps,
32
+ { slots }
33
+ ) {
34
+ const mapRef = useGmap();
35
+ const pathRef = useGDrivingRoute(props);
36
+ const angleRef = useGmapAngle({ pathRef, mapRef });
37
+ return () => <div>{slots.render?.({ pathRef, angleRef })}</div>;
38
+ });
39
+
40
+ export const DrivingRoute = defineSetup(function DrivingRoute(props: DrivingRouteProps) {
41
+ const { supplier } = useMapSupplier();
42
+ return () => createElement(supplier === "gmap" ? GDrivingRoute : ADrivingRoute, { attrs: props });
43
+ });
@@ -0,0 +1 @@
1
+ export * from "./DrivingRoute";
@@ -0,0 +1,16 @@
1
+ import { defineSetup } from "../../types/helper";
2
+ import { PlaceCircle } from "../PlaceCircle";
3
+
4
+ export interface PickupPointsProps {
5
+ positions: [number, number][];
6
+ labels: string[];
7
+ }
8
+ export const PickupPoints = defineSetup(function PickupPoints(props: PickupPointsProps) {
9
+ return () => (
10
+ <div>
11
+ {props.positions.map((position, idx) => (
12
+ <PlaceCircle position={position} label={props.labels[idx]} textAlign="left" />
13
+ ))}
14
+ </div>
15
+ );
16
+ });
@@ -0,0 +1 @@
1
+ export * from "./PickupPoints";
@@ -1,17 +1,48 @@
1
1
  import { style } from "@vanilla-extract/css";
2
+ import { recipe } from "@vanilla-extract/recipes";
2
3
 
3
- export const placeCircleLayout = style({
4
- display: "flex",
5
- alignItems: "center",
4
+ export const placeCircleLayout = recipe({
5
+ base: {
6
+ display: "flex",
7
+ alignItems: "center",
8
+ },
9
+ variants: {
10
+ textAlign: {
11
+ left: {
12
+ flexDirection: "row-reverse",
13
+ },
14
+ right: {},
15
+ },
16
+ },
6
17
  });
7
18
 
8
- export const amapPlaceIconLayout = style({
9
- marginLeft: "-2.265vw",
19
+ export const amapPlaceIconLayout = recipe({
20
+ variants: {
21
+ textAlign: {
22
+ left: {
23
+ marginRight: "-2.265vw",
24
+ },
25
+ right: {
26
+ marginLeft: "-2.265vw",
27
+ },
28
+ },
29
+ },
10
30
  });
11
31
 
12
- export const gmapPlaceIconLayout = style({
13
- marginBottom: "-2.265vw",
14
- marginLeft: "calc(50% - 2.265vw)",
32
+ export const gmapPlaceIconLayout = recipe({
33
+ base: {
34
+ marginBottom: "-2.265vw",
35
+ },
36
+ variants: {
37
+ textAlign: {
38
+ left: {
39
+ marginRight: "calc(50% - 2.265vw)",
40
+ },
41
+ right: {
42
+ marginLeft: "calc(50% - 2.265vw)",
43
+ },
44
+ },
45
+ },
15
46
  });
16
47
 
17
48
  export const placeIcon = style({
@@ -9,36 +9,48 @@ import { createDom } from "../../utils/dom";
9
9
  import { vec2lnglat } from "../../utils/transform";
10
10
  import * as css from "./PlaceCircle.css";
11
11
 
12
- interface PlaceCircleProps {
12
+ export interface PlaceCircleProps {
13
13
  position: [number, number];
14
14
  label?: string;
15
+ textAlign?: "left" | "right";
15
16
  }
16
17
  export const APlaceCircle = defineSetup(function APlaceCircle(props: PlaceCircleProps) {
18
+ const textAlignRef = computed(() => props.textAlign ?? "right");
17
19
  const contentRef = computed(
18
20
  () => `
19
- <div class="${css.placeCircleLayout}" >
20
- <img class="${css.placeIcon} ${css.amapPlaceIconLayout}" src="${imgPlaceCircle}">
21
+ <div class="${css.placeCircleLayout({ textAlign: textAlignRef.value })}" >
22
+ <img class="${css.placeIcon} ${css.amapPlaceIconLayout({
23
+ textAlign: textAlignRef.value,
24
+ })}" src="${imgPlaceCircle}">
21
25
  <div class="${css.label}">${props.label}</div>
22
26
  </div>
23
27
  `
24
28
  );
25
29
  const contentWithoutLabelRef = computed(
26
- () => `<img class="${css.placeIcon} ${css.amapPlaceIconLayout}" src="${imgPlaceCircle}">`
30
+ () =>
31
+ `<img class="${css.placeIcon} ${css.amapPlaceIconLayout({
32
+ textAlign: textAlignRef.value,
33
+ })}" src="${imgPlaceCircle}">`
27
34
  );
28
35
  return () => (
29
36
  <AmapMarker
30
37
  position={props.position}
31
38
  content={props.label ? contentRef.value : contentWithoutLabelRef.value}
32
- anchor={AnchorType.middleLeft}
39
+ anchor={textAlignRef.value === "left" ? AnchorType.middleRight : AnchorType.middleLeft}
33
40
  />
34
41
  );
35
42
  });
36
43
 
37
44
  export const GPlaceCircle = defineSetup(function GPlaceCircle(props: PlaceCircleProps) {
45
+ const textAlignRef = computed(() => props.textAlign ?? "right");
38
46
  const contentRef = computed(() =>
39
47
  createDom(
40
48
  "div",
41
- { class: `${css.placeCircleLayout} ${css.gmapPlaceIconLayout}` },
49
+ {
50
+ class: `${css.placeCircleLayout({
51
+ textAlign: textAlignRef.value,
52
+ })} ${css.gmapPlaceIconLayout({ textAlign: textAlignRef.value })}`,
53
+ },
42
54
  `
43
55
  <img class="${css.placeIcon}" src="${imgPlaceCircle}">
44
56
  <div class="${css.label}">${props.label}</div>
@@ -46,7 +58,10 @@ export const GPlaceCircle = defineSetup(function GPlaceCircle(props: PlaceCircle
46
58
  )
47
59
  );
48
60
  const contentWithoutLabelRef = computed(() =>
49
- createDom("img", { class: `${css.placeIcon} ${css.gmapPlaceIconLayout}`, src: imgPlaceCircle })
61
+ createDom("img", {
62
+ class: `${css.placeIcon} ${css.gmapPlaceIconLayout({ textAlign: textAlignRef.value })}`,
63
+ src: imgPlaceCircle,
64
+ })
50
65
  );
51
66
  return () => (
52
67
  <GmapAdvancedMarkerView
@@ -24,8 +24,8 @@ export const ATaxiCar = defineSetup(function ATaxiCar(props: TaxiCarProps) {
24
24
  : `<span class="${css.pointInfoBoxEmphasize}">${item.value}</span>`
25
25
  )
26
26
  .join("");
27
- if (!props.title) return `<img src="${imgTaxicar}" class="${css.carIcon}">`;
28
27
  const carStyle = `transform:rotate(${props.angle ?? 0}deg)`;
28
+ if (!props.title) return `<img src="${imgTaxicar}" class="${css.carIcon}" style="${carStyle}">`;
29
29
  return `
30
30
  <div class="${css.pointLayout}">
31
31
  <div class="${css.pointSingleInfoBox}">${titleRow}</div>
@@ -49,8 +49,9 @@ export const GTaxiCar = defineSetup(function GTaxiCar(props: TaxiCarProps) {
49
49
  : `<span class="${css.pointInfoBoxEmphasize}">${item.value}</span>`
50
50
  )
51
51
  .join("");
52
- if (!props.title) return createDom("img", { class: css.carIcon, src: imgTaxicar });
53
52
  const carStyle = `transform:rotate(${props.angle ?? 0}deg)`;
53
+ if (!props.title)
54
+ return createDom("img", { class: css.carIcon, src: imgTaxicar, style: carStyle });
54
55
  return createDom(
55
56
  "div",
56
57
  { class: css.pointLayout },
@@ -1,5 +1,7 @@
1
1
  import { computed, h, shallowRef, watchPostEffect } from "vue-demi";
2
+ import type { SetMap } from "../../hooks/useHeycarMap";
2
3
  import { defineSetup } from "../../types/helper";
4
+ import type { MapEventHandler } from "../../types/mapHelper";
3
5
  import {
4
6
  watchNoneImmediatePostEffectForDeepOption,
5
7
  watchNoneImmediatePostEffectForMapProperty,
@@ -9,11 +11,13 @@ import * as css from "./Amap.css";
9
11
  import { provideAmap } from "./useAmap";
10
12
 
11
13
  export interface AmapProps extends AMap.MapOptions {
12
- onMapMove?: (e: { type: "mapmove"; target: AMap.Map }) => void;
14
+ mapRef?: SetMap<AMap.Map>;
15
+ onDragStart?: MapEventHandler<AMap.Map>;
16
+ onDragEnd?: MapEventHandler<AMap.Map>;
13
17
  }
14
18
 
15
19
  export const Amap = defineSetup(function Amap(props: AmapProps, { slots, emit }) {
16
- const { onMapMove, ...defaultOptions } = props;
20
+ const { onDragStart, onDragEnd, mapRef: setMap, ...defaultOptions } = props;
17
21
  const statusOptions = computed(() => {
18
22
  return {
19
23
  dragEnable: !!props.dragEnable,
@@ -31,7 +35,9 @@ export const Amap = defineSetup(function Amap(props: AmapProps, { slots, emit })
31
35
  watchPostEffect(() => {
32
36
  // todo 这里是否会因为 mapRef 的赋值导致不停运行?
33
37
  if (mapRef.value || !elementRef.value) return;
34
- mapRef.value = new AMap.Map(elementRef.value, { ...defaultOptions });
38
+ const map = new AMap.Map(elementRef.value, { ...defaultOptions });
39
+ mapRef.value = map;
40
+ setMap?.(map);
35
41
  });
36
42
  watchNoneImmediatePostEffectForDeepOption(
37
43
  () => statusOptions.value,
@@ -53,6 +59,6 @@ export const Amap = defineSetup(function Amap(props: AmapProps, { slots, emit })
53
59
  { name: "mask", defaultValue: [] },
54
60
  { name: "labelRejectMask", defaultValue: false },
55
61
  ]);
56
- watchPostEffectForAMapEvent(mapRef, props, emit, ["onMapMove"]);
62
+ watchPostEffectForAMapEvent(mapRef, props, emit, ["onDragStart", "onDragEnd"]);
57
63
  return () => h("div", { ref: elementRef, class: css.amap }, slots.default?.());
58
64
  });
@@ -1,5 +1,8 @@
1
- import { AddressBox } from "../../business-components/AddressBox";
2
- import { useMapCenter } from "../../hooks/useMapCenter";
1
+ import { DrivingLine } from "../../business-components/DrivingLine";
2
+ import { DrivingRoute } from "../../business-components/DrivingRoute";
3
+ import { TaxiCar } from "../../business-components/TaxiCar";
4
+ import { useHeycarMap } from "../../hooks/useHeycarMap";
5
+ import { useMapDrag } from "../../hooks/useMapDrag";
3
6
  import { defineSetup } from "../../types/helper";
4
7
  import { HeycarMap, MapProvider } from "../MapProvider/MapProvider";
5
8
  import * as css from "./Demo.css";
@@ -18,28 +21,46 @@ export const HeycarDemo = defineSetup(function HeycarDemo() {
18
21
  gmapKey={gmapApiKey}
19
22
  supplier={"amap"}
20
23
  >
21
- <HeycarMap
22
- class={css.demo}
23
- fallback={() => <div>error</div>}
24
- loading={() => <div>loading</div>}
25
- center={[0, 0]}
26
- zoom={3}
27
- >
28
- <Hello />
29
- <AddressBox position={[0, 0]} title={"Martyrs Lawn"} description={"您将在此处上车"} />
30
- </HeycarMap>
24
+ <SomePage />
31
25
  </MapProvider>
32
26
  );
33
27
  });
34
28
 
35
- export const Hello = defineSetup(function Hello() {
36
- const { center, setCenter } = useMapCenter();
37
- (window as any).setCenter = setCenter;
29
+ export const SomePage = defineSetup(function Hello() {
30
+ const { mapRef, setMap, panTo } = useHeycarMap();
31
+ const { centerPlace, isDragging } = useMapDrag(mapRef);
32
+ (window as any).panTo = panTo;
38
33
  return () => {
39
- console.log("center = ", { ...center });
40
34
  return (
41
35
  <div>
42
- {center.name} | {center.lng} | {center.lat}{" "}
36
+ isDragging: {`${isDragging.value}`} <br />
37
+ {centerPlace.lng} | {centerPlace.lat} | {centerPlace.name}
38
+ <HeycarMap
39
+ class={css.demo}
40
+ fallback={() => <div>error</div>}
41
+ loading={() => <div>loading</div>}
42
+ center={[121, 31]}
43
+ zoom={15}
44
+ mapRef={setMap}
45
+ >
46
+ {/* <AddressBox position={[0, 0]} title={"Martyrs Lawn"} description={"您将在此处上车"} /> */}
47
+ {/* <TaxiCar position={[121, 31]} angle={0} /> */}
48
+ {/* <PickupPoints
49
+ positions={[
50
+ [-1, -1],
51
+ [-2, -2],
52
+ ]}
53
+ labels={["place name 1", "place name 2"]}
54
+ /> */}
55
+ <DrivingRoute
56
+ from={[121, 31]}
57
+ to={[121.6, 31.3]}
58
+ render={({ pathRef, angleRef }) => [
59
+ pathRef.value.length > 0 && <DrivingLine path={pathRef.value} />,
60
+ <TaxiCar position={[121, 31]} angle={angleRef.value} />,
61
+ ]}
62
+ />
63
+ </HeycarMap>
43
64
  </div>
44
65
  );
45
66
  };
@@ -1,28 +1,35 @@
1
1
  import { computed, h, shallowRef, watchPostEffect } from "vue-demi";
2
+ import type { SetMap } from "../../hooks/useHeycarMap";
2
3
  import { defineSetup } from "../../types/helper";
4
+ import type { MapEventHandler } from "../../types/mapHelper";
3
5
  import {
4
6
  watchNoneImmediatePostEffectForDeepOption,
5
7
  watchPostEffectForGMapEvent,
6
8
  } from "../../utils/compare";
7
9
  import { provideGmap } from "./useGmap";
8
- export interface GampProps extends google.maps.MapOptions {
9
- onCenter_changed?: (e: { target: google.maps.Map }) => void;
10
+ export interface GmapProps extends google.maps.MapOptions {
11
+ mapRef?: SetMap<google.maps.Map>;
12
+ onDragStart?: MapEventHandler<google.maps.Map>;
13
+ onDragEnd?: MapEventHandler<google.maps.Map>;
10
14
  }
11
15
 
12
- export const Gmap = defineSetup(function Gmap(props: GampProps, { slots, emit }) {
16
+ export const Gmap = defineSetup(function Gmap(props: GmapProps, { slots, emit }) {
17
+ const setMap = props.mapRef;
13
18
  const options = computed(() => {
14
- const { onCenter_changed, ...options } = props;
19
+ const { mapRef, onDragStart, onDragEnd, ...options } = props;
15
20
  return options;
16
21
  });
17
22
  const defaultOptions = options.value;
18
23
  const elementRef = shallowRef();
19
24
  const mapRef = shallowRef<google.maps.Map>();
20
- const handleCenter_changed: typeof emit = (name) => emit(name, { target: mapRef.value! });
25
+ const handleDrag: typeof emit = (name) => emit(name as any, { target: mapRef.value! });
21
26
  provideGmap(mapRef);
22
27
  watchPostEffect(() => {
23
28
  // todo 这里是否会因为 mapRef 的赋值导致不停运行?
24
29
  if (mapRef.value || !elementRef.value) return;
25
- mapRef.value = new google.maps.Map(elementRef.value, { ...defaultOptions });
30
+ const map = new google.maps.Map(elementRef.value, { ...defaultOptions });
31
+ mapRef.value = map;
32
+ setMap?.(map);
26
33
  });
27
34
  watchNoneImmediatePostEffectForDeepOption(
28
35
  () => options.value,
@@ -30,6 +37,6 @@ export const Gmap = defineSetup(function Gmap(props: GampProps, { slots, emit })
30
37
  mapRef.value?.setOptions({ ...options });
31
38
  }
32
39
  );
33
- watchPostEffectForGMapEvent(mapRef, props, handleCenter_changed, ["onCenter_changed"]);
40
+ watchPostEffectForGMapEvent(mapRef, props, handleDrag, ["onDragStart", "onDragEnd"]);
34
41
  return () => h("div", { ref: elementRef }, slots.default?.());
35
42
  });
@@ -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";
1
+ import type { SetMap } from "../../hooks/useHeycarMap";
2
+ import { defineLagecySetup } from "../../types/helper";
4
3
  import { 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,21 +19,25 @@ 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
+ mapRef?: SetMap<AMap.Map> | SetMap<google.maps.Map>;
23
+ onDragEnd?: (value: [number, number]) => any;
24
24
  }
25
- export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, { slots, emit }) {
25
+ export const HeycarMap = defineLagecySetup(function HeycarMap(
26
+ props: HeycarMapProps,
27
+ { slots, emit }
28
+ ) {
26
29
  const payload = useMapSupplier();
27
- const gmapDebouncedEmit = debounce<Required<GampProps>["onCenter_changed"]>(({ target }) => {
30
+ const gmapDebouncedEmit: GmapProps["onDragEnd"] = ({ target }) => {
28
31
  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 }) => {
32
+ emit("dragEnd", [lng(), lat()]);
33
+ };
34
+ const amapDebounceEmit: AmapProps["onDragEnd"] = ({ target }) => {
32
35
  const { lng, lat } = target.getCenter();
33
- emit("changeCenter", [lng, lat]);
34
- }, ON_CHANGE_CENTER_INTERVAL);
36
+ emit("dragEnd", [lng, lat]);
37
+ };
35
38
  return () => {
36
39
  const { gmapKey, amapKey, amapSecret, amapServiceHost, supplier, gmapId } = payload;
37
- const { fallback, loading, center, zoom } = props;
40
+ const { mapRef: setMap, fallback, loading, center, zoom } = props;
38
41
  const children = slots.default?.();
39
42
  switch (supplier) {
40
43
  case "gmap":
@@ -47,10 +50,11 @@ export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, {
47
50
  fallback={fallback}
48
51
  >
49
52
  <Gmap
53
+ mapRef={setMap as SetMap<google.maps.Map>}
50
54
  mapId={gmapId}
51
55
  center={center ? vec2lnglat(center) : undefined}
52
56
  zoom={zoom}
53
- onCenter_changed={gmapDebouncedEmit}
57
+ onDragEnd={gmapDebouncedEmit}
54
58
  >
55
59
  {children}
56
60
  </Gmap>
@@ -72,11 +76,16 @@ export const HeycarMap = defineSetup(function HeycarMap(props: HeycarMapProps, {
72
76
  loading={loading}
73
77
  fallback={fallback}
74
78
  >
75
- <Amap center={center} zoom={zoom} onMapMove={amapDebounceEmit}>
79
+ <Amap
80
+ mapRef={setMap as SetMap<AMap.Map>}
81
+ center={center}
82
+ zoom={zoom}
83
+ onDragEnd={amapDebounceEmit}
84
+ >
76
85
  {children}
77
86
  </Amap>
78
87
  </AmapLoader>
79
88
  );
80
89
  }
81
90
  };
82
- });
91
+ }).props(["center", "fallback", "loading", "mapRef", "zoom"]);