canvas 画区域,功能支持画多区域,删除选中拖拽,增加点的拖动
前面做了个简单的,这次有时间用es6 的class 封装了一下
本人菜鸡,觉着好用的话点个赞,觉着不好用的勿喷 谢谢!!!
init.js
//canvas video 画区域
class CanvasServer {
constructor(opts) {
this.option = opts
// 画布1
this.can = null;
// 画布2
this.canvasSaves = null;
// 画布上下文
this.ctxSave = null;
this.ctx = null;
// 临时存放绘制的点
this.pointArr = []
//拷贝存放绘制的点
this.cloneData = []
//处理后后端需要的点
this.arrData = []
//画区域所需要的点
this.newData = []
this.startDrawArea = false //true 开始画区域 false 不能操作
//拖动点的范围
this.pointRangeDrag = 5;
// 重合距离
this.coincidentDistance = 10,
//判断鼠标是否移动到起始点处,-1为否,1为是
this.oIndex = -1,
//默认线条颜色
this.defaultLineColor = "rgba(64, 158, 255, 1)"
//默认填充颜色
this.defaultFllStyle = "rgba(161,195,255,0.4)"
//默认选中颜色
this.defaultSelectStyle = "rgba(255,0,0,0.3)"
//线条颜色
this.lineColor = ''
//填充颜色
this.fillStyle = '',
//选中颜色
this.selectStyle = ''
//选中区域的下标
this.moveIndex = null
//选中点的下标
this.currentDropIndex = ''
//选中点的数据
this.currentDrop = {
}
//判断鼠标下落方式,
this.endMethod = false
this.isDropPoint = false //选中的区域某个点 是否移动
this.clickMove = false //整个区域是否移动
this.completedDraw = true //是否完成画框
this.MovePointArr = [] //移动后的数据
this.copyArrData = [] //copy ArrData
this.currentArrData = []
// 圆点的定义
this.arcInfo = {
radius: 8,
curPointColor: '#ff0000',
pointColor: 'blue'
}
// 初始化canvas
this._init(opts);
}
//初始
_init(opts) {
this.can = opts.canvas;
this.can.width = opts.width;
this.can.height = opts.height;
this.canvasSaves = opts.canvasSave
this.canvasSaves.width = opts.width
this.canvasSaves.height = opts.height
this.lineColor = opts?.lineColor || this.defaultLineColor
this.fillStyle = opts?.fillStyle || this.defaultFllStyle
this.selectStyle = opts?.selectStyle || this.defaultSelectStyle
this.ctx = this.can.getContext(`2d`);
this.ctx.strokeStyle = this.lineColor; //线条颜色
this.ctx.fillStyle = this.fillStyle; //填充颜色
this.ctxSave = this.canvasSaves.getContext(`2d`);
this.ctxSave.strokeStyle = this.lineColor; //线条颜色
this.ctxSave.fillStyle = this.fillStyle; //填充颜色
// 初始化鼠标事件
this._initCanvasEvent();
}
//添加事件
_initCanvasEvent() {
this.canvasSaves.addEventListener('mousemove', this._handleCanvasSaveMove);
this.canvasSaves.addEventListener('click', this._handleCanvasSaveClick);
this.canvasSaves.addEventListener('mousedown', this._handleMouseDown);
this.canvasSaves.addEventListener('mouseup', this._handleMouseUp);
}
_handleMouseDown = (e) => {
if (e.button == 2) return
if (this.completedDraw && this.newData.some(i => i.checked)) {
this.pointX = e.offsetX
this.pointY = e.offsetY
this.clickMove = true
return
}
this.completedDraw = false
console.log('长按鼠标', e)
}
_handleMouseUp = (e, endMethod) => {
if (e?.button == 2) return
if (this.clickMove && this.completedDraw && this.currentArrData.length > 0) {
this.clickMove = false;
this.isDropPoint = false
this.newData = JSON.parse(JSON.stringify(this.MovePointArr))
this.arrData = JSON.parse(JSON.stringify(this.currentArrData))
this.option.getData(this.arrData)
this.endMethod = endMethod || false
console.log('松下鼠标', this.arrData)
}
// console.log('松下鼠标', this.arrData)
}
//删除按钮操作
deleteCanvas(delNone) {
return delNone
}
//获取操作完成的数据
getData(arrData) {
return arrData
}
//区域回显
echoCanvas = (pointColorArr) => {
let arrData = pointColorArr.map(i => {
return i.map(j => {
let obj = {
x: j.x, //(Number(j.x) / this.scaling).toFixed(2),
y: j.y //(Number(j.y) / this.scaling).toFixed(2)
}
return obj
})
})
this.cloneData = JSON.parse(JSON.stringify(arrData))
let arr = arrData.map(item => {
let obj = {
ponitArr: item,
checked: false,
color: this.fillStyle
}
return obj
})
arr.forEach(item => {
this.moveChecked(item.ponitArr, item.color)
})
}
getGcd = (a, b) => {
let n1, n2;
if (a > b) {
n1 = a;
n2 = b;
} else {
n1 = b;
n2 = a;
}
let remainder = n1 % n2;
if (remainder === 0) {
return n2;
} else {
return this.getGcd(n2, remainder)
}
}
//绘制文字
canvasText(text, point) {
this.ctxSave.font = "20px Consolas"; //字体样式的属性
this.ctxSave.textAlign = "center"; //设置文本对齐方式
this.ctxSave.textBaseline = "middle"; //文本基线
let textWidth = this.ctxSave.measureText(text).width;
var canvasWidth = this.can.width