click
事件获取点击的坐标,用fillRect
方法绘制一个直径4像素的小矩形,作为点(也可以做圆形)moveTo,lineTo
方法连线注意: 双击事件会触发两次单击事件,需要处理一下,网上找的方法:
click(){
clearTimeout(timer)
timer = setTimeout(()=>{
// xxx
},200)
}
dbclick(){
clearTimeout(timer)
// xxxx
}
打点式标注部分代码
this.ctx.drawImage(this.image,0,0,this.w,this.h)
// 绘制矩形小点
this.ctx.fillStyle="#FF0000";
this.ctx.fillRect(e.offsetX - 2, e.offsetY - 2, 4, 4);
//连线 tempPointArr是储存坐标点的数组,双击形成闭环后清空
this.ctx.beginPath()
this.ctx.strokeStyle= '#FF0000'
this.ctx.moveTo(this.tempPointArr[this.tempPointArr.length - 2].x,this.tempPointArr[this.tempPointArr.length - 2].y);
this.ctx.lineTo(this.tempPointArr[this.tempPointArr.length - 1].x,this.tempPointArr[this.tempPointArr.length - 1].y);
this.ctx.stroke();
mousedown
mousemove
mouseup
来完成mousedown
事件获取开始的坐标mousemove
事件使用strokeRect
画矩形,但要注意先清空,再画新的,否则会导致有很多矩形框mouseup
事件清空开始坐标,完成一个矩形框的绘制鼠标按下时记录当前canvas 内容,在每一次鼠标拖动时先还原之前干净的canvas内容,再画新的矩形,达到先清空再画新矩形的目的
重点代码:
mousedown(){
this.imgData = this.ctx.getImageData(0,0,this.w,this.h)
}
mousemove(){
this.ctx.putImageData(this.imgData,0,0)
}
矩形框标注部分代码
mousedown(){
this.startPoint = {
x:e.offsetX,
y:e.offsetY
}
this.imgData = this.ctx.getImageData(0,0,this.w,this.h)
}
mousemove(){
this.ctx.putImageData(this.imgData,0,0)
this.ctx.beginPath()
this.ctx.fillStyle = "rgba(255,0,0,0.1)";
this.ctx.strokeStyle = '#FF0000';
this.ctx.strokeRect(this.startPoint.x,this.startPoint.y,e.offsetX - this.startPoint.x,e.offsetY - this.startPoint.y);
}
mouseup(){
this.startPoint = null
}
在有内容的地方才弹出,没有内容的地方不弹
主要使用坐标点去判断在不在某一个范围内,之前把每一个绘制的内容都存储成数组
思路:右键的坐标点必须满足大于某个x点,小于另一个x点,大于某个y点,小于另一个y点,则表示在这个内容区域内
部分代码
const index = this.pointData.findIndex((item)=>{
let leftX = false
let rightX = false
let topY = false
let bottomY = false
item.point.forEach(p=>{
if(e.offsetX > p.x){
leftX = true
}
if(e.offsetX < p.x){
rightX = true
}
if(e.offsetY < p.y){
bottomY = true
}
if(e.offsetY > p.y){
topY = true
}
})
return leftX && rightX && topY && bottomY
})
if(index > -1){
/**
xxxxxx
*/
this.fillRect(this.pointData[index].point) //给这个区域填充背景色,表示高亮
}
思路:使用橡皮擦模拟实现删除效果,canvas下面要有多一张背景图,否则的话会直接擦成白色;
使用完后再使用其他功能切记要把globalCompositeOperation
属性从destination-out
改回默认值source-over
部分代码
this.ctx.globalCompositeOperation = 'destination-out' //重点
/**
...重新绘制一次要删除的内容
*/
this.ctx.globalCompositeOperation = 'source-over'
使用
fillText
方法添加文本
在添加新的文本前先清除掉之前写的文本,主要使用clearRect
方法
部分代码
let textW = this.ctx.measureText(this.textObj[this.selectedIndex]).width
this.ctx.clearRect(this.pointData[this.selectedIndex].point[0].x + 5,this.pointData[this.selectedIndex].point[0].y - 8 - 12 ,textW,13)
this.ctx.font="12px Arial"
this.ctx.fillStyle ='#FF0000'
this.ctx.fillText(this.note,this.pointData[this.selectedIndex].point[0].x + 5,this.pointData[this.selectedIndex].point[0].y - 8)
大致思路到此为止
多次使用
geiImageData
putImageData
来实现保存某一步的内容,再显示;
也可以利用这个实现撤销的功能
如果需要完整的代码可以去git 上下载一下,也希望有大佬可以帮忙优化一下代码,感谢~~~
最后附上地址:
https://gitee.com/cuijinrong/project-gather/blob/master/src/components/marker.vue