map-marker.js 8.0 KB
Newer Older
Q
qiang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
import getRealPath from 'uni-platform/helpers/get-real-path'

export default {
  props: {
    id: {
      type: [Number, String],
      default: ''
    },
    latitude: {
      type: [Number, String],
      require: true
    },
    longitude: {
      type: [Number, String],
      require: true
    },
    title: {
      type: String,
      default: ''
    },
    iconPath: {
      type: String,
      require: true
    },
    rotate: {
      type: [Number, String],
      default: 0
    },
    alpha: {
      type: [Number, String],
      default: 1
    },
    width: {
      type: [Number, String],
      default: ''
    },
    height: {
      type: [Number, String],
      default: ''
    },
    callout: {
      type: Object,
      default: null
    },
    label: {
      type: Object,
      default: null
    },
    anchor: {
      type: Object,
      default: null
    },
    clusterId: {
      type: [Number, String],
      default: ''
    },
    customCallout: {
      type: Object,
      default: null
    },
    ariaLabel: {
      type: String,
      default: ''
    }
  },
Q
qiang 已提交
66 67 68 69 70
  data () {
    return {
      idString: String(isNaN(Number(this.id)) ? '' : this.id)
    }
  },
Q
qiang 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  mounted () {
    const $parent = this.$parent
    $parent.mapReady(() => {
      this._maps = $parent._maps
      this._map = $parent._map
      this.addMarker(this.$props)
      Object.keys(this.$props).forEach(key => {
        this.$watch(key, () => {
          this.updateMarker(this.$props)
        })
      })
    })
  },
  beforeDestroy () {
    this.removeMarker()
  },
  methods: {
    addMarker (props) {
      const maps = this._maps
      const map = this._map
      const marker = this._marker = new maps.Marker({
        map,
        flat: true,
        autoRotation: false
      })
Q
qiang 已提交
96
      this.$parent._markers[this.idString] = marker
Q
qiang 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110
      this.updateMarker(props)
      maps.event.addListener(marker, 'click', () => {
        const callout = marker.callout
        if (callout) {
          const div = callout.div
          const parent = div.parentNode
          if (!callout.alwaysVisible) {
            callout.set('visible', !callout.visible)
          }
          if (callout.visible) {
            parent.removeChild(div)
            parent.appendChild(div)
          }
        }
Q
qiang 已提交
111
        if (this.idString) {
Q
qiang 已提交
112
          this.$parent.$trigger('markertap', {}, {
Q
qiang 已提交
113
            markerId: Number(this.idString)
Q
qiang 已提交
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
          })
        }
      })
    },
    updateMarker (option) {
      const map = this._map
      const maps = this._maps
      const marker = this._marker
      const title = option.title
      const position = new maps.LatLng(option.latitude, option.longitude)
      const img = new Image()
      img.onload = () => {
        const anchor = option.anchor || {}
        let icon
        let w
        let h
        const x = typeof anchor.x === 'number' ? anchor.x : 0.5
        const y = typeof anchor.y === 'number' ? anchor.y : 1
        if (option.iconPath && (option.width || option.height)) {
          w = option.width || (img.width / img.height) * option.height
          h = option.height || (img.height / img.width) * option.width
        } else {
          w = img.width / 2
          h = img.height / 2
        }
139
        const top = h - (h - y * h)
Q
qiang 已提交
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
        if ('MarkerImage' in maps) {
          icon = new maps.MarkerImage(
            img.src,
            null,
            null,
            new maps.Point(x * w, y * h),
            new maps.Size(w, h)
          )
        } else {
          icon = {
            url: img.src,
            anchor: new maps.Point(x, y),
            size: new maps.Size(w, h)
          }
        }
        marker.setPosition(position)
        marker.setIcon(icon)
        if ('setRotation' in marker) {
          marker.setRotation(option.rotate || 0)
        }
        const labelOpt = option.label || {}
        if ('label' in marker) {
          marker.label.setMap(null)
          delete marker.label
        }
        let label
        if (labelOpt.content) {
Q
qiang 已提交
167 168 169 170 171 172 173 174 175
          const labelStyle = {
            borderColor: labelOpt.borderColor,
            borderWidth: (Number(labelOpt.borderWidth) || 0) + 'px',
            padding: (Number(labelOpt.padding) || 0) + 'px',
            borderRadius: (Number(labelOpt.borderRadius) || 0) + 'px',
            backgroundColor: labelOpt.bgColor,
            color: labelOpt.color,
            fontSize: (labelOpt.fontSize || 14) + 'px',
            lineHeight: (labelOpt.fontSize || 14) + 'px',
Q
qiang 已提交
176 177
            marginLeft: (Number(labelOpt.anchorX || labelOpt.x) || 0) + 'px',
            marginTop: (Number(labelOpt.anchorY || labelOpt.y) || 0) + 'px'
Q
qiang 已提交
178
          }
Q
qiang 已提交
179 180 181 182 183 184
          if ('Label' in maps) {
            label = new maps.Label({
              position: position,
              map: map,
              clickable: false,
              content: labelOpt.content,
Q
qiang 已提交
185
              style: labelStyle
Q
qiang 已提交
186 187 188
            })
            marker.label = label
          } else if ('setLabel' in marker) {
Q
qiang 已提交
189
            const className = this.updateMarkerLabelStyle(this.idString, labelStyle)
Q
qiang 已提交
190 191
            marker.setLabel({
              text: labelOpt.content,
Q
qiang 已提交
192 193 194
              color: labelStyle.color,
              fontSize: labelStyle.fontSize,
              className
Q
qiang 已提交
195 196 197 198 199 200 201
            })
          }
        }
        const calloutOpt = option.callout || {}
        let callout = marker.callout
        let calloutStyle
        if (calloutOpt.content || title) {
202
          const boxShadow = '0px 0px 3px 1px rgba(0,0,0,0.5)'
Q
qiang 已提交
203 204 205 206 207 208 209 210 211 212 213
          calloutStyle = calloutOpt.content
            ? {
              position,
              map,
              top,
              content: calloutOpt.content,
              color: calloutOpt.color,
              fontSize: calloutOpt.fontSize,
              borderRadius: calloutOpt.borderRadius,
              bgColor: calloutOpt.bgColor,
              padding: calloutOpt.padding,
214
              boxShadow: calloutOpt.boxShadow || boxShadow,
Q
qiang 已提交
215 216 217 218 219 220 221
              display: calloutOpt.display
            }
            : {
              position,
              map,
              top,
              content: title,
222
              boxShadow: boxShadow
Q
qiang 已提交
223 224 225 226 227
            }
          if (callout) {
            callout.setOption(calloutStyle)
          } else {
            callout = marker.callout = new maps.Callout(calloutStyle)
Q
qiang 已提交
228
            callout.div.onclick = ($event) => {
Q
qiang 已提交
229
              if (this.idString) {
Q
qiang 已提交
230
                this.$parent.$trigger('callouttap', $event, {
Q
qiang 已提交
231
                  markerId: Number(this.idString)
Q
qiang 已提交
232 233 234 235 236 237 238 239 240 241 242 243 244
                })
              }
              $event.stopPropagation()
              $event.preventDefault()
            }
          }
        } else {
          if (callout) {
            callout.setMap(null)
            delete marker.callout
          }
        }
      }
Q
qiang 已提交
245 246 247 248 249
      if (option.iconPath) {
        img.src = getRealPath(option.iconPath)
      } else {
        console.error('Marker.iconPath is required.')
      }
Q
qiang 已提交
250
    },
Q
qiang 已提交
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
    updateMarkerLabelStyle (id, style) {
      const className = 'uni-map-marker-label-' + id
      let styleEl = document.getElementById(className)
      if (!styleEl) {
        styleEl = document.createElement('style')
        styleEl.id = className
        document.head.appendChild(styleEl)
        this.$once('hook:destroyed', () => {
          styleEl.remove()
        })
      }
      const newStyle = Object.assign({}, style, {
        position: 'absolute',
        top: '70px',
        borderStyle: 'solid'
      })
      const div = document.createElement('div')
      Object.keys(newStyle).forEach(key => {
        div.style[key] = newStyle[key] || ''
      })
      styleEl.innerText = `.${className}{${div.getAttribute('style')}}`
      return className
    },
Q
qiang 已提交
274 275 276
    removeMarker () {
      const marker = this._marker
      if (marker) {
Q
qiang 已提交
277
        if (marker.label && 'setMap' in marker.label) {
Q
qiang 已提交
278 279 280 281 282 283 284
          marker.label.setMap(null)
        }
        if (marker.callout) {
          marker.callout.setMap(null)
        }
        marker.setMap(null)
      }
Q
qiang 已提交
285
      delete this.$parent._markers[this.idString]
Q
qiang 已提交
286 287 288 289 290 291 292
      this._marker = null
    }
  },
  render () {
    return null
  }
}