Browse Source

feat: add map around

张延森 5 years ago
parent
commit
fef46079a1

BIN
src/assets/icons/blank.png View File


BIN
src/assets/icons/marker.png View File


BIN
src/assets/icons/marker_checked.png View File


+ 28
- 23
src/components/amap/PoiAround.js View File

@@ -1,9 +1,7 @@
1 1
 import Taro, { Component } from '@tarojs/taro'
2 2
 import { Map } from '@tarojs/components'
3 3
 
4
-const makerIcon = require('@assets/icons/marker.png')
5
-const makerCheckedIcon = require('@assets/icons/marker_checked.png')
6
-
4
+const makerIcon = require('@assets/icons/blank.png')
7 5
 
8 6
 export default class PoiAround extends Component {
9 7
 
@@ -11,41 +9,47 @@ export default class PoiAround extends Component {
11 9
     current: undefined,
12 10
   }
13 11
 
14
-  markerTap = false
15
-
16 12
   handleTap = (e) => {
17
-    const inx = e.markerId
18
-    this.markerTap = true
19
-    this.setState({ current: inx }, () => {
20
-      const marker = this.props.markers.filter((_, i) => i=== inx)[0]
21
-      this.props.onMarkerClick && this.props.onMarkerClick(marker)
22
-    })
13
+    const marker = this.props.markers.filter(x => x.id === e.markerId)[0]
14
+
15
+    this.setState({ current: e.markerId })
16
+    this.props.onMarkerClick && this.props.onMarkerClick(marker)
23 17
   }
24 18
 
25 19
   render() {
26 20
     const { current } = this.state
27 21
     const markers =  (this.props.markers || []).map((marker, index) => {
22
+
28 23
       return {
29 24
         id: marker.id,
30 25
         latitude: marker.latitude,
31 26
         longitude: marker.longitude,
32
-        iconPath: index === current && this.markerTap ? makerCheckedIcon : makerIcon,
33
-        width: marker.width,
34
-        height: marker.height,
27
+        iconPath: makerIcon,
28
+        width: 30,
29
+        height: 30,
35 30
         alpha: 0.7,
36
-        title: index + 1,
37
-        label: {
38
-          content: index + 1,
39
-          // borderRadius: 1000,
40
-          color: '#fff',
41
-          bgColor: '#f00',
31
+        // title: index + 1,
32
+        // label: {
33
+        //   content: index + 1,
34
+        //   // borderRadius: 1000,
35
+        //   color: '#fff',
36
+        //   bgColor: '#f00',
37
+        //   textAlign: 'center',
38
+        // },
39
+        callout: {
40
+          content: index + 1 > 9 ? `${index + 1}` : `0${index + 1}`,
41
+          borderRadius: 30,
42
+          borderWidth: 2,
43
+          borderColor: '#BB9C79',
44
+          padding: 5,
45
+          color: current === marker.id ? '#fff' : '#BB9C79',
46
+          bgColor: current === marker.id ? '#BB9C79' : '#fff',
42 47
           textAlign: 'center',
48
+          display: 'ALWAYS',
43 49
         },
44 50
       }
45 51
     })
46 52
 
47
-    this.markerTap = false
48
-
49 53
     return this.props.longitude && (
50 54
       <Map
51 55
         showLocation
@@ -53,7 +57,8 @@ export default class PoiAround extends Component {
53 57
         markers={markers}
54 58
         longitude={this.props.longitude}
55 59
         latitude={this.props.latitude}
56
-        onMarkerTap={this.handleTap}
60
+        onCalloutTap={this.handleTap}
61
+        style={this.props.style}
57 62
       />
58 63
     )
59 64
   }

+ 41
- 0
src/pages/project/detail/Around/Pannel.js View File

@@ -0,0 +1,41 @@
1
+import Taro from '@tarojs/taro'
2
+import { View } from '@tarojs/components'
3
+import './style.scss'
4
+
5
+export default function Pannel(props) {
6
+  const { data = [], manualData = [] } = props.dataset || {}
7
+  const activeKey = props.active
8
+
9
+  return (
10
+    <View className="around-pannel">
11
+      {
12
+        data.map((item, index) => {
13
+          const { id, name, distance } = item || {}
14
+          const dist = distance >= 1000 ? `${Number(distance / 1000).toFixed(1)}km` : `${distance}m`
15
+          const active = activeKey === id
16
+
17
+          return (
18
+            <View className={`around-cell ${active ? 'active' : ''}`} key={`auto-${id}`}>
19
+              <View className="around-cell__body">{`${index + 1}、${name}`}</View>
20
+              <View className="around-cell__action">{dist}</View>
21
+            </View>
22
+          )
23
+        })
24
+      }
25
+      {
26
+        manualData.length && (
27
+          <View className="around-cell-title">其他</View>
28
+        )
29
+      }
30
+      {
31
+        manualData.map((item, index) => {
32
+          return (
33
+            <View className="around-cell" key={`manual-${index}`}>
34
+              <View className="around-cell__body">{`${index + 1}、${item}`}</View>
35
+            </View>
36
+          )
37
+        })
38
+      }
39
+    </View>
40
+  )
41
+}

+ 31
- 0
src/pages/project/detail/Around/Tab.js View File

@@ -0,0 +1,31 @@
1
+import Taro, { useState } from '@tarojs/taro'
2
+import { View } from '@tarojs/components'
3
+import './style.scss'
4
+
5
+export default function Tab(props) {
6
+  const [current, setCurrent] = useState(props.default || 0)
7
+  const tabList = props.dataset ? props.dataset.filter(x => x.num) : []
8
+  const handleClick = index => () => {
9
+    setCurrent(index)
10
+    if (typeof props.onChange === 'function') {
11
+      props.onChange(index, tabList[index])
12
+    }
13
+  }
14
+
15
+  return (
16
+    <View className="around-tab">
17
+      {tabList.map((item, index) => {
18
+        const { key, label, num } = item || {}
19
+        return (
20
+          <View
21
+            key={key}
22
+            className={`around-tab__item ${current === index ? 'active' : ''}`}
23
+            onClick={handleClick(index)}
24
+          >
25
+            {`${label}(${num})`}
26
+          </View>
27
+        )
28
+      })}
29
+    </View>
30
+  )
31
+}

+ 76
- 0
src/pages/project/detail/Around/index.js View File

@@ -0,0 +1,76 @@
1
+import Taro, { useState } from '@tarojs/taro'
2
+import { View } from '@tarojs/components'
3
+import PoiAround from '@components/amap/PoiAround'
4
+import Tab from './Tab'
5
+import Pannel from './Pannel'
6
+import './style.scss'
7
+
8
+export default function Around(props) {
9
+  const detail = props.building || {}
10
+  const [lat, lng] = (detail.coordinate || '').split(',')
11
+  const poiDatas = detail.mapJson ? JSON.parse(detail.mapJson) : []
12
+
13
+  // 展示内容数组
14
+  const dataList = poiDatas.map((item) => {
15
+    const key = item.key
16
+    const manualData = (detail[`building${key}`] || '').split(',')
17
+
18
+    return {
19
+      ...item,
20
+      manualData,
21
+      num: (item.data || []).length + manualData.length,
22
+    }
23
+  })
24
+
25
+  // 所有的 markers
26
+  const markersList = dataList.map((item) => {
27
+    
28
+    return (item.data || []).map((it) => {
29
+      const [longitude, latitude] = it.location.split(',')
30
+
31
+      return {
32
+        id: it.id,
33
+        latitude,
34
+        longitude,
35
+        name: it.name,
36
+        address: it.address,
37
+      }
38
+    })
39
+  })
40
+
41
+  // 部分默认值
42
+  const [curTab, setCurTab] = useState(0)
43
+  const [markers, setMarkers] = useState(markersList[curTab])
44
+  const [curAD, setCurAD] = useState()
45
+  
46
+  // tab 切换
47
+  const handleTabChange = (index, tabItem) => {
48
+    setCurTab(index)
49
+    setMarkers(markersList[index])
50
+  }
51
+
52
+  // marker 点切换
53
+  const handleMarkerTap = (marker) => {
54
+    setCurAD(marker.id)
55
+  }
56
+
57
+  const goto = () => {
58
+    if (typeof props.onAction === 'function') {
59
+      props.onAction()
60
+    }
61
+  }
62
+  
63
+  return (
64
+    <View className="around-box">
65
+      <View className="around-header">
66
+        <PoiAround style="width: 100vw; height: 500rpx;" markers={markers} longitude={lng} latitude={lat} onMarkerClick={handleMarkerTap}/>
67
+      </View>
68
+      <View className="around-body">
69
+        <Tab dataset={dataList} onChange={handleTabChange} />
70
+        <Pannel active={curAD} dataset={dataList[curTab]} />
71
+        <View className="goto-map" onClick={goto}>立即前往</View>
72
+        <View className="around-hr" />
73
+      </View>
74
+    </View>
75
+  )
76
+}

+ 104
- 0
src/pages/project/detail/Around/style.scss View File

@@ -0,0 +1,104 @@
1
+@import "@styles/mixins.scss";
2
+@import "@styles/theme.scss";
3
+
4
+.around-box {
5
+  width: 100vw;
6
+  background-color: #fff;
7
+    
8
+  .around-header {
9
+    width: 100%;
10
+    height: 500px;
11
+  }
12
+
13
+  .around-body {
14
+    padding: 0 30px;
15
+  
16
+    .goto-map {
17
+      width: 670px;
18
+      height: 94px;
19
+      background-color: #F8F8F8;
20
+      border-radius: 8px;
21
+      margin: 0 auto;
22
+      margin-top: 40px;
23
+      text-align: center;
24
+      font-size: 36px;
25
+      font-weight:400;
26
+      color:#BB9C79;
27
+      line-height: 94px;
28
+    }
29
+  }
30
+}
31
+
32
+.around-tab {
33
+  display: flex;
34
+  flex-wrap:nowrap;
35
+  align-items: center;
36
+  overflow-x: scroll;
37
+  scroll-behavior: smooth;
38
+  padding: 24px 0;
39
+
40
+  &__item {
41
+    flex: 1 0 auto;
42
+
43
+    font-size: 32px;
44
+    color:#666;
45
+    line-height: 44px;
46
+    padding: 4px 0;
47
+
48
+    &.active {
49
+      color: #BB9C79;
50
+      border-bottom: 1px solid #C8B299;
51
+    }
52
+
53
+    & + & {
54
+      margin-left: 64px;
55
+    }
56
+  }
57
+}
58
+
59
+.around-hr {
60
+  // width: 200px;
61
+  height: 8px;
62
+  margin: 20px auto 30px auto;
63
+  // background-color:rgba(0,0,0,0.12);
64
+  // border-radius:4px;
65
+}
66
+
67
+.around-pannel {
68
+  margin-top: 30px;
69
+}
70
+
71
+.around-cell {
72
+  display: flex;
73
+  align-items: center;
74
+  width: 100%;
75
+  font-size: 32px;
76
+  font-weight: 400;
77
+  color: #666;
78
+  line-height: 44px;
79
+
80
+  &.active {
81
+    color: #BB9C79;
82
+  }
83
+
84
+  & + .around-cell {
85
+    margin-top: 26px;
86
+  }
87
+
88
+  &__body {
89
+    flex: auto;
90
+  }
91
+
92
+  &__action {
93
+    flex: none;
94
+    width: 200px;
95
+  }
96
+}
97
+
98
+.around-cell-title {
99
+  font-size: 32px;
100
+  font-weight: 700;
101
+  color:#666;
102
+  line-height: 44px;
103
+  margin: 42px auto 20px 0;
104
+}

+ 11
- 50
src/pages/project/detail/index.js
File diff suppressed because it is too large
View File