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