当前位置: 首页 > news >正文

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

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

实现效果

请添加图片描述

代码实现

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()

总结

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

相关文章:

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

画一个矩形&#xff0c;可以选中高亮&#xff0c;删除自己效果的实现&#xff0c;后期会丰富下细节&#xff0c;拖动及拖动调整矩形大小 实现效果 代码实现 class Draw {constructor() {this.x 0this.y 0this.disX 0this.disY 0this.startX 0this.startY 0this.mouseDo…...

【git实践】分享一个适用于敏捷开发的分支管理策略

文章目录 1. 背景2. 分支管理实践2.1. 敏捷开发中分支管理面临的问题2.2. 分支管理策略2.3. 还需要注意的一些问题 3.总结 1. 背景 在实际的开发工作中&#xff0c;我们往往会面临多任务并行研发&#xff0c;多个环境管理的情况&#xff0c;这种情况下&#xff0c;一个合适的分…...

Redis与MySQL如何保证数据一致性

Redis与MySQL如何保证数据一致性 简单来说 该场景主要发生在读写并发进行时&#xff0c;才会发生数据不一致。 主要流程就是要么先操作缓存&#xff0c;要么先操作Redis&#xff0c;操作也分修改和删除。 一般修改要执行一系列业务代码&#xff0c;所以一般直接删除成本较低…...

基于微信小程序的教室预约系统+LW示例参考

1.项目介绍 功能模块&#xff1a;管理员&#xff08;学生管理、教师管理、申请管理、设备管理、报修管理等&#xff09;、普通用户/学生&#xff08;注册登录、申请预约、退订、报修等&#xff09;技术选型&#xff1a;SSM、JSP、uniapp等测试环境&#xff1a;idea2024&#x…...

Linux 安装 Git 服务器

一、安装 Git 1. 在 CentOS/RHEL 中使用以下命令&#xff1a; sudo yum update -y # 或者 sudo dnf update -y (在较新的系统中) sudo yum install git -y验证安装&#xff1a;git --version 2. 配置 Git 用户 git config --global user.name "Your Name" git co…...

总结:Yarn资源管理

一、介绍 本文梳理下Yarn的资源分配计算逻辑。 二、配置 - 资源限制 1、配置NodeManager可分配的资源池的总量 <property><name>yarn.nodemanager.resource.memory-mb</name><value>4096</value> </property> 作用对象:节点管理器(No…...

Python学习34天

import random class Game: peo0 rob0 # # def __init__(self,peo,rob): # self.peopeo # self.robrob def Play(self): """ 石头剪刀布游戏&#xff0c;0代表石头&#xff0c;1代见到&#xff0c;2代表石头 …...

深入浅出 WebSocket:构建实时数据大屏的高级实践

简介 请参考下方&#xff0c;学习入门操作 基于 Flask 和 Socket.IO 的 WebSocket 实时数据更新实现 在当今数字化时代&#xff0c;实时性是衡量互联网应用的重要指标之一。无论是股票交易、在线游戏&#xff0c;还是实时监控大屏&#xff0c;WebSocket 已成为实现高效、双向…...

三开关VUE组件

一、使用效果 <template><QqThreeSwitch v-model"value" /><!-- <SqThreeSwitch v-model"value" :options"[test1, test2, test3]"><template #left-action><div style"display: flex"><IconMoon…...

SpringCloud+SpringCloudAlibaba学习笔记

SpringCloud 服务注册中心 eureka ap 高可用 分布式容错 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency><groupId…...

牛客小白月赛105(A~E)

文章目录 A lz的吃饭问题思路code B lz的数字问题思路code C lz的蛋挞问题思路code D lz的染色问题思路code E lz的括号问题思路code 总结 牛客小白月赛105 A lz的吃饭问题 思路 签到题&#xff0c;比较大小即可 code void solve(){int a,b,c,d;cin >> a >> b…...

OSPF协议整理

OSPF&#xff08;Open Shortest Path First&#xff09;即开放式最短路径优先协议&#xff0c;是一种广泛应用于大型网络中的链路状态路由协议。 OSPF 的基本概念 OSPF 是基于链路状态算法的内部网关协议&#xff08;IGP&#xff09;&#xff0c;用于在一个自治系统&#xff…...

Java中的多线程

文章目录 Java中的多线程一、引言二、多线程的创建和启动1、继承Thread类2、实现Runnable接口 三、线程的常用方法1、currentThread()和getName()2、sleep()和yield()3、join() 四、线程优先级五、使用示例六、总结 Java中的多线程 一、引言 在Java中&#xff0c;多线程编程是…...

什么是聚簇索引、非聚簇索引、回表查询

其实聚集索引也叫聚簇索引&#xff0c;二级索引也叫非聚簇索引&#xff0c;大家不要认为这是不同的两个知识点。 定义 先看一下数据库的索引介绍。 聚簇索引 1. 如果存在主键&#xff08;一般都存在&#xff09;&#xff0c;主键索引就是聚簇索引。 2. 如果不存在&#xff0c;…...

探索 Spring 框架核心组件:构建强大 Java 应用的基石

Spring框架作为Java企业级开发的首选框架之一&#xff0c;其强大的功能和灵活的架构深受开发者喜爱。Spring框架的核心组件共同构建了一个高效、可扩展的应用程序开发平台。本文将深入探讨Spring框架的核心组件&#xff0c;揭示它们如何在Spring框架中发挥关键作用。 一、Bean…...

Android 13 Aosp 默认允许应用动态权限

图库 frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java 修改 public void grantDefaultPermissions(int userId) {DelayingPackageManagerCache pm new DelayingPackageManagerCache();grantPermissionsToSysCompon…...

【C++知识总结1】c++第一篇,简单了解一下命名空间是什么

一、C的由来 C语言是一种结构化和模块化的编程语言&#xff0c;它对于处理较小规模的程序非常适用。然而&#xff0c;当面临需要高度抽象和建模的复杂问题&#xff0c;以及规模较大的程序时&#xff0c;C语言就显得不那么合适了。为了应对这种挑战&#xff0c;并在解决软件危机…...

从0开始深度学习(32)——循环神经网络的从零开始实现

本章将从零开始&#xff0c;基于循环神经网络实现字符级语言模型&#xff08;不是单词级&#xff09; 首先我们把从0开始深度学习&#xff08;30&#xff09;——语言模型和数据集中的load_corpus_time_machine()函数进行引用&#xff0c;用于导入数据&#xff1a; train_iter…...

GitLab使用操作v1.0

1.前置条件 Gitlab 项目地址&#xff1a;http://******/req Gitlab账户信息&#xff1a;例如 001/******自己的分支名称&#xff1a;例如 001-master&#xff08;注&#xff1a;master只有项目创建者有权限更新&#xff0c;我们只能更新自己分支&#xff0c;然后创建合并请求&…...

cuda conda yolov11 环境搭建

优雅的 yolo v11 标注工具 AutoLabel Conda环境直接识别训练 nvidia-smi 检查CUDA版本 下载nvidia cudnn对应的版本 将cuDNN压缩包内对应的文件复制到本地bin、include、lib的文件夹中 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6 miniConda快速开始-安装 执行…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...