提交 8319b947 编写于 作者: L liyongning

feat: 1、polygon 暴露的属性、事件对齐微信小程序;2、兼容 google 地图

上级 80811c9a
import {
hasOwn
}
from 'uni-shared'
from 'uni-shared'
export const pixelRatio = (function () {
const canvas = document.createElement('canvas')
......
import {
noop
}
from 'uni-shared'
from 'uni-shared'
const sharedPropertyDefinition = {
enumerable: true,
......
......@@ -14,7 +14,7 @@ import {
import {
lifecycleMixin
}
from 'uni-core/service/plugins/lifecycle'
from 'uni-core/service/plugins/lifecycle'
import {
VD_SYNC_VERSION
......@@ -23,7 +23,7 @@ import {
import {
ON_REACH_BOTTOM_DISTANCE
}
from '../../constants'
from '../../constants'
import {
NAVBAR_HEIGHT
......
......@@ -9,7 +9,7 @@ import {
getApp,
getCurrentPages
}
from 'uni-core/service/plugins/app'
from 'uni-core/service/plugins/app'
initOn(UniServiceJSBridge.on, {
getApp,
......
......@@ -10,7 +10,7 @@
/>
<map-polygon
v-for="item in polygons"
:key="JSON.stringify(item)"
:key="JSON.stringify(item.points)"
v-bind="item"
/>
<div
......
......@@ -2,34 +2,8 @@ const { assign, create } = Object
// 事件对象,以腾讯原生事件名为 key,对外暴露的对应事件名为 value
export const eventObj = assign(create(null), {
// 当此多边形所在地图更改时会触发此事件
map_changed: 'polygonmapchanged',
// 当此多边形可见性更改时会触发此事件
visible_changed: 'polygonvisiblechanged',
// 当此多边形zIndex更改时会触发此事件
zindex_changed: 'polygonzindexchange',
// 点击此多边形后会触发此事件
click: 'polygontap',
// 双击多边形后会触发此事件
dblclick: 'polygondblclick',
// 右键点击多边形后会触发此事件
rightclick: 'polygonrightclick',
// 鼠标在多边形内按下触发此事件
mousedown: 'polygonmousedown',
// 鼠标在多边形上抬起时触发此事件
mouseup: 'polygonmouseup',
// 当鼠标进入多边形区域时会触发此事件
mouseover: 'polygonmouseover',
// 鼠标离开多边形时触发此事件
mouseout: 'polygonmouseout',
// 鼠标在多边形内移动时触发此事件
mousemove: 'polygonmousemove',
// 编辑多边形添加节点时触发此事件
insertNode: 'polygoninsertnode',
// 编辑多边形删除节点时触发此事件
removeNode: 'polygonremovenode',
// 编辑多边形移动节点时触发此事件
adjustNode: 'polygonadjustnode'
click: 'polygontap'
})
/**
......@@ -41,7 +15,7 @@ export function listenEvent (
trigger
) {
for (const key in eventObj) {
maps.event.addListener(polygonIns, key, function (e) {
maps.event.addDomListener(polygonIns, key, function (e) {
// 要对外暴露的事件
const eVal = eventObj[key]
e ? trigger(eVal, {}, e) : trigger(eVal, {})
......
import { hexToRgba } from 'uni-shared'
import { listenEvent } from './event'
// 变量声明放外面,而不是放组件实例上的原因也是和下面 $watch 部分描述的问题有关
let polygonIns = null
export default {
props: {
// 边框虚线,腾讯地图支持,google 地图不支持,默认值为[0, 0] 为实线,非 [0, 0] 为虚线,H5 端无法像微信小程序一样控制虚线的间隔像素大小
dashArray: {
type: Array,
default: () => [0, 0]
},
// 经纬度数组,[{latitude: 0, longitude: 0}]
points: {
type: Array,
required: true
},
// 多边形是否可点击。
clickable: {
type: Boolean
},
// 鼠标在多边形内的光标样式。
cursor: {
type: String
},
// 区域是否可编辑
editable: {
type: Boolean,
default: false
},
// 多边形是否可见。
visible: {
type: Boolean,
default: true
},
// 描边的宽度
strokeWidth: {
type: Number
},
// 描边的颜色,十六进制
strokeColor: {
type: String
},
// 描边的透明度,[0-1]
strokeColorAlpha: {
type: Number,
default: 1
},
// 多边形的边框样式。实线是solid,虚线是dash。
strokeDashStyle: {
type: String
// 描边的颜色,十六进制
strokeColor: {
type: String,
default: '#000000'
},
// 填充颜色,十六进制
fillColor: {
type: String
},
// 设置填充色的透明度,[0-1]
fillColorAlpha: {
type: Number,
default: 1
type: String,
default: '#00000000'
},
// 设置多边形 Z 轴数值
zIndex: {
type: Number
type: Number,
default: 0
}
},
mounted () {
......@@ -68,11 +42,6 @@ export default {
// 遍历 props 对象,观察其中的每个属性,当属性发生变化时,更新地图上的 polygon
Object.keys(this.$props).forEach(key => {
/**
* 这段其实暂时没有用,因为 props 更新时组件会重新挂载,而不是直接更新。
* 问题可能出在 uni-app 重写 Vue 时某些地方有问题。
* 但先留着这部分内容,防止以后 uni-app 修复该问题后 polygon 更新出问题
*/
this.$watch(key, () => {
this.drawPolygon()
}, { deep: true })
......@@ -85,17 +54,11 @@ export default {
// polygon 组件的 props 配置
const {
points,
clickable,
cursor,
editable,
strokeWidth,
strokeColor,
strokeColorAlpha,
strokeDashStyle,
dashArray,
fillColor,
fillColorAlpha,
zIndex,
visible
zIndex
} = this
// 从父组件解析 _maps、_map 和 $trigger,下面要用
......@@ -106,63 +69,76 @@ export default {
return new _maps.LatLng(latitude, longitude)
})
// 将 16 进制的色值转换为 rgb 的格式
const { r: fcR, g: fcG, b: fcB } = hexToRgba(fillColor || '#5f9ea0')
const { r: scR, g: scG, b: scB } = hexToRgba(strokeColor || '#000000')
const { r: fcR, g: fcG, b: fcB, a: fcA } = hexToRgba(fillColor)
const { r: scR, g: scG, b: scB, a: scA } = hexToRgba(strokeColor)
const polygonOptions = {
// 多边形是否可点击。
clickable: clickable || true,
clickable: true,
// 鼠标在多边形内的光标样式。
cursor: cursor || 'crosshair',
cursor: 'crosshair',
// 多边形是否可编辑。
editable,
// 多边形的填充色,可通过Color对象的alpha属性设置透明度。
fillColor: new _maps.Color(fcR, fcG, fcB, fillColorAlpha),
editable: false,
// 地图实例,即要显示多边形的地图
// @ts-ignore
map: _map,
// 区域填充色
fillColor: '',
// 多边形的路径,以经纬度坐标数组构成。
path,
// 多边形的线条颜色,可通过Color对象的alpha属性设置透明度。
strokeColor: new _maps.Color(scR, scG, scB, strokeColorAlpha),
// 区域边框
strokeColor: '',
// 多边形的边框样式。实线是solid,虚线是dash。
strokeDashStyle: strokeDashStyle || 'dash',
strokeDashStyle: dashArray.some((item) => item > 0) ? 'dash' : 'solid',
// 多边形的边框线宽。
strokeWeight: strokeWidth || 5,
strokeWeight: strokeWidth,
// 多边形是否可见。
visible,
visible: true,
// 多边形的zIndex值。
zIndex: zIndex || 1000
zIndex: zIndex
}
// 多边形的填充色、边框以及相应的透明度
if (_maps.Color) {
// 说明是 腾讯地图,google map 实例没有 Color 属性
// 将类型转为两者共有的 string,避免 ts 报错
polygonOptions.fillColor = new _maps.Color(fcR, fcG, fcB, fcA)
polygonOptions.strokeColor = new _maps.Color(scR, scG, scB, scA)
} else {
// google map
polygonOptions.fillColor = `rgb(${fcR}, ${fcG}, ${fcB})`
polygonOptions.fillOpacity = fcA
polygonOptions.strokeColor = `rgb(${scR}, ${scG}, ${scB})`
polygonOptions.strokeOpacity = scA
}
if (polygonIns) {
if (this.polygonIns) {
// 更新区域属性
polygonIns.setOptions(polygonOptions)
this.polygonIns.setOptions(polygonOptions)
return
}
// 说明是新增区域
polygonIns = new _maps.Polygon(polygonOptions)
this.polygonIns = new _maps.Polygon(polygonOptions)
// 监听事件,当对应事件发生时,将事件暴露给用户
listenEvent(_maps, polygonIns, this.$parent.$trigger)
listenEvent(_maps, this.polygonIns, this.$parent.$trigger)
}
},
// 卸载时清除地图上绘制的 polygon
beforeDestroy () {
polygonIns.setMap(null)
polygonIns = null
this.polygonIns.setMap(null)
this.polygonIns = null
},
render () {
return null
......
/**
* 从 16 进制的色值解析成 rgba 格式的色值
* @param { string } hex, #000、#000A、#000000、#000000AA,参数只能是这四种格式
* @returns {
r: number;
g: number;
b: number;
a: number;
}
*/
export function hexToRgba (hex) {
let r
let g
let b
hex = hex.replace('#', '')
if (hex.length === 6) {
r = hex.substring(0, 2)
g = hex.substring(2, 4)
b = hex.substring(4, 6)
} else if (hex.length === 3) {
r = hex.substring(0, 1)
g = hex.substring(1, 2)
b = hex.substring(2, 3)
} else {
return false
// 异常情况
if (!hex) {
return {
r: 0,
g: 0,
b: 0,
a: 0
}
}
if (r.length === 1) {
r += r
// 去掉 #
let tmpHex = hex.slice(1)
const tmpHexLen = tmpHex.length
// 处理 16 进制色值位数异常的情况
if (![3, 4, 6, 8].includes(tmpHexLen)) {
return {
r: 0,
g: 0,
b: 0,
a: 0
}
}
if (g.length === 1) {
g += g
// 格式化 tmpHex,使其变成 rrggbb 或 rrggbbaa
if (tmpHexLen === 3 || tmpHexLen === 4) {
// rgb => rrggbb || rgba => rrggbbaa
tmpHex = tmpHex.replace(/(\w{1})/g, 'r1r1')
}
if (b.length === 1) {
b += b
// r1 ~ a2
const [r1, r2, g1, g2, b1, b2, a1, a2] = tmpHex.match(/(\w{1})/g)
// rgb
const r = parseInt(r1) * 16 + parseInt(r2); const g = parseInt(g1) * 16 + parseInt(g2); const b = parseInt(b1) * 16 + parseInt(b2)
if (!a1) {
return { r, g, b, a: 1 }
}
r = parseInt(r, 16)
g = parseInt(g, 16)
b = parseInt(b, 16)
return {
r,
g,
b
r, g, b, a: (`0x100${a1}${a2}` - 0x10000) / 255
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册