import { MapType, getMapInfo, IS_AMAP } from '../../../helpers/location' 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: '' } }, data () { return { idString: String(isNaN(Number(this.id)) ? '' : this.id) } }, 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 }) this.$parent._markers[this.idString] = marker this.updateMarker(props) maps.event.addListener(marker, 'click', (e) => { const callout = marker.callout if (callout && !callout.alwaysVisible) { if (IS_AMAP) { callout.visible = !callout.visible if (callout.visible) { marker.callout.createAMapText() } else { marker.callout.removeAMapText() } } else { callout.set('visible', !callout.visible) if (callout.visible) { const div = callout.div const parent = div.parentNode parent.removeChild(div) parent.appendChild(div) } } } const event = e.event || e.domEvent || e.originEvent if (this.idString) { const { latitude, longitude } = this.getMarkerLatitudeLongitude(e) this.$parent.$trigger('markertap', event, { markerId: Number(this.idString), latitude, longitude }) } // 避开高德地图bug: pc端 stopPropagation 无效且地图随鼠标移动 if (event !== e.originEvent) { event.stopPropagation() } }) // 处理 google H5移动端 maker 点击触发 map 点击问题 maps.event.addListener(marker, 'mousedown', (e) => { if (e.domEvent) { e.domEvent.stopPropagation() } }) }, updateMarker (option) { const map = this._map const maps = this._maps const marker = this._marker const title = option.title const position = IS_AMAP ? new maps.LngLat(option.longitude, option.latitude) : 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 } const top = h - (h - y * h) if ('MarkerImage' in maps) { // 腾讯 & google icon = new maps.MarkerImage( img.src, null, null, new maps.Point(x * w, y * h), new maps.Size(w, h) ) } else if ('Icon' in maps) { // 高德 icon = new maps.Icon({ image: img.src, size: new maps.Size(w, h), imageSize: new maps.Size(w, h), imageOffset: new maps.Pixel(x * w, y * 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) { 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', marginLeft: (Number(labelOpt.anchorX || labelOpt.x) || 0) + 'px', marginTop: (Number(labelOpt.anchorY || labelOpt.y) || 0) + 'px' } if ('Label' in maps) { // 腾讯 label = new maps.Label({ position, map: map, clickable: false, content: labelOpt.content, style: labelStyle }) marker.label = label } else if ('setLabel' in marker) { if (IS_AMAP) { const content = `