Bootstrap

【es6】原生js在页面上画矩形及删除的实现方法

画一个矩形,可以选中高亮,删除自己效果的实现,后期会丰富下细节,拖动及拖动调整矩形大小

实现效果

请添加图片描述

代码实现

class Draw {
  constructor() {
    this.x = 0
    this.y = 0
    this.disX = 0
    this.disY = 0
    this.startX = 0
    this.startY = 0

    this.mouseDown = this.mouseDown.bind(this)
    this.mouseMove = this.mouseMove.bind(this)
    this.mouseUp = this.mouseUp.bind(this)
    this.zIndex = 0
    this.shadowBox = document.createElement('div')
    this.init()
  }

  init() {
    this.draw()
  }
  draw() {
    window.addEventListener('mousedown', this.mouseDown)
  }
  mouseDown(e) {
    console.log('🚀 ~ Draw ~ mouseDown ~ e:', e)
    if (e.target.className == 'delete-btn') return
    // 校验点击的是不是画的的元素
    if (e.target.className == 'draw-rect') {
      // 改变边框颜色
      this.changeBorderColor(e.target)
      return false
    } else {
      this.x = e.clientX
      this.y = e.clientY
      document.addEventListener('mousemove', this.mouseMove)
      document.addEventListener('mouseup', this.mouseUp)
    }
  }
  mouseMove(e) {
    // 不要选中文字
    e.preventDefault()
    // this.disX = e.clientX - this.x
    // this.disY = e.clientY - this.y
    // const startX = e.clientX < this.x ? e.clientX : this.x
    // const startY = e.clientY < this.y ? e.clientY : this.y
    // this.disX = e.clientX > this.x ? e.clientX - this.x : this.x - e.clientX
    // this.disY = e.clientY > this.y ? e.clientY - this.y : this.y - e.clientY
    this.startX = Math.min(e.clientX, this.x)
    this.startY = Math.min(e.clientY, this.y)
    this.disX = Math.abs(e.clientX - this.x)
    this.disY = Math.abs(e.clientY - this.y)

    // console.log('🚀 ~ Draw ~ mouseMove ~ e:', this.disX, this.disY)
    this.drawShadeRect()
  }
  mouseUp() {
    document.removeEventListener('mousemove', this.mouseMove)
    document.removeEventListener('mouseup', this.mouseUp)
    this.drawRect()
    this.shadowBox && this.shadowBox.remove()
  }
  drawShadeRect(startX, startY) {
    // console.log('🚀 ~ Draw ~ drawRect', this)
    // const div = document.createElement('div')
    this.shadowBox.style = `width: ${this.disX}px;height: ${
      this.disY
    }px;border:1px solid red;background:rgba(94,243,243,.5);position: absolute;left: ${
      this.startX
    }px;top: ${this.startY}px;z-index:${this.zIndex++}`
    document.body.appendChild(this.shadowBox)
  }
  drawRect() {
    const div = document.createElement('div')
    div.className = 'draw-rect'
    div.style = `width: ${this.disX}px;height: ${this.disY}px;border:1px solid red;position: absolute;left: ${this.startX}px;top: ${this.startY}px`
    div.appendChild(this.addDeleteBtn())
    document.body.appendChild(div)
  }
  changeBorderColor(target) {
    target.style.border = '1px solid blue'
  }
  // 动态添加一个删除按钮
  addDeleteBtn() {
    const btn = document.createElement('button')
    btn.innerHTML = '删除'
    btn.className = 'delete-btn'
    btn.style = `position: absolute;right: 0px;bottom: -25px`
    // 绑定事件
    btn.onclick = function () {
      this.parentElement.remove()
    }
    return btn
  }
}

const d = new Draw()
d.init()

当前高亮

请添加图片描述

constructor里面新增

this.allRect = []
drawRect() {
    const div = document.createElement('div')
    div.className = 'draw-rect'
    div.style = `width: ${this.disX}px;height: ${this.disY}px;border:1px solid #ccc;position: absolute;left: ${this.startX}px;top: ${this.startY}px`
    div.appendChild(this.addDeleteBtn())
    document.body.appendChild(div)
    // 收集所有的rect
    this.allRect.push(div)
    this.setCurrentBorderColor(div)
  }
changeBorderColor(target) {
    console.log('🚀 ~ Draw ~ changeBorderColor ~ target:', target)
    this.nowMoveTarget = target
    this.setCurrentBorderColor(target)
    // 改变鼠标指针
    target.style.cursor = 'move'
  }

setCurrentBorderColor方法

setCurrentBorderColor(target) {
  // 改变边框颜色,当前选中的高亮
  this.allRect.forEach((item) => {
    if (item != target) {
      item.style.border = '1px solid #ccc'
    }
  })
  target.style.border = '1px solid blue'
}


添加元素拖动效果

请添加图片描述

class Draw {
  constructor() {
    // ...
    this.nowMoveTarget = null
    this.mouseDown = this.mouseDown.bind(this)
    this.mouseMove = this.mouseMove.bind(this)
    this.mouseUp = this.mouseUp.bind(this)
    this.handleRectMove = this.handleRectMove.bind(this)
    this.handleRectUp = this.handleRectUp.bind(this)
    // ...
  }
  mouseDown(e) {
    console.log('🚀 ~ Draw ~ mouseDown ~ e:', e)
    if (e.target.className == 'delete-btn') return
    // 校验点击的是不是画的的元素
    if (e.target.className == 'draw-rect') {
      // 改变边框颜色
      this.changeBorderColor(e.target)
      this.handleRectDown(e)
      return false
    } else {
      this.x = e.clientX
      this.y = e.clientY
      document.addEventListener('mousemove', this.mouseMove)
      document.addEventListener('mouseup', this.mouseUp)
    }
  }
  mouseUp(e) {
    document.removeEventListener('mousemove', this.mouseMove)
    document.removeEventListener('mouseup', this.mouseUp)
    this.drawRect()
    this.shadowBox && this.shadowBox.remove()
  }
  drawShadeRect(startX, startY) {
    this.shadowBox.style = `width: ${this.disX}px;height: ${
      this.disY
    }px;border:1px solid red;background:rgba(94,243,243,.5);position: absolute;left: ${
      this.startX
    }px;top: ${this.startY}px;z-index:${this.zIndex++}`
    document.body.appendChild(this.shadowBox)
  }
  drawRect() {
    const div = document.createElement('div')
    div.className = 'draw-rect'
    div.style = `width: ${this.disX}px;height: ${this.disY}px;border:1px solid #ccc;position: absolute;left: ${this.startX}px;top: ${this.startY}px`
    div.appendChild(this.addDeleteBtn())
    document.body.appendChild(div)

    this.allRect.push(div)
    this.setCurrentBorderColor(div)
  }
  handleRectDown(e) {
    this.startX = e.clientX
    this.startY = e.clientY
    this.offsetX = e.clientX - this.nowMoveTarget.offsetLeft
    this.offsetY = e.clientY - this.nowMoveTarget.offsetTop
    const that = this
    document.addEventListener('mousemove', this.handleRectMove)
    document.addEventListener('mouseup', this.handleRectUp)
  }
  handleRectMove(e) {
    this.disX = e.clientX - this.offsetX
    this.disY = e.clientY - this.offsetY
    this.nowMoveTarget.style.left = `${this.disX}px`
    this.nowMoveTarget.style.top = `${this.disY}px`
  }
  handleRectUp() {
    const that = this
    console.log('🚀 ~ Draw ~ handleRectUp ~ that:', that)
    document.removeEventListener('mousemove', this.handleRectMove)
    document.removeEventListener('mouseup', this.handleRectUp)
  }
}

const d = new Draw()
d.init()

总结

  • 鼠标事件的熟练运动
  • 下步会丰富下拖动调整矩形大小的功能
;