Help the algorithm do the data annotation work, see if you can use the front-end implementation, integrated data annotation function in the finished product
Target: The coordinates and pattern type of each point
1, the layout
<div class="img-box" @mousedown.stop="mousedownImg" @mousemove.stop="mouseMoveImg" @mouseout.stop="mouseOutImg" :style="{'cursor': moveFlag ? 'pointer' : 'default'}"> <img src=".. /assets/img/1.jpeg" ref="canvasImg" width="100%" id="targetImg" > <canvas id="canvas" class="canvas-box" ></canvas> <div class="sml-box" v-show="moveFlag" ref="smlBox" :style="{'left': smlBoxLf + 'px', 'top': smlBoxTop + 'px'}"> <img src=".. /assets/img/1.jpeg" class="sml-img" ref="smlImg" :style="{'left': smlImgLf + 'px', 'top': smlImgTop + 'px'}"> <span class="green-line01"></span> <span class="green-line02"></span> </div> </div>Copy the code
The image is set to 100% width and adaptive height
The width and height of the canvas depends on the width and height of the image
However, canvas has a default width and height of 300×150, which can be set with JS and CSS. However, CSS Settings will cause jagged and virtual graphics drawn, so JS Settings are used
2. Mouse operation
Calculate the position of the image in the viewable area of the browser, posiX, posiY
Mouse click event mousedownImg (e){} :
Calculate the distance from the click position to the upper left corner of the image:
The following logic:
Determine if it’s your first drawing
First drawing: Add points, draw circles
Not the first drawing: Determine if the last drawing is closed
Close: Start adding shapes again, add points, draw circles
Not closed: Determines whether the added point coincides with the first point on the graph
No overlap: continue to add dots, circles and lines
Overlap: draw lines
if (! This. DownFlag) {points: [], type: '', isClose: false } this.lineList.push(lineObj) this.lineList[0].points.push({ x: this.pointX, y: this.pointY }) this.drawArc(this.lineList[0].points[0].x, This.linelist [0].points[0].y)} else {if (this.linelist [this.linelist.length-1].isclose) {// Let lineObj = {points: [], type: '', isClose: false } this.lineList.push(lineObj) let len = this.lineList.length this.lineList[len - 1].points.push({ x: this.pointX, y: this.pointY }) this.drawArc(this.lineList[len - 1].points[0].x, This.linelist [len-1].points[0].y)} else {if (this.equalStartPoint(this.pointx, This.pointy)) {let num = this.linelist. Length this.linelist [num - 1].points.push({x: this.lineList[num - 1].points[0].x, y: this.lineList[num - 1].points[0].y }) let lineObj = this.lineList[num - 1] let n = this.lineList[num - 1].points.length this.drawLine(lineObj.points[n - 2].x, lineObj.points[n - 2].y, lineObj.points[n - 1].x, Lineobj. points[n-1].y) this.dialogVisible = true this.nowLine = num - 1} else {// do not merge let num = this.linelist.length this.lineList[num - 1].points.push({ x: this.pointX, y: this.pointY }) let n = this.lineList[num - 1].points.length let lineObj = this.lineList[num - 1] this.drawLine(lineObj.points[n - 2].x, lineObj.points[n - 2].y, lineObj.points[n - 1].x, lineObj.points[n - 1].y) this.drawArc(lineObj.points[n - 1].x, lineObj.points[n - 1].y) } } }Copy the code
Watch to monitor lineList
lineList: {
handler (newVal, oldVal) {
if (newVal.length > 0) {
this.downFlag = true
} else {
this.downFlag = false
}
},
deep: true
}
Copy the code
Circle:
drawArc (x, y) {
this.context.strokeStyle = 'blue'
this.context.beginPath()
this.context.arc(x, y, this.roundrr, 360, Math.PI * 2, true)
this.context.closePath()
this.context.stroke()
}
Copy the code
Draw lines:
drawLine (startX, startY, endX, endY) {
this.context.strokeStyle = 'blue'
this.context.lineWidth = this.lineWid
this.context.moveTo(startX, startY)
this.context.lineTo(endX, endY)
this.context.stroke()
}
Copy the code
Judge the coincidence of two points:
equalStartPoint (x, y) {
let point = this.lineList[this.lineList.length - 1].points
if (Math.abs((x - point[0].x) * (x - point[0].x)) + Math.abs((y - point[0].y) * (y - point[0].y)) <= this.roundrr * this.roundrr) {
this.lineList[this.lineList.length - 1].isClose = true
return true
} else {
this.lineList[this.lineList.length - 1].isClose = false
return false
}
}
Copy the code
Mouse movement event mouseMoveImg (e) {} :
When the mouse moves within the picture boundary, a magnifying glass mode will appear near the cursor (inspired by wechat screenshot), which is easy to click and draw pictures.
Questions to consider:
1. Boundary processing
2. In order to make the graph close, the difficulty of overlap between the last point and the starting point is solved by moving the mouse pointer to the starting point, a highlight will appear. Click on this point to overlap and close
mouseMoveImg (e) { this.moveFlag = true let pointX = e.clientX - this.posiX let pointY = e.clientY - this.posiY // Left of the larger image, Top this.smlImgLf = -(this.smlImgScl * pointX) + 50 this.smlImgTop = -(this.smlImgScl * pointY) + 50 top if (pointX > this.canvasWid - 120) { this.smlBoxLf = e.clientX - this.posiX - 120 } else { this.smlBoxLf = e.clientX - this.posiX + 20 } if (pointY > this.canvashig - 120) { this.smlBoxTop = e.clientY - this.posiY - 120 } else { this.smlBoxTop = e.clientY - this.posiY + 20 } if (this.downFlag) { let pointXSml = e.clientX - this.posiX let pointYSml = e.clientY - this.posiY let point = this.lineList[this.lineList.length - 1].points if (Math.abs((pointXSml - point[0].x) * (pointXSml - point[0].x)) + Math.abs((pointYSml - point[0].y) * (pointYSml - point[0].y)) <= this.roundrr * this.roundrr && ! this.lineList[this.lineList.length - 1].isClose) { if (! this.whiteFlage) { this.drawArcWhite(point[0].x, point[0].y) } }else { this.clearrect() } } }Copy the code
Specular white spot:
drawArcWhite (x, y) {
this.context.fillStyle = '#FFF'
this.context.beginPath()
this.context.arc(x, y, this.whiteRound, 360, Math.PI * 2, true)
this.context.closePath()
this.context.fill()
this.whiteFlage = true
}
Copy the code
Redraw the graph based on the data lineList:
clearrect () {
this.context.clearRect(0, 0, this.canvasWid, this.canvashig)
this.drawOneLine(this.lineList)
this.whiteFlage = false
}
Copy the code
Since there may be a completely closed graph in lineList, there is:
drawOneLine (lineData) {
let len = lineData.length
for (let i = 0; i < len; i++) {
let num = lineData[i].points.length
lineData[i].points.forEach((item, index) => {
if (index === 0) {
this.drawArc(item.x, item.y)
} else if (index === num) {
this.drawLine(lineData[i].points[index - 1].x, lineData[i].points[index - 1].y, item.x, item.y)
} else {
this.drawLine(lineData[i].points[index - 1].x, lineData[i].points[index - 1].y, item.x, item.y)
this.drawArc(item.x, item.y)
}
})
}
}
Copy the code
Mouse out event:
mouseOutImg () {
this.moveFlag = false
}
Copy the code
Added a retraction (delete the point of the previous step) :
resove () {
let len = this.lineList.length
if (this.lineList[len - 1].isClose) {
this.lineList[len - 1].isClose = false
}
if (this.lineList[len - 1].points.length === 1) {
this.lineList.pop()
} else {
this.lineList[len - 1].points.pop()
}
this.clearrect()
}
Copy the code
When the start and end points overlap, a pop-up box will pop up to edit the graphic type:
When you draw a graph, the related information of the graph, such as the number and type, is displayed. You can also perform related operations on the graph, such as deleting and editing the type.
Delete operation:
After labeling the graph, you can use the lineList data!
This tool is based on labelme data annotation tool to simulate, to achieve most of the functions, can carry out picture annotation on the web page, there is still a function is not realized, is drag point, in the process of editing this article, I thought of some methods, should be able to achieve, continue to improve the function!
After the map incident, I have not seen RM for a long time, no regret!
Work hard, live hard and be happy every day! With a silly dog, hahaha