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

ops/2024/11/27 19:05:57/

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

实现效果

请添加图片描述

代码实现

class Draw {constructor() {this.x = 0this.y = 0this.disX = 0this.disY = 0this.startX = 0this.startY = 0this.mouseDown = this.mouseDown.bind(this)this.mouseMove = this.mouseMove.bind(this)this.mouseUp = this.mouseUp.bind(this)this.zIndex = 0this.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.clientXthis.y = e.clientYdocument.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.clientYthis.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)// 收集所有的rectthis.allRect.push(div)this.setCurrentBorderColor(div)}
changeBorderColor(target) {console.log('🚀 ~ Draw ~ changeBorderColor ~ target:', target)this.nowMoveTarget = targetthis.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 = nullthis.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.clientXthis.y = e.clientYdocument.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.clientXthis.startY = e.clientYthis.offsetX = e.clientX - this.nowMoveTarget.offsetLeftthis.offsetY = e.clientY - this.nowMoveTarget.offsetTopconst that = thisdocument.addEventListener('mousemove', this.handleRectMove)document.addEventListener('mouseup', this.handleRectUp)}handleRectMove(e) {this.disX = e.clientX - this.offsetXthis.disY = e.clientY - this.offsetYthis.nowMoveTarget.style.left = `${this.disX}px`this.nowMoveTarget.style.top = `${this.disY}px`}handleRectUp() {const that = thisconsole.log('🚀 ~ Draw ~ handleRectUp ~ that:', that)document.removeEventListener('mousemove', this.handleRectMove)document.removeEventListener('mouseup', this.handleRectUp)}
}const d = new Draw()
d.init()

总结

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

http://www.ppmy.cn/ops/137146.html

相关文章

获 2023 年度浙江省科学技术进步奖一等奖 | 网易数智日报

11 月 22 日&#xff0c;加快建设创新浙江因地制宜发展新质生产力动员部署会暨全省科学技术奖励大会在杭州隆重召开。浙江大学、网易数智等单位联合研发的“大规模结构化数据智能计算平台及产业化”项目获得 2023 年度浙江省科学技术进步奖一等奖。 加快建设创新浙江因地制宜发…

微信万能门店小程序系统存在任意文件读取漏洞

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…

如何开发历史题材游戏。

历史题材的数据整理要领&#xff1a;1. 当时的主流文化和著名作品&#xff1b;2. 后世的一些追记与创作&#xff08;与相关观点和主张的发端有关&#xff09;&#xff1b;3. 高频词汇和用语&#xff08;不一定是当时的实际数据、来源可以是后来的一些创作&#xff0c;关键在于体…

调用 AWS Lambda 时如何传送字节数组

本文主要验证用 Python 写的 AWS Lambda 与 Java 客户端之间如何双向传递二进制数据&#xff0c;这里不涉及到 Lambda 流输入输出的问题。比如一个 Python AWS Lambda 的处理方法声明是 def lambda_handler(event, context): pass # or do something 通过我们用 Lambda 调…

使用Hutool读取大Excel

改造后可以在数秒内读取百万级别量的excel数据&#xff0c;注意&#xff1a;csv不行&#xff0c;先转成excel再读取 public class MyBigExcelUtil {/*** 储存表头*/private static List<Object> headLine;/*** 储存返回数据*/private static List<Map<String, Obj…

Jtti:排查和解决服务器死机问题的步骤

服务器死机是一个严重的问题&#xff0c;可能导致业务中断和数据丢失。要排查和解决服务器死机问题&#xff0c;需要系统地检查以下几个方面&#xff1a; 一、硬件问题 电源供应&#xff1a;检查电源是否稳定&#xff0c;是否有电源故障或电源线松动的问题。查看不间断电源(UPS…

AMD(Xilinx) FPGA配置Flash大小选择

目录 1 FPGA配置Flash大小的决定因素2 为什么选择的Flash容量大小为最小保证能够完成整个FPGA的配置呢&#xff1f; 1 FPGA配置Flash大小的决定因素 在进行FPGA硬件设计时&#xff0c;选择合适的配置Flash是我们进行硬件设计必须考虑的&#xff0c;那么配置Flash大小的选择由什…

51单片机从入门到精通:理论与实践指南(一)

单片机在智能控制领域的应用已非常普遍&#xff0c;发展也很迅猛&#xff0c;学习和使用单片机的人员越来越多。虽然新型微控制器在不断推出&#xff0c;但51单片机价格低廉、易学易用、性能成熟&#xff0c;在家电和工业控制中有一定的应用&#xff0c;而且学好了51单片机&…