提交 049e00e9 编写于 作者: d-u-a's avatar d-u-a

add vue <map>

上级 9d71a65d
<template>
<uni-map
v-bind="attrs"
v-on="$listeners">
<div
ref="container"
class="uni-map-container" />
<v-uni-cover-image
v-for="(control, index) in mapControls"
:key="index"
:src="control.iconPath"
:style="control.position"
@click="controlclick(control)"/>
<div class="uni-map-slot">
<slot />
</div>
</uni-map>
</template>
<script>
import {
subscriber
} from 'uni-mixins'
import native from '../../mixins/native'
const methods = [
'getCenterLocation',
'moveToLocation',
'getRegion',
'getScale',
'$getAppMap'
]
const events = [
'markertap',
'callouttap',
'controltap',
'regionchange',
'tap',
'updated'
]
const attrs = [
'latitude',
'longitude',
'scale',
'markers',
'polyline',
'circles',
'controls',
'show-location'
]
const convertCoordinates = (lng, lat, callback) => {
// plus.maps.Map.convertCoordinates(new plus.maps.Point(lng, lat), {
// coordType: 'gcj02'
// }, callback)
callback({
coord: {
latitude: lat,
longitude: lng
}
})
}
export default {
name: 'Map',
mixins: [subscriber, native],
props: {
id: {
type: String,
default: ''
},
latitude: {
type: [Number, String],
default: ''
},
longitude: {
type: [Number, String],
default: ''
},
scale: {
type: [String, Number],
default: 1
},
markers: {
type: Array,
default () {
return []
}
},
polyline: {
type: Array,
default () {
return []
}
},
circles: {
type: Array,
default () {
return []
}
},
controls: {
type: Array,
default () {
return []
}
}
},
data () {
return {
style: {
top: '0px',
left: '0px',
width: '0px',
height: '0px',
position: 'static'
},
hidden: false
}
},
computed: {
attrs () {
const obj = {}
attrs.forEach(key => {
let val = this.$props[key]
val = key === 'src' ? this.$getRealPath(val) : val
obj[key.replace(/[A-Z]/g, str => '-' + str.toLowerCase())] = val
})
return obj
},
mapControls () {
const list = this.controls.map((control) => {
let position = { position: 'absolute' };
['top', 'left', 'width', 'height'].forEach(key => {
position[key] = control.position[key] + 'px'
})
return {
id: control.id,
iconPath: this.$getRealPath(control.iconPath),
position: position
}
})
return list
}
},
watch: {
hidden (val) {
this.map && this.map[val ? 'hide' : 'show']()
}
},
listeners: {
'@view-update': '_requestUpdate'
},
mounted () {
this._updateStyle()
let mapStyle = Object.assign({}, this.attrs, this.style)
if (this.latitude && this.longitude) {
mapStyle.center = new plus.maps.Point(this.longitude, this.latitude)
}
const map = this.map = plus.maps.create('map' + Date.now(), mapStyle)
map.__markers__ = {}
map.__lines__ = []
map.__circles__ = []
plus.webview.currentWebview().append(map)
if (this.hidden) {
map.hide()
}
this.$watch('attrs', () => {
this.map && this.map.setStyles(this.attrs)
}, {
deep: true
})
this.$watch('style', () => {
this.map && this.map.setStyles(this.style)
}, {
deep: true
})
map.onclick((data = {}) => {
this.$trigger('tap', {}, data)
})
map.onstatuschanged((data = {}) => {
this.$trigger('end', {}, data)
})
this._addMarkers(this.markers)
this._addMapLines(this.polyline)
this._addMapCircles(this.circles)
},
beforeDestroy () {
delete this.map
},
methods: {
_handleSubscribe ({
type,
data = {}
}) {
if (!methods.includes(type)) {
return
}
this.map && this[type](data)
},
getRegion () {
// TODO
const region = this.map.getBounds()
},
getScale () {
// TODO
const zoom = this.map.getZoom()
},
_updateStyle () {
const rect = this.$refs.container.getBoundingClientRect()
this.hidden = false;
['top', 'left', 'width', 'height'].forEach(key => {
let val = rect[key]
val = key === 'top' ? val + (document.documentElement.scrollTop || document.body.scrollTop || 0) : val
if (!val && (key === 'width' || key === 'height')) {
this.hidden = true
}
this.style[key] = val + 'px'
})
},
_requestUpdate () {
if (this._animationFrame) {
cancelAnimationFrame(this._animationFrame)
}
if (this.video) {
this._animationFrame = requestAnimationFrame(() => {
delete this._animationFrame
this._updateStyle()
})
}
},
controlclick (e) {
this.$trigger('controltap', {}, { id: e.id })
},
_addMarker (nativeMap, marker) {
const {
id,
title,
latitude,
longitude,
iconPath,
width,
height,
rotate,
alpha,
callout,
label
} = marker
convertCoordinates(longitude, latitude, res => {
const {
latitude,
longitude
} = res.coord
const nativeMarker = new plus.maps.Marker(new plus.maps.Point(longitude, latitude))
if (iconPath) {
nativeMarker.setIcon(this.$getRealPath(iconPath))
}
if (label && label.content) {
nativeMarker.setLabel(label.content)
}
let nativeBubble = false
if (callout && callout.content) {
nativeBubble = new plus.maps.Bubble(callout.content)
}
if (nativeBubble) {
nativeMarker.setBubble(nativeBubble)
}
if (id || id === 0) {
nativeMarker.onclick = (e) => {
this.$trigger('markertap', {}, {
id
})
}
if (nativeBubble) {
nativeBubble.onclick = () => {
this.$trigger('callouttap', {}, {
id
})
}
}
}
nativeMap.addOverlay(nativeMarker)
nativeMap.__markers__[id + ''] = nativeMarker
})
},
_addMarkers (markers, clear) {
if (this.map) {
if (clear) {
this.map.clearOverlays()
}
markers.forEach(marker => {
this._addMarker(this.map, marker)
})
return {
errMsg: 'addMapMarkers:ok'
}
}
return {
errMsg: 'addMapMarkers:fail:请先创建地图元素'
}
},
_translateMapMarker ({
autoRotate,
callbackId,
destination,
duration,
markerId
}) {
if (this.map) {
const nativeMarker = this.map.__markers__[markerId + '']
if (nativeMarker) {
nativeMarker.setPoint(new plus.maps.Point(destination.longitude, destination.latitude))
}
}
return {
errMsg: 'translateMapMarker:ok'
}
},
_addMapLines (lines) {
const nativeMap = this.map
if (!nativeMap) {
return {
errMsg: 'addMapLines:fail:请先创建地图元素'
}
}
if (nativeMap.__lines__.length > 0) {
nativeMap.__lines__.forEach(circle => {
nativeMap.removeOverlay(circle)
})
nativeMap.__lines__ = []
}
lines.forEach(line => {
const {
color,
width,
dottedLine,
arrowLine,
arrowIconPath,
borderColor,
borderWidth
} = line
const points = line.points.map(point => new plus.maps.Point(point.longitude, point.latitude))
const polyline = new plus.maps.Polyline(points)
if (color) {
const strokeStyle = parseHex(color)
polyline.setStrokeColor(strokeStyle.color)
polyline.setStrokeOpacity(strokeStyle.opacity)
}
if (width) {
polyline.setLineWidth(width)
}
nativeMap.addOverlay(polyline)
nativeMap.__lines__.push(polyline)
})
return {
errMsg: 'addMapLines:ok'
}
},
_addMapCircles (circles) {
const nativeMap = this.map
if (!nativeMap) {
return {
errMsg: 'addMapCircles:fail:请先创建地图元素'
}
}
if (nativeMap.__circles__.length > 0) {
nativeMap.__circles__.forEach(circle => {
nativeMap.removeOverlay(circle)
})
nativeMap.__circles__ = []
}
circles.forEach(circle => {
const {
latitude,
longitude,
color,
fillColor,
radius,
strokeWidth
} = circle
const nativeCircle = new plus.maps.Circle(new plus.maps.Point(longitude, latitude), radius)
if (color) {
const strokeStyle = parseHex(color)
nativeCircle.setStrokeColor(strokeStyle.color)
nativeCircle.setStrokeOpacity(strokeStyle.opacity)
}
if (fillColor) {
const fillStyle = parseHex(fillColor)
nativeCircle.setFillColor(fillStyle.color)
nativeCircle.setFillOpacity(fillStyle.opacity)
}
if (strokeWidth) {
nativeCircle.setLineWidth(strokeWidth)
}
nativeMap.addOverlay(nativeCircle)
nativeMap.__circles__.push(nativeCircle)
})
return {
errMsg: 'addMapCircles:ok'
}
}
}
}
</script>
<style>
uni-map {
width: 300px;
height: 225px;
display: inline-block;
line-height: 0;
overflow: hidden;
position: relative;
}
uni-map[hidden] {
display: none;
}
.uni-map-container {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
background-color: black;
}
.uni-map-slot {
position: absolute;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册