Commit bd9f1393 authored by aoobao's avatar aoobao

fix: 当擦除整条线段时发生的bug问题

parent 1bd4bbea
// const STATUS = { // const STATUS = {
// VIEW: 0, // 查看模式 // VIEW: 0, // 查看模式
// CLEAR: 1, // 清除模式 // CLEAR: 1, // 清除模式
// EDIT: 2 // 编辑模式 // EDIT: 2 // 编辑模式
// } // }
/** /**
* opt * opt
* color : String 线段默认颜色 '#fff' * color : String 线段默认颜色 '#fff'
* pointSize : Number 点位大小 3 * pointSize : Number 点位大小 3
* pointColor : String 点位颜色 默认线段颜色 * pointColor : String 点位颜色 默认线段颜色
* lastPointColor : String 最后一个点的颜色 'red' * lastPointColor : String 最后一个点的颜色 'red'
* lastPointSize : Number 最后一个点的大小,默认pointSize * lastPointSize : Number 最后一个点的大小,默认pointSize
*/ */
export default class LineManager { export default class LineManager {
constructor(map, opt) { constructor(map, opt) {
this._initialize(map, opt || {}) this._initialize(map, opt || {})
} }
// static STATUS = { // static STATUS = {
// VIEW: 0, // 查看模式 // VIEW: 0, // 查看模式
// CLEAR: 1, // 清除模式 // CLEAR: 1, // 清除模式
// EDIT: 2 // 编辑模式 // EDIT: 2 // 编辑模式
// } // }
static VIEW = 0 static VIEW = 0
static CLEAR = 1 static CLEAR = 1
static EDIT = 2 static EDIT = 2
_initialize(map, opt) { _initialize(map, opt) {
this._map = map this._map = map
this._color = opt.color || 'yellow' this._color = opt.color || 'yellow'
this._pointSize = opt.pointSize || 3 this._pointSize = opt.pointSize || 3
this._pointColor = opt.pointColor || this._color this._pointColor = opt.pointColor || this._color
this._lastPointColor = opt.lastPointColor || 'red' this._lastPointColor = opt.lastPointColor || 'red'
this._lastPointSize = opt.lastPointSize || this._pointSize this._lastPointSize = opt.lastPointSize || this._pointSize
// this._status = LineManager.STATUS.VIEW // 默认查看模式 // this._status = LineManager.STATUS.VIEW // 默认查看模式
this._status = LineManager.VIEW this._status = LineManager.VIEW
this._lines = [] this._lines = []
this._createCustomLayer() this._createCustomLayer()
this.show() this.show()
} }
_createCustomLayer() { _createCustomLayer() {
let canvas = this._canvas = document.createElement('canvas') let canvas = this._canvas = document.createElement('canvas')
this._ctx = canvas.getContext('2d') this._ctx = canvas.getContext('2d')
let size = this._map.getSize() let size = this._map.getSize()
canvas.width = this._width = size.width canvas.width = this._width = size.width
canvas.height = this._height = size.height canvas.height = this._height = size.height
this._cus = new AMap.CustomLayer(canvas, { this._cus = new AMap.CustomLayer(canvas, {
zIndex: 10 zIndex: 10
}) })
this._cus.render = this._redraw.bind(this) this._cus.render = this._redraw.bind(this)
} }
_redraw() { _redraw() {
this._lines = this._lines.map(lineObj => { this._lines = this._lines.map(lineObj => {
let pixels = lineObj.line.map(t => this._map.lngLatToContainer(t)) let pixels = lineObj.line.map(t => this._map.lngLatToContainer(t))
let obj = { let obj = {
...lineObj, ...lineObj,
pixels pixels
} }
return obj return obj
}) })
this._draw() this._draw()
} }
_draw() { _draw() {
this._clearCanvas() this._clearCanvas()
this._drawCanvas() this._drawCanvas()
} }
_clearCanvas() { _clearCanvas() {
this._ctx.clearRect(0, 0, this._width, this._height) this._ctx.clearRect(0, 0, this._width, this._height)
} }
_drawCanvas() { _drawCanvas() {
if (!this._lines || this._lines.length == 0) return if (!this._lines || this._lines.length == 0) return
let ctx = this._ctx let ctx = this._ctx
ctx.save() ctx.save()
this._lines.forEach(lineObj => { this._lines.forEach(lineObj => {
let pixels = lineObj.pixels let pixels = lineObj.pixels
// 线条颜色 // fix : 当线段全部被擦除的时候,pixels数组为空,跳过绘制 2019-4-25
ctx.strokeStyle = lineObj.color ? lineObj.color : this._color if (pixels && pixels.length > 0) {
ctx.lineWidth = 1 // 线条颜色
ctx.beginPath() ctx.strokeStyle = lineObj.color ? lineObj.color : this._color
for (let i = 0; i < pixels.length; i++) { ctx.lineWidth = 1
let pixel = pixels[i]; ctx.beginPath()
ctx.lineTo(pixel.getX(), pixel.getY()) for (let i = 0; i < pixels.length; i++) {
} let pixel = pixels[i];
ctx.lineTo(pixel.getX(), pixel.getY())
// ctx.closePath() }
ctx.stroke()
// ctx.closePath()
// 如果当前状态不是查看状态,并且该线段没有标记锁定, 标记出每个点位. ctx.stroke()
if (this._status != LineManager.VIEW && !lineObj.lock) {
ctx.fillStyle = lineObj.pointColor ? lineObj.pointColor : this._pointColor // 如果当前状态不是查看状态,并且该线段没有标记锁定, 标记出每个点位.
for (let i = 0; i < pixels.length; i++) { if (this._status != LineManager.VIEW && !lineObj.lock) {
const pixel = pixels[i]; ctx.fillStyle = lineObj.pointColor ? lineObj.pointColor : this._pointColor
ctx.beginPath() for (let i = 0; i < pixels.length; i++) {
ctx.arc(pixel.getX(), pixel.getY(), lineObj.pointSize || this._pointSize, 0, 2 * Math.PI) const pixel = pixels[i];
ctx.fill() ctx.beginPath()
} ctx.arc(pixel.getX(), pixel.getY(), lineObj.pointSize || this._pointSize, 0, 2 * Math.PI)
} ctx.fill()
}
// 绘制最后一个点 }
let pixel = pixels[pixels.length - 1] // 最后一个点
ctx.fillStyle = lineObj.lastPointColor || this._lastPointColor // 绘制最后一个点
ctx.beginPath() let pixel = pixels[pixels.length - 1] // 最后一个点
ctx.arc(pixel.getX(), pixel.getY(), lineObj.lastPointSize || this._lastPointSize, 0, 2 * Math.PI) ctx.fillStyle = lineObj.lastPointColor || this._lastPointColor
ctx.fill() ctx.beginPath()
ctx.arc(pixel.getX(), pixel.getY(), lineObj.lastPointSize || this._lastPointSize, 0, 2 * Math.PI)
ctx.fill()
}); }
});
ctx.restore()
} ctx.restore()
}
// 生成线段
createLine(list) { // 生成线段
return new Promise(resolve => { createLine(list) {
let canvas = document.createElement('canvas') return new Promise(resolve => {
canvas.width = this._width let canvas = document.createElement('canvas')
canvas.height = this._height canvas.width = this._width
let ctx = canvas.getContext('2d') canvas.height = this._height
ctx.strokeStyle = '#000' let ctx = canvas.getContext('2d')
ctx.lineWidth = 2 ctx.strokeStyle = '#000'
ctx.beginPath() ctx.lineWidth = 2
for (let i = 0; i < list.length; i++) { ctx.beginPath()
const point = list[i]; for (let i = 0; i < list.length; i++) {
let pixel = this._map.lngLatToContainer(point) const point = list[i];
ctx.lineTo(pixel.getX(), pixel.getY()) let pixel = this._map.lngLatToContainer(point)
} ctx.lineTo(pixel.getX(), pixel.getY())
ctx.stroke() }
let dataUrl = canvas.toDataURL('image/png', 1.0) ctx.stroke()
resolve(dataUrl) let dataUrl = canvas.toDataURL('image/png', 1.0)
}) resolve(dataUrl)
} })
}
getLineList() {
let list = this._lines.map(lineObj => { getLineList() {
let obj = { let list = this._lines.map(lineObj => {
...lineObj, let obj = {
pixels: null ...lineObj,
} pixels: null
delete obj.pixels }
return obj delete obj.pixels
}) return obj
return list })
} return list.filter(t => t.line && t.line.length > 0)
}
// 擦除
clearLine(pixel, clearWidth) { // 擦除
// console.log(pixel, clearWidth) clearLine(pixel, clearWidth) {
let flag = false // console.log(pixel, clearWidth)
let lines = this._lines.map(lineObj => { let flag = false
if (lineObj.lock) return lineObj let lines = this._lines.map(lineObj => {
let obj = this.filterPixels(lineObj, pixel, clearWidth) if (lineObj.lock) return lineObj
if (obj == null) { let obj = this.filterPixels(lineObj, pixel, clearWidth)
return lineObj if (obj == null) {
} else { return lineObj
flag = true } else {
return obj flag = true
} return obj
}) }
if (flag) { })
this._lines = lines if (flag) {
this._draw() this._lines = lines
} this._draw()
} }
}
filterPixels(lineObj, pixel, clearWidth) {
let minX = pixel.getX() - clearWidth / 2 filterPixels(lineObj, pixel, clearWidth) {
let minY = pixel.getY() - clearWidth / 2 let minX = pixel.getX() - clearWidth / 2
let maxX = pixel.getX() + clearWidth / 2 let minY = pixel.getY() - clearWidth / 2
let maxY = pixel.getY() + clearWidth / 2 let maxX = pixel.getX() + clearWidth / 2
let rowIndex = null let maxY = pixel.getY() + clearWidth / 2
let rowIndex = null
let pixels = lineObj.pixels
let lines = lineObj.line let pixels = lineObj.pixels
let points = [] let lines = lineObj.line
let pointPixels = [] let points = []
for (let i = 0; i < pixels.length; i++) { let pointPixels = []
const p = pixels[i] for (let i = 0; i < pixels.length; i++) {
let line = lines[i] const p = pixels[i]
// 判断当前点位是否在擦除范围内. let line = lines[i]
if (isInPath(p, minX, minY, maxX, maxY)) { // 判断当前点位是否在擦除范围内.
if (rowIndex == null) rowIndex = i - 1 // 拿到上一个点位. if (isInPath(p, minX, minY, maxX, maxY)) {
} else { if (rowIndex == null) rowIndex = i - 1 // 拿到上一个点位.
if (rowIndex != null) { // 已经有点被擦除. } else {
points.push(line) if (rowIndex != null) { // 已经有点被擦除.
pointPixels.push(p) points.push(line)
} pointPixels.push(p)
} }
} }
// 有点位被擦除 }
if (rowIndex != null) { // 有点位被擦除
if (rowIndex > -1) { // 将头部的点加到新数组的末尾. if (rowIndex != null) {
points.push(...lines.slice(0, rowIndex + 1)) if (rowIndex > -1) { // 将头部的点加到新数组的末尾.
pointPixels.push(...pixels.slice(0, rowIndex + 1)) points.push(...lines.slice(0, rowIndex + 1))
} pointPixels.push(...pixels.slice(0, rowIndex + 1))
return { }
...lineObj, return {
pixels: pointPixels, ...lineObj,
line: points pixels: pointPixels,
} line: points
} else { }
// 没有点位被擦除,不需要修改,返回null,优化性能 } else {
return null // 没有点位被擦除,不需要修改,返回null,优化性能
} return null
} }
}
setClearModel() {
// this._status = LineManager.STATUS.CLEAR setClearModel() {
this._map.setStatus({ // this._status = LineManager.STATUS.CLEAR
dragEnable: false this._map.setStatus({
}) dragEnable: false
this._status = LineManager.CLEAR })
this._draw() this._status = LineManager.CLEAR
} this._draw()
}
setViewModel() {
this._map.setStatus({ setViewModel() {
dragEnable: true this._map.setStatus({
}) dragEnable: true
this._status = LineManager.VIEW })
this._draw() this._status = LineManager.VIEW
} this._draw()
}
setEditModel() {
this._map.setStatus({ setEditModel() {
dragEnable: true this._map.setStatus({
}) dragEnable: true
this._status = LineManager.EDIT })
this._draw() this._status = LineManager.EDIT
} this._draw()
}
/**
* 重新渲染数据 /**
* @param {Array<Opt>} list * 重新渲染数据
* opt : * @param {Array<Opt>} list
* color : String 线段默认颜色 '#fff' * opt :
* pointSize : Number 点位大小 3 * color : String 线段默认颜色 '#fff'
* pointColor : String 点位颜色 默认线段颜色 * pointSize : Number 点位大小 3
* lastPointColor : String 最后一个点的颜色 'red' * pointColor : String 点位颜色 默认线段颜色
* lastPointSize : Number 最后一个点的大小,默认pointSize * lastPointColor : String 最后一个点的颜色 'red'
* lock : Bool true代表不可擦除,编辑 * lastPointSize : Number 最后一个点的大小,默认pointSize
*/ * lock : Bool true代表不可擦除,编辑
setData(list) { */
this._lines = list setData(list) {
this._lines = list
this._redraw()
} this._redraw()
}
show() {
this._cus.setMap(this._map) show() {
} this._cus.setMap(this._map)
}
hide() {
this._cus.setMap(null) hide() {
} this._cus.setMap(null)
}
destroy() {
this.hide() destroy() {
} this.hide()
} }
}
function isInPath(pixel, minX, minY, maxX, maxY) {
let x = pixel.getX() function isInPath(pixel, minX, minY, maxX, maxY) {
let y = pixel.getY() let x = pixel.getX()
if (x >= minX && x <= maxX) { let y = pixel.getY()
if (y >= minY && y <= maxY) { if (x >= minX && x <= maxX) {
return true if (y >= minY && y <= maxY) {
} return true
} }
return false }
return false
} }
\ No newline at end of file
...@@ -98,6 +98,10 @@ export default { ...@@ -98,6 +98,10 @@ export default {
center: [120, 30] center: [120, 30]
}) })
this.map.on('click', e => {
console.log(e.lnglat)
})
// // // 测试代码 // // // 测试代码
// setTimeout(() => { // setTimeout(() => {
// this.addLine({ // this.addLine({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment