@heycar/heycars-map 0.3.1 → 0.3.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.
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .n8tgem0{position:absolute;bottom:50%;left:0;right:0;margin-left:auto;margin-right:auto;display:flex;flex-direction:column;align-items:center;z-index:1}.n8tgem1{padding:2.67vw 4.27vw;background:linear-gradient(90deg,#79AFFF 0%,#5C8DFF 32%,#507FFF 75%,#4471FF 100%);border-radius:3.2vw;display:flex;align-items:center}.n8tgem2{padding-right:2.67vw;max-width:41.33vw}.n8tgem3{display:-webkit-box;font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#fff;line-height:4.8vw;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.n8tgem4{margin-top:.53vw;font-size:2.93vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#fff;line-height:4.27vw;opacity:.8}.n8tgem5{width:1.758vw;height:2.93vw}.n8tgem6{width:.8vw;height:4vw;background:#4C80FF;border-radius:0vw 0vw 26.67vw 26.67vw}.n8tgem7{width:6.9355vw;height:10.67vw}.rgf09w0{width:7.1045vw;height:10.93vw;display:flex}._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}._1d8ur7t0,._7anfuo0{position:relative}._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}._1l6offo0{display:flex}._1l6offo1{width:4.53vw;height:4.53vw;margin-bottom:-2.265vw}._1l6offo2{width:16.27vw;height:16.27vw;margin-bottom:-8.135vw}.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{opacity:0}.fhyw8b{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#243e66;line-height:4.53vw;white-space:nowrap}._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}
1
+ .n8tgem0{pointer-events:none;position:absolute;bottom:50%;left:0;right:0;margin-left:auto;margin-right:auto;display:flex;flex-direction:column;align-items:center;z-index:1}.n8tgem1{pointer-events:auto;padding:2.67vw 4.27vw;background:linear-gradient(90deg,#79AFFF 0%,#5C8DFF 32%,#507FFF 75%,#4471FF 100%);border-radius:3.2vw;display:flex;align-items:center}.n8tgem2{padding-right:2.67vw;max-width:41.33vw}.n8tgem3{display:-webkit-box;font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#fff;line-height:4.8vw;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.n8tgem4{margin-top:.53vw;font-size:2.93vw;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;color:#fff;line-height:4.27vw;opacity:.8}.n8tgem5{width:1.758vw;height:2.93vw}.n8tgem6{width:.8vw;height:4vw;background:#4C80FF;border-radius:0vw 0vw 26.67vw 26.67vw}.n8tgem7{width:6.9355vw;height:10.67vw}.rgf09w0{width:7.1045vw;height:10.93vw;display:flex}._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}._1d8ur7t0,._7anfuo0{position:relative}._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}._1l6offo0{display:flex}._1l6offo1{width:4.53vw;height:4.53vw;margin-bottom:-2.265vw}._1l6offo2{width:16.27vw;height:16.27vw;margin-bottom:-8.135vw}.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{opacity:0}.fhyw8b{font-size:3.47vw;font-family:PingFangSC-Semibold,PingFang SC;font-weight:600;color:#243e66;line-height:4.53vw;white-space:nowrap}._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}
@@ -14,7 +14,7 @@ export interface AutoCompletePlace extends Place {
14
14
  placeId?: string;
15
15
  description: string;
16
16
  }
17
- export type City = {
17
+ export type Region = {
18
18
  bound?: {
19
19
  east: number;
20
20
  north: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heycar/heycars-map",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite -c vite.config.dev.ts",
@@ -1,4 +1,4 @@
1
- import { computed } from "vue-demi";
1
+ import { computed, reactive } from "vue-demi";
2
2
  import {
3
3
  BusinessRecomendPlaceMap,
4
4
  BusinessRecomendPlaceMapProps,
@@ -6,6 +6,7 @@ import {
6
6
  import { useBusinessMapAutoComplete } from "../hooks-business/useBusinessMapAutoComplete";
7
7
  import { useBusinessRecomendPlaceMap } from "../hooks-business/useBusinessRecomendPlaceMap";
8
8
  import { defineSetup } from "../types/helper";
9
+ import type { Region } from "../types/interface";
9
10
  import * as css from "./Demo.css";
10
11
 
11
12
  const SomeAutoComplete = defineSetup(function SomeAutoComplete(props: { cityName: string }) {
@@ -32,6 +33,8 @@ const SomeAutoComplete = defineSetup(function SomeAutoComplete(props: { cityName
32
33
  });
33
34
 
34
35
  export const DemoBusinessRecomendPlace = defineSetup(function DemoBusinessRecomendPlace() {
36
+ const city = reactive<Region>({ name: "" });
37
+ const cityParent = reactive<Region>({ name: "" });
35
38
  const getRecomendPlace: BusinessRecomendPlaceMapProps["getRecomendPlace"] = async (
36
39
  place,
37
40
  context
@@ -46,22 +49,22 @@ export const DemoBusinessRecomendPlace = defineSetup(function DemoBusinessRecome
46
49
  const {
47
50
  centerPlace,
48
51
  placeCandidates,
49
- setCenterPlaceByRecomand,
52
+ setCenterPlaceByUserSpecified,
50
53
  mapContext,
51
- apiMapDistance,
52
54
  panToGeoPositionByRecomend,
53
55
  } = useBusinessRecomendPlaceMap();
54
- (window as any).setCenterPlaceByRecomand = setCenterPlaceByRecomand;
56
+ (window as any).setCenterPlaceByUserSpecified = setCenterPlaceByUserSpecified;
55
57
  (window as any).panToGeoPositionByRecomend = panToGeoPositionByRecomend;
56
58
  return () => {
57
59
  return (
58
60
  <div>
59
61
  placeCandidates: {placeCandidates} <br />
60
- centerPlace: {centerPlace.lng} | {centerPlace.lat} | {centerPlace.name} |{" "}
61
- {centerPlace.cityName} | {centerPlace.cityParentName} | {centerPlace.countryName} <br />
62
+ centerPlace: {centerPlace.lng} | {centerPlace.lat} | {centerPlace.name} | {city.name} |{" "}
63
+ {cityParent.name} <br />
62
64
  <SomeAutoComplete cityName="Shinjuku-ku"></SomeAutoComplete>
63
65
  <BusinessRecomendPlaceMap
64
66
  class={css.demo}
67
+ geoLoadingTitle={"正在读取GPS位置信息..."}
65
68
  unavailableTitle={"当前区域暂未开通服务"}
66
69
  noRecomendDescription={"附近无推荐上车地点"}
67
70
  recomendDescription={"最佳上车地点"}
@@ -70,6 +73,10 @@ export const DemoBusinessRecomendPlace = defineSetup(function DemoBusinessRecome
70
73
  mapContext={mapContext}
71
74
  onGeoError={(e) => console.log("onGeoError e = ", e)}
72
75
  onClickLocator={() => alert("hi")}
76
+ onChangeCity={({ cityName, cityParentName }) => {
77
+ city.name = cityName ?? "";
78
+ cityParent.name = cityParentName ?? "";
79
+ }}
73
80
  />
74
81
  </div>
75
82
  );
@@ -1,6 +1,7 @@
1
1
  import { style } from "@vanilla-extract/css";
2
2
 
3
3
  export const absoluteAddressBoxLayout = style({
4
+ pointerEvents: "none",
4
5
  position: "absolute",
5
6
  bottom: "50%",
6
7
  left: 0,
@@ -14,6 +15,7 @@ export const absoluteAddressBoxLayout = style({
14
15
  });
15
16
 
16
17
  export const absoluteAddressBox = style({
18
+ pointerEvents: "auto",
17
19
  padding: "2.67vw 4.27vw",
18
20
  background: "linear-gradient(90deg, #79AFFF 0%, #5C8DFF 32%, #507FFF 75%, #4471FF 100%)",
19
21
  borderRadius: "3.2vw",
@@ -23,6 +23,7 @@ export interface BusinessRecomendPlaceMapProps
23
23
  extends Omit<HeycarMapProps, "center" | "zoom" | "mapRef">,
24
24
  Pick<UseMapRecomendPlaceProps<CenterPlaceSource>, "getRecomendPlace">,
25
25
  MapLogProps {
26
+ geoLoadingTitle: string;
26
27
  unavailableTitle: string;
27
28
  recomendDescription: string;
28
29
  noRecomendDescription: string;
@@ -33,6 +34,7 @@ export interface BusinessRecomendPlaceMapProps
33
34
  onChangeByDrag?: UseMapDragProps["onChange"];
34
35
  onChangeGeoLocation?: UseGeoLocationProps["onChange"];
35
36
  onChangePlace?: UseMapPlaceProps["onChange"];
37
+ onChangeCity?: UseMapPlaceProps["onChangeCity"];
36
38
  onChangeRecomandPlace?: UseMapRecomendPlaceProps["onChange"];
37
39
  onGeoError?: UseGeoLocationProps["onError"];
38
40
  onClickLocator?: AbsoluteAddressBoxProps["onClick"];
@@ -47,15 +49,18 @@ export const BusinessRecomendPlaceMap = defineLagecySetup(
47
49
  lng: geoDefaultPosition?.[0] ?? 0,
48
50
  lat: geoDefaultPosition?.[1] ?? 0,
49
51
  name: "",
50
- cityName: undefined,
51
52
  });
52
53
  const centerPoint = computed<Point>(() => [centerPlace.lng, centerPlace.lat]);
53
54
  const centerSource: CenterPlaceSource = { source: "geo" };
54
55
  const setCenterPlaceByRecomand = (point: Point) => {
55
56
  centerSource.source = "api";
56
- centerPlace.lng = point[0];
57
- centerPlace.lat = point[1];
58
- updatePlace();
57
+ updatePlace(point);
58
+ };
59
+ const setCenterPlaceByUserSpecified = (place: Place) => {
60
+ centerSource.source = "api";
61
+ setPlace(place);
62
+ updateCity(place);
63
+ updateRecomandPlace();
59
64
  };
60
65
  const setCenterByPlace = (place: Place) => {
61
66
  centerSource.source = "api";
@@ -64,30 +69,26 @@ export const BusinessRecomendPlaceMap = defineLagecySetup(
64
69
  centerPlace.name = place.name;
65
70
  };
66
71
 
67
- const { geoPosition, geoError } = useGeoLocation({
72
+ const { geoPosition, geoError, geoLoading } = useGeoLocation({
68
73
  geoDefaultPosition,
69
74
  onLoad: async (value) => {
70
75
  // geo 主入口
71
76
  await readyPromise;
72
77
  centerSource.source = "geo";
73
- centerPlace.lng = value.position[0];
74
- centerPlace.lat = value.position[1];
75
- updatePlace();
78
+ updatePlace(value.position);
76
79
  emit("loadGeoLocation", value);
77
80
  },
78
81
  onLoadDefault: async (value) => {
79
82
  // geo default position 主入口
80
83
  await readyPromise;
81
84
  centerSource.source = "geo";
82
- centerPlace.lng = value.position[0];
83
- centerPlace.lat = value.position[1];
84
- updatePlace();
85
+ updatePlace(value.position);
85
86
  emit("loadDefaultGeoLocation", value);
86
87
  },
87
88
  onChange: (v) => emit("changeGeoLocation", v),
88
89
  onError: (e) => emit("geoError", e),
89
90
  });
90
- mapContext.setCenterPlaceByRecomand = setCenterPlaceByRecomand;
91
+ mapContext.setCenterPlaceByUserSpecified = setCenterPlaceByUserSpecified;
91
92
  mapContext.panToGeoPositionByRecomend = () => {
92
93
  if (geoError.value) return false;
93
94
  setCenterPlaceByRecomand(geoPosition.value);
@@ -97,45 +98,49 @@ export const BusinessRecomendPlaceMap = defineLagecySetup(
97
98
  mapRef,
98
99
  onChange: (point) => {
99
100
  centerSource.source = "drag";
100
- centerPlace.lng = point[0];
101
- centerPlace.lat = point[1];
102
- updatePlace();
101
+ updatePlace(point);
103
102
  emit("changeByDrag", point);
104
103
  },
105
104
  });
106
- const { updatePlace, updateRecomandPlace, placeCandidates, availableRef } = useMapRecomendPlace(
107
- {
108
- pointRef: centerPoint,
109
- context: centerSource,
110
- getRecomendPlace,
111
- getLimit: (context) => {
112
- const source = context?.source;
113
- switch (source) {
114
- case "drag":
115
- case "api":
116
- return RECOMMEND_PLACE_LIMIT;
117
- case "geo":
118
- case "default":
119
- return Infinity;
120
- default:
121
- throw new Error(`MyError: should not call getLimit on source: ${source}`);
122
- }
123
- },
124
- onChangePlace: (place) => {
125
- Object.assign(centerPlace, { ...place });
126
- if (centerSource.source !== "recomend") {
127
- updateRecomandPlace();
128
- }
129
- emit("changePlace", place);
130
- },
131
- onChange: (place) => {
132
- centerSource.source = "recomend";
133
- Object.assign(centerPlace, { ...place });
134
- updatePlace();
135
- emit("changeRecomandPlace", place);
136
- },
137
- }
138
- );
105
+ const {
106
+ updatePlace,
107
+ setPlace,
108
+ updateCity,
109
+ updateRecomandPlace,
110
+ placeCandidates,
111
+ availableRef,
112
+ } = useMapRecomendPlace({
113
+ pointRef: centerPoint,
114
+ context: centerSource,
115
+ getRecomendPlace,
116
+ getLimit: (context) => {
117
+ const source = context?.source;
118
+ switch (source) {
119
+ case "drag":
120
+ case "api":
121
+ return RECOMMEND_PLACE_LIMIT;
122
+ case "geo":
123
+ case "default":
124
+ return Infinity;
125
+ default:
126
+ throw new Error(`MyError: should not call getLimit on source: ${source}`);
127
+ }
128
+ },
129
+ onChangePlace: (place) => {
130
+ if (centerSource.source !== "recomend") {
131
+ updateRecomandPlace();
132
+ }
133
+ emit("changePlace", place);
134
+ },
135
+ onChange: (place) => {
136
+ centerSource.source = "recomend";
137
+ Object.assign(centerPlace, { ...place });
138
+ emit("changeRecomandPlace", place);
139
+ },
140
+ onChangeCity: (value) => {
141
+ emit("changeCity", value);
142
+ },
143
+ });
139
144
  watchEffect(() => {
140
145
  mapContext.onChangeCenterPlace({ ...centerPlace });
141
146
  });
@@ -143,6 +148,11 @@ export const BusinessRecomendPlaceMap = defineLagecySetup(
143
148
  mapContext.onChangeRecomendPlaces([...placeCandidates.value]);
144
149
  });
145
150
  return () => {
151
+ const title = geoLoading.value
152
+ ? props.geoLoadingTitle
153
+ : availableRef.value
154
+ ? centerPlace.name
155
+ : props.unavailableTitle;
146
156
  const description = !availableRef.value
147
157
  ? undefined
148
158
  : placeCandidates.value.length > 0
@@ -153,7 +163,7 @@ export const BusinessRecomendPlaceMap = defineLagecySetup(
153
163
  <PassengerCircle position={geoPosition.value} />
154
164
  <PickupPoints places={placeCandidates.value} onClick={setCenterByPlace} log={props.log} />
155
165
  <AbsoluteAddressBox
156
- title={availableRef.value ? centerPlace.name : props.unavailableTitle}
166
+ title={title}
157
167
  description={description}
158
168
  type={isDragging.value ? "locator" : "box"}
159
169
  log={props.log}
@@ -165,6 +175,7 @@ export const BusinessRecomendPlaceMap = defineLagecySetup(
165
175
  }
166
176
  ).props([
167
177
  "log",
178
+ "geoLoadingTitle",
168
179
  "unavailableTitle",
169
180
  "recomendDescription",
170
181
  "noRecomendDescription",
@@ -10,6 +10,7 @@ export interface UseGeoLocationProps {
10
10
  }
11
11
  export const useGeoLocation = (props?: UseGeoLocationProps) => {
12
12
  const { onChange, onLoad, onLoadDefault, onError, geoDefaultPosition } = props ?? {};
13
+ let isOnLoadDefaultTriggered = false;
13
14
  const loading = ref(false);
14
15
  const readyRef = ref(false);
15
16
  const errorRef = ref<GeolocationPositionError>();
@@ -44,12 +45,15 @@ export const useGeoLocation = (props?: UseGeoLocationProps) => {
44
45
  loading.value = false;
45
46
  errorRef.value = error;
46
47
  const position = props?.geoDefaultPosition;
47
- if (position) onLoadDefault?.({ position });
48
+ if (position && !isOnLoadDefaultTriggered) {
49
+ isOnLoadDefaultTriggered = true;
50
+ onLoadDefault?.({ position });
51
+ }
48
52
  onError?.(error);
49
53
  console.log("errorRef = ", errorRef);
50
54
  },
51
55
  // todo 要不要 timeout
52
- { timeout: 5000, maximumAge: 0, enableHighAccuracy: true }
56
+ { timeout: 3000, maximumAge: 0, enableHighAccuracy: false }
53
57
  );
54
58
  onCleanup(() => navigator.geolocation.clearWatch(watchId));
55
59
  },
@@ -1,11 +1,11 @@
1
1
  import { ref, watch } from "vue-demi";
2
- import type { AutoCompletePlace, City } from "../types/interface";
2
+ import type { AutoCompletePlace, Region } from "../types/interface";
3
3
  import { MapLogProps, useMapLogVariable } from "./useMapLog";
4
4
  import { useMapSupplier } from "./useMapSupplier";
5
5
  import { useUpdate } from "./useUdate";
6
6
 
7
7
  export interface UseMapAutoCompleteProps extends MapLogProps {
8
- city: City;
8
+ city: Region;
9
9
  }
10
10
 
11
11
  export const useAmapAutoComplete = (props: UseMapAutoCompleteProps) => {
@@ -16,7 +16,7 @@ export const useAmapAutoComplete = (props: UseMapAutoCompleteProps) => {
16
16
  const keywordRef = ref("");
17
17
  const autoCompletePlacesRef = ref<AutoCompletePlace[]>([]);
18
18
  const { update, idx: updateKey } = useUpdate();
19
- const setCity = (value: City) => {
19
+ const setCity = (value: Region) => {
20
20
  cityRef.value = value;
21
21
  update();
22
22
  };
@@ -65,7 +65,7 @@ export const useGmapAutoComplete = (props: UseMapAutoCompleteProps) => {
65
65
  const keywordRef = ref("");
66
66
  const autoCompletePlacesRef = ref<AutoCompletePlace[]>([]);
67
67
  const { update, idx: updateKey } = useUpdate();
68
- const setCity = (value: City) => {
68
+ const setCity = (value: Region) => {
69
69
  cityRef.value = value;
70
70
  update();
71
71
  };
@@ -1,13 +1,13 @@
1
1
  import { reactive, Ref, watch, watchEffect } from "vue-demi";
2
2
  import { LANGUAGE } from "../types/helper";
3
- import type { City } from "../types/interface";
3
+ import type { Region } from "../types/interface";
4
4
  import { useMapSupplier } from "./useMapSupplier";
5
5
 
6
6
  export interface UseMapCityBoundProps {
7
7
  cityNameRef: Ref<string | undefined>;
8
- onChange?: (value: City) => any;
8
+ onChange?: (value: Region) => any;
9
9
  }
10
- export const useAmapBoundCity = (props: UseMapCityBoundProps): City => {
10
+ export const useAmapBoundCity = (props: UseMapCityBoundProps): Region => {
11
11
  const { cityNameRef, onChange } = props;
12
12
  const city = reactive({ name: cityNameRef.value ?? "" });
13
13
  watch(
@@ -21,10 +21,10 @@ export const useAmapBoundCity = (props: UseMapCityBoundProps): City => {
21
21
  return city;
22
22
  };
23
23
 
24
- export const useGmapBoundCity = (props: UseMapCityBoundProps): City => {
24
+ export const useGmapBoundCity = (props: UseMapCityBoundProps): Region => {
25
25
  const { cityNameRef, onChange } = props;
26
26
  const { readyPromise } = useMapSupplier();
27
- const city = reactive<City>({
27
+ const city = reactive<Region>({
28
28
  name: cityNameRef.value ?? "",
29
29
  bound: {
30
30
  east: 0,
@@ -18,9 +18,12 @@ export const useAmapDrag = (props: UseMapDragProps<AMap.Map>) => {
18
18
  const centerRef = ref<Point>([0, 0]);
19
19
  const isDragging = ref(false);
20
20
  const emitDragStart: SetupContextEmitHandler<Pick<AmapProps, "onDragStart">> = () => {
21
- Promise.resolve().then(() => (isDragging.value = true));
21
+ pipeAsync(() => {
22
+ isDragging.value = true;
23
+ });
22
24
  };
23
25
  const emitDragEnd: SetupContextEmitHandler<Pick<AmapProps, "onDragEnd">> = (_, { target }) => {
26
+ console.log("on DragEnd ------");
24
27
  isDragging.value = false;
25
28
  const { lng, lat } = target.getCenter();
26
29
  centerRef.value = [lng, lat];
@@ -40,7 +43,9 @@ export const useGmapDrag = (props: UseMapDragProps<google.maps.Map>) => {
40
43
  const centerRef = ref<Point>([0, 0]);
41
44
  const isDragging = ref(false);
42
45
  const emitDragStart: SetupContextEmitHandler<Pick<GmapProps, "onDragStart">> = () => {
43
- Promise.resolve().then(() => (isDragging.value = true));
46
+ pipeAsync(() => {
47
+ isDragging.value = true;
48
+ });
44
49
  };
45
50
  const emitDragEnd: SetupContextEmitHandler<Pick<GmapProps, "onDragEnd">> = async () => {
46
51
  isDragging.value = false;
@@ -1,24 +1,50 @@
1
- import { reactive, Ref, watch } from "vue-demi";
1
+ import { reactive, ref, Ref, watch } from "vue-demi";
2
2
  import { LANGUAGE } from "../types/helper";
3
3
  import type { Place, Point } from "../types/interface";
4
4
  import { geocoderResult2cityName } from "../utils/transform";
5
5
  import { useMapSupplier } from "./useMapSupplier";
6
6
  import { useUpdate } from "./useUdate";
7
7
 
8
+ export interface UseMapPlaceOnChangeCityProps {
9
+ cityName?: string;
10
+ cityParentName?: string;
11
+ }
8
12
  export interface UseMapPlaceProps {
9
13
  pointRef: Ref<Point>;
10
14
  onChange?: (value: Place) => any;
15
+ onChangeCity?: (value: UseMapPlaceOnChangeCityProps) => any;
11
16
  }
12
17
  export const useAmapPlace = (props: UseMapPlaceProps) => {
13
- const { pointRef, onChange } = props;
18
+ const { onChange, onChangeCity } = props;
19
+ const defaultPoint: Point = [...props.pointRef.value];
20
+ const pointRef = ref<Point>(defaultPoint);
14
21
  const { readyPromise } = useMapSupplier();
15
- const { idx: placeKey, update: updatePlace } = useUpdate();
16
22
  const place = reactive<Place>({
17
23
  lng: pointRef.value[0],
18
24
  lat: pointRef.value[1],
19
25
  name: "",
20
- cityName: undefined,
21
26
  });
27
+ const { idx: placeKey, update } = useUpdate();
28
+ const updateCity = (value: Place) => {
29
+ const geocoder = new AMap.Geocoder({ lang: LANGUAGE });
30
+ const { lng, lat } = value;
31
+ geocoder.getAddress(new AMap.LngLat(lng, lat), (status, result) => {
32
+ if (status !== "complete") return;
33
+ const { addressComponent } = (result as AMap.ReGeocoderResult).regeocode;
34
+ const cityName = addressComponent.city ? addressComponent.city : addressComponent.province;
35
+ const cityParentName = addressComponent.province;
36
+ onChangeCity?.({ cityName, cityParentName });
37
+ });
38
+ };
39
+ const updatePlace = (value: Point) => {
40
+ pointRef.value = value;
41
+ update();
42
+ };
43
+ const setPlace = (value: Place) => {
44
+ place.lng = value.lng;
45
+ place.lat = value.lat;
46
+ place.name = value.name;
47
+ };
22
48
  watch(
23
49
  () => placeKey.value,
24
50
  async () => {
@@ -33,15 +59,12 @@ export const useAmapPlace = (props: UseMapPlaceProps) => {
33
59
  const cityName = addressComponent.city
34
60
  ? addressComponent.city
35
61
  : addressComponent.province;
36
- const countryName = addressComponent.country;
37
62
  const cityParentName = addressComponent.province;
38
63
  place.name = name;
39
64
  place.lng = lng;
40
65
  place.lat = lat;
41
- place.cityName = cityName;
42
- place.cityParentName = cityParentName;
43
- place.countryName = countryName;
44
- onChange?.({ lng, lat, name, cityName, cityParentName, countryName });
66
+ onChange?.({ lng, lat, name });
67
+ onChangeCity?.({ cityName, cityParentName });
45
68
  return;
46
69
  }
47
70
 
@@ -55,14 +78,31 @@ export const useAmapPlace = (props: UseMapPlaceProps) => {
55
78
  });
56
79
  }
57
80
  );
58
- return { place, updatePlace };
81
+ return { place, updatePlace, setPlace, updateCity };
59
82
  };
60
83
 
61
84
  export const useGmapPlace = (props: UseMapPlaceProps) => {
62
- const { pointRef, onChange } = props;
85
+ const { pointRef, onChange, onChangeCity } = props;
63
86
  const { readyPromise } = useMapSupplier();
64
87
  const { idx: placeKey, update: updatePlace } = useUpdate();
65
- const place = reactive<Place>({ lng: pointRef.value[0], lat: pointRef.value[1], name: "" });
88
+ const place = reactive<Place>({
89
+ lng: pointRef.value[0],
90
+ lat: pointRef.value[1],
91
+ name: "",
92
+ });
93
+ const setPlace = (value: Place) => {
94
+ place.lng = value.lng;
95
+ place.lat = value.lat;
96
+ place.name = value.name;
97
+ };
98
+ const updateCity = async (value: Place) => {
99
+ const geocoder = new google.maps.Geocoder();
100
+ const { lng, lat } = value;
101
+ const { results } = await geocoder.geocode({ language: LANGUAGE, location: { lng, lat } });
102
+ const cityName = geocoderResult2cityName(results[0]);
103
+ const cityParentName = results.slice(-2)[0].address_components[0].long_name;
104
+ onChangeCity?.({ cityName, cityParentName });
105
+ };
66
106
  watch(
67
107
  () => placeKey.value,
68
108
  async () => {
@@ -73,17 +113,15 @@ export const useGmapPlace = (props: UseMapPlaceProps) => {
73
113
  const name = results[0].formatted_address;
74
114
  const cityName = geocoderResult2cityName(results[0]);
75
115
  const cityParentName = results.slice(-2)[0].address_components[0].long_name;
76
- const countryName = results.slice(-1)[0].address_components[0].long_name;
116
+ // const countryName = results.slice(-1)[0].address_components[0].long_name;
77
117
  place.lng = lng;
78
118
  place.lat = lat;
79
119
  place.name = name;
80
- place.cityName = cityName;
81
- place.cityParentName = cityParentName;
82
- place.countryName = countryName;
83
- onChange?.({ lng, lat, name, cityName, cityParentName, countryName });
120
+ onChange?.({ lng, lat, name });
121
+ onChangeCity?.({ cityName, cityParentName });
84
122
  }
85
123
  );
86
- return { place, updatePlace };
124
+ return { place, updatePlace, setPlace, updateCity };
87
125
  };
88
126
 
89
127
  export const useMapPlace = (props: UseMapPlaceProps) => {
@@ -35,16 +35,22 @@ export interface UseMapRecomendPlaceProps<C = Record<string, any>> {
35
35
  getLimit: (context?: C) => number;
36
36
  // 如果返回 undefined, 表示当前位置无服务可提供
37
37
  getRecomendPlace: (place: Place, context?: C) => Promise<Place[] | undefined>;
38
+ onChangeCity?: UseMapPlaceProps["onChangeCity"];
38
39
  onChangePlace?: UseMapPlaceProps["onChange"];
39
40
  onChange?: (place: Place) => any;
40
41
  }
41
42
  export const useAmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<C>) => {
42
- const { pointRef, getRecomendPlace, getLimit, context, onChange, onChangePlace } = props;
43
+ const { pointRef, getRecomendPlace, getLimit, context, onChange, onChangePlace, onChangeCity } =
44
+ props;
43
45
  const availableRef = ref(true);
44
46
  const placeCandidatesRef = ref<Place[]>([]);
45
47
  const { idx: recomendPlaceKey, update: updateRecomandPlace } = useUpdate();
46
48
  const { readyPromise } = useMapSupplier();
47
- const { place, updatePlace } = useAmapPlace({ pointRef, onChange: onChangePlace });
49
+ const { place, updatePlace, setPlace, updateCity } = useAmapPlace({
50
+ pointRef,
51
+ onChange: onChangePlace,
52
+ onChangeCity,
53
+ });
48
54
  const recomendPlace = reactive<Place>({ ...place });
49
55
  watch(
50
56
  () => recomendPlaceKey.value,
@@ -73,16 +79,23 @@ export const useAmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<C>) => {
73
79
  availableRef,
74
80
  updateRecomandPlace,
75
81
  updatePlace,
82
+ setPlace,
83
+ updateCity,
76
84
  };
77
85
  };
78
86
 
79
87
  export const useGmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<C>) => {
80
- const { pointRef, getRecomendPlace, getLimit, context, onChange, onChangePlace } = props;
88
+ const { pointRef, getRecomendPlace, getLimit, context, onChange, onChangePlace, onChangeCity } =
89
+ props;
81
90
  const availableRef = ref(true);
82
91
  const placeCandidatesRef = ref<Place[]>([]);
83
92
  const { idx: recomendPlaceKey, update: updateRecomandPlace } = useUpdate();
84
93
  const { readyPromise } = useMapSupplier();
85
- const { place, updatePlace } = useGmapPlace({ pointRef, onChange: onChangePlace });
94
+ const { place, updatePlace, setPlace, updateCity } = useGmapPlace({
95
+ pointRef,
96
+ onChange: onChangePlace,
97
+ onChangeCity,
98
+ });
86
99
  const recomendPlace = reactive<Place>({ ...place });
87
100
  watch(
88
101
  () => recomendPlaceKey.value,
@@ -111,6 +124,8 @@ export const useGmapRecomendPlace = <C>(props: UseMapRecomendPlaceProps<C>) => {
111
124
  availableRef,
112
125
  updateRecomandPlace,
113
126
  updatePlace,
127
+ setPlace,
128
+ updateCity,
114
129
  };
115
130
  };
116
131
 
@@ -4,7 +4,7 @@ import type { Place, Point } from "../types/interface";
4
4
 
5
5
  export interface BusinessRecomendPlaceContext {
6
6
  panToGeoPositionByRecomend: (value: Point) => void;
7
- setCenterPlaceByRecomand: (value: Point) => void;
7
+ setCenterPlaceByUserSpecified: (value: Place) => void;
8
8
  onChangeCenterPlace: (value: Place) => void;
9
9
  onChangeRecomendPlaces: (value: Place[]) => void;
10
10
  }
@@ -14,17 +14,17 @@ export const useBusinessRecomendPlaceMap = () => {
14
14
  lng: 0,
15
15
  lat: 0,
16
16
  name: "",
17
- cityName: undefined,
18
17
  });
19
18
  const placeCandidates = ref<Place[]>([]);
20
19
  const { apiMapDistance } = useMapGeometry();
21
20
  const panToGeoPositionByRecomend = (value: Point) => mapContext.panToGeoPositionByRecomend(value);
22
- const setCenterPlaceByRecomand = (value: Point) => mapContext.setCenterPlaceByRecomand(value);
21
+ const setCenterPlaceByUserSpecified = (value: Place) =>
22
+ mapContext.setCenterPlaceByUserSpecified(value);
23
23
  const mapContext: BusinessRecomendPlaceContext = {
24
24
  panToGeoPositionByRecomend: () => {
25
25
  throw new Error("MyError: panToGeoPositionByRecomend used before assigned");
26
26
  },
27
- setCenterPlaceByRecomand: () => {
27
+ setCenterPlaceByUserSpecified: () => {
28
28
  throw new Error("MyError: setCenterPlaceByRecomand used before assigned");
29
29
  },
30
30
  onChangeCenterPlace: (place: Place) => {
@@ -39,7 +39,7 @@ export const useBusinessRecomendPlaceMap = () => {
39
39
  centerPlace,
40
40
  placeCandidates,
41
41
  panToGeoPositionByRecomend,
42
- setCenterPlaceByRecomand,
42
+ setCenterPlaceByUserSpecified,
43
43
  apiMapDistance,
44
44
  };
45
45
  };
@@ -16,7 +16,7 @@ export interface AutoCompletePlace extends Place {
16
16
  description: string;
17
17
  }
18
18
 
19
- export type City = {
19
+ export type Region = {
20
20
  bound?: {
21
21
  east: number;
22
22
  north: number;