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

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

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