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

Canvas鼠标画线

鼠标按下开始画线,鼠标移动根据鼠标的轨迹去画,鼠标抬起停止画线
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Canvas Drawing</title><style>canvas {border: 1px solid #000;}</style>
</head><body><canvas id="myCanvas" width="500" height="500"></canvas><script>document.addEventListener('DOMContentLoaded', function () {const canvas = document.getElementById('myCanvas')const ctx = canvas.getContext('2d')let isDrawing = falsefunction startDrawing (e) {isDrawing = truedraw(e)}function stopDrawing () {isDrawing = falsectx.beginPath() // Reset the path for the next draw}function draw (e) {if (!isDrawing) returnctx.lineWidth = 5ctx.lineCap = 'round'ctx.strokeStyle = '#000'ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop)ctx.stroke()ctx.beginPath()ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop)}canvas.addEventListener('mousedown', startDrawing)canvas.addEventListener('mousemove', draw)canvas.addEventListener('mouseup', stopDrawing)canvas.addEventListener('mouseout', stopDrawing)});</script>
</body></html>

效果图
在这里插入图片描述

和上面效果相同,只是轨迹线换成了直线(鼠标移动始终显示两点直线,只能绘制有一条线)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Canvas Drawing</title><style>canvas {border: 1px solid #000;}</style>
</head><body><canvas id="myCanvas" width="500" height="500"></canvas><script>document.addEventListener('DOMContentLoaded', function () {const canvas = document.getElementById('myCanvas')const ctx = canvas.getContext('2d')let isDrawing = falselet startX, startYfunction startDrawing (e) {isDrawing = truestartX = e.clientX - canvas.offsetLeftstartY = e.clientY - canvas.offsetTop}function drawLine (e) {if (!isDrawing) returnconst endX = e.clientX - canvas.offsetLeftconst endY = e.clientY - canvas.offsetTopctx.clearRect(0, 0, canvas.width, canvas.height) // Clear the canvasctx.lineWidth = 5ctx.lineCap = 'round'ctx.strokeStyle = '#000'ctx.beginPath()ctx.moveTo(startX, startY)ctx.lineTo(endX, endY)ctx.stroke()}function stopDrawing () {isDrawing = false}canvas.addEventListener('mousedown', startDrawing)canvas.addEventListener('mousemove', drawLine)canvas.addEventListener('mouseup', stopDrawing)canvas.addEventListener('mouseout', stopDrawing)});</script>
</body></html>

效果图
在这里插入图片描述

效果图和上面相同(可以画多条直线,点击确定按钮会保留最后画的一条线)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Canvas Drawing</title><style>canvas {border: 1px solid #000;margin-bottom: 20px;}button {display: block;margin-top: 10px;}</style>
</head><body><canvas id="myCanvas" width="500" height="500"></canvas><button id="confirmButton">Confirm</button><script>document.addEventListener('DOMContentLoaded', function () {const canvas = document.getElementById('myCanvas')const ctx = canvas.getContext('2d')let lines = [] // 画线的数组let lines2 = [] // 点击确定后存放的按钮let num = 0let isDrawing = falselet startPoint = {}let endPoint = {}function startDrawing (e) {isDrawing = truestartPoint = {x: e.clientX - canvas.offsetLeft,y: e.clientY - canvas.offsetTop}}function drawLine (e) {if (!isDrawing) returnendPoint = {x: e.clientX - canvas.offsetLeft,y: e.clientY - canvas.offsetTop}ctx.clearRect(0, 0, canvas.width, canvas.height) // Clear the canvasctx.lineWidth = 5ctx.lineCap = 'round'ctx.strokeStyle = '#000'lines.forEach(line => {ctx.beginPath()ctx.moveTo(line.start.x, line.start.y)ctx.lineTo(line.end.x, line.end.y)ctx.stroke()})ctx.beginPath()ctx.moveTo(startPoint.x, startPoint.y)ctx.lineTo(endPoint.x, endPoint.y)ctx.stroke()}function stopDrawing () {if (isDrawing) {isDrawing = falselines.push({ start: { ...startPoint }, end: { ...endPoint } })}}function confirmLines () {lines2.push(lines[lines.length - 1])lines = [...lines2]ctx.clearRect(0, 0, canvas.width, canvas.height) // Clear the canvasif (lines2.length > 0) {lines2.forEach((item) => {const lastLine = itemctx.beginPath()ctx.moveTo(lastLine.start.x, lastLine.start.y)ctx.lineTo(lastLine.end.x, lastLine.end.y)ctx.stroke()})}}canvas.addEventListener('mousedown', startDrawing)canvas.addEventListener('mousemove', drawLine)canvas.addEventListener('mouseup', stopDrawing)canvas.addEventListener('mouseout', stopDrawing)const confirmButton = document.getElementById('confirmButton')confirmButton.addEventListener('click', confirmLines)});</script>
</body></html>

相关文章:

Canvas鼠标画线

鼠标按下开始画线,鼠标移动根据鼠标的轨迹去画,鼠标抬起停止画线 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…...

Docker 安装部署 Sentinel Dashboard

1、下载 jar 包 官方 jar 包下载地址&#xff1a;https://github.com/alibaba/Sentinel/releases 或者点击 链接 直接跳转到下载页 进入链接下载你需要的版本 下载完毕&#xff08;我这里统一放在一个sentinel目录内&#xff09; 2、编写 Dockerfile 文件&#xff08;这里我不…...

第21章网络通信

Internet 提供了大量有用的信息&#xff0c;很少有人能在接触过Internet后拒绝它的诱惑。计算机网络实现了多台计算机间的互联&#xff0c;使得它们彼此之间能够进行数据交流。网络应用程序就是在已连接的不同计算机上运行的程序&#xff0c;这些程序借助于网络协议&#xff0c…...

一、运行时数据区域

根据 《Java 虚拟机规范》的规定&#xff0c;Java 虚拟机所管理的内存将会包括以下截个运行时数据区域&#xff0c;如图所示。 1、程序计数器 程序计数器是一块较小的内存空间&#xff0c;它可以看做是当前线程所执行的字节码的行号指示器。在 Java 虚拟机的概念模型里&#x…...

OCR原理解析

目录 1.概述 2.应用场景 3.发展历史 4.基于传统算法的OCR技术原理 4.1 图像预处理 4.1.1 灰度化 4.1.2 二值化 4.1.3 去噪 4.1.4 倾斜检测与校正 4.1.4.2 轮廓矫正 4.1.5 透视矫正 4.2 版面分析 4.2.1 连通域检测文本 4.2.2 MSER检测文本 4.3 字符切割 4.3.1 连…...

使用com组件编辑word

一个普通的窗体应用&#xff0c;6个button using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; u…...

国产Euler(欧拉)系统安装docker

国产的真™难用呀 生态又差还不开源 血泪经验 解压Docker安装包。 tar zxf docker-19.03.10.tgz 将解压后目录中的文件移动到“/usr/bin”下。 cp docker/* /usr/bin配置docker.service文件。 编辑docker.service文件。 vim /usr/lib/systemd/system/docker.service添加以…...

Linux 进程控制

文章目录 进程创建进程终止进程结果wait函数waitpid函数status参数 进程替换进程替换原理进程替换函数 补充/拓展 进程创建 fork函数 #include <unistd.h>pid_t fork(void);函数返回值&#xff1a; 在父进程中&#xff0c;fork函数返回子进程的进程ID&#xff08;PID&…...

[ Linux Audio 篇 ] 音频开发入门基础知识

在短视频兴起的背景下&#xff0c;音视频开发越来越受到重视。接下来将为大家介绍音频开发者入门知识&#xff0c;帮助读者快速了解这个领域。 轻柔的音乐、程序员有节奏感的键盘声、嗡嗡的发动机、刺耳的手提钻……这些声音是如何产生的呢&#xff1f;又是如何传到我们耳中的…...

关于高校电子邮件系统开通双因素认证的经验分享-以清华大学为例

清华大学信息化技术中心 马云龙 作者简介: 马云龙,男,清华大学信息化技术中心高级工程师;Coremail管理员社区大咖嘉宾 深耕高校计算机网络/信息化/网络安全岗位20年,对大规模计算机网络及信息系统规划,开发/建设,运维有深刻体会。 目前,越来越多的高校/企业/政府机关…...

「Swift」类淘宝商品瀑布流展示

前言&#xff1a;需要做一个类似于淘宝商品页面的瀑布流展示 结构分析&#xff1a; ps&#xff1a;图片来源 思路分析&#xff1a; 该瀑布流主要还是基于UICollectionView进行展示&#xff0c;只是在cell展示的UICollectionViewFlowLayout需要进行相应调整和自定义&#xff…...

道可云会展元宇宙平台全新升级,打造3D沉浸式展会新模式

随着VR虚拟现实、人工智能、虚拟数字人等元宇宙技术的快速发展&#xff0c;各个行业正试图通过元宇宙技术寻求新的发展突破口&#xff0c;会展行业也不例外。会展作为经贸领域的重要产业形态&#xff0c;越来越多的企业和组织开始寻求通过元宇宙技术为展会赋能&#xff0c;以满…...

Ant Design Pro初始化报错

今天按照官网步骤初始化项目&#xff0c;第一次报错 fatal: unable to access https://github.com/ant-design/ant-design-pro/: SSL certificate problem: unable to get local issuer certificate 致命&#xff1a;无法访问https://github.com/ant-design/ant-design-pro/&…...

第16届中国R会议暨2023X-AGI大会开幕,和鲸科技分享ModelOps在数据科学平台中的实践与应用

11月25日&#xff0c;第 16 届中国 R 会议暨 2023 X-AGI 大会在在中国人民大学逸夫会堂拉开帷幕&#xff0c;本次会议由中国人民大学统计学院、中国人民大学应用统计科学研究中心、统计之都、原灵科技和中国商业统计学会人工智能分会&#xff08;筹&#xff09;主办&#xff0c…...

❀My学习Linux命令小记录(12)❀

目录 ❀My学习Linux命令小记录&#xff08;12&#xff09;❀ 46.arp指令 47.tcpdump指令 48.chmod指令 49.chown指令 50.bash调用脚本指令 shell介绍 shell脚本的组成部分 脚本执行方式 检查脚本语法 bash之变量 变量的种类&#xff1a;根据生效的范围不同来区分 …...

MySQL学习day05

DCL&#xff08;Data Control Language&#xff09;数据控制语言学习 作用&#xff1a;用来创建数据库用户、控制数据库的访问权限 1&#xff09;查询用户&#xff1a; use mysql; select * from user; 2&#xff09;创建用户&#xff1a; create user 用户名主机名 identifi…...

JAVA面试题7

1.Java中的ClassLoader是什么&#xff1f; 它有什么作用&#xff1f; 答案&#xff1a;ClassLoader是一种加载Java类文件的机制&#xff0c;可以从不同的来源加载类文件&#xff0c;如本地文件系统、网络等。ClassLoader可以帮助实现模块化开发和动态加载类等功能。 2.什么是J…...

好用免费的AI换脸5个工具

在当今社会的发展中&#xff0c;人工智能&#xff08;Artificial Intelligence, AI&#xff09;扮演着关键的角色&#xff0c;其应用领域不断扩展。作为AI的一个分支&#xff0c;换脸技术近年来备受欢迎。这项技术使得将一个人的面部特征迁移到另一个人的照片或视频成为可能。除…...

【Linux】公网远程访问AMH服务器管理面板

目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板&#xff0c;它提供了一系列的功能&#xff0c;包括网站管理、FTP 管理、数据库管理、DNS 管理、…...

随笔-这都是命吗

我与鹏哥、小付有个小群&#xff0c;前几天&#xff0c;鹏哥在群里发了一个图&#xff0c;是他那个城市准备扶持的高新产业&#xff0c;有元宇宙、量子信息、生物制药、人工智能什么的。 先前的时候鹏哥给我说过&#xff0c;当地准备了六百多亩地&#xff0c;准备发展高新产业…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...