canvas跟随鼠标移动画带透明度的线

提示:canvas画线

文章目录

  • 前言
  • 一、带透明度的线
  • 二、试错,只有lineTo的时候画,只有最后地方是透明度的
  • 三、试错,只存上一次的点,线会出现断裂的情况
  • 总结


前言

一、带透明度的线

test.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>canvas跟随鼠标移动画透明线</title><style>div,canvas,img{user-select: none;}.my_canvas,.bg_img{position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);}.bg_img{width: 674px;height: 495px;background: #ddd;}</style>
</head>
<body><div class="bg_img"></div><canvas id="myCanvasBot" class="my_canvas" width="674" height="495"></canvas><canvas id="myCanvasTop" class="my_canvas" width="674" height="495"></canvas><script>const canvasWidth = 674;const canvasHeight = 495;//底层canvasconst botCan = document.getElementById('myCanvasBot');//顶层canvasconst topCan = document.getElementById('myCanvasTop');//底层画布const botCtx = botCan.getContext('2d');//顶层画布const topCtx = topCan.getContext('2d');//鼠标是否按下  是否移动  是否画图了let isDown = false,isMove = false,isDrawed = false;//需要画图的轨迹let drawPoints = [];//起始点x,ylet startPoint = {x:0,y:0};//图片历史let imgHistory = [];//icon历史let partHistory = [];//鼠标按下const mousedown = (e)=>{isDown = true;let x = (e||window.event).offsetX;let y = (e||window.event).offsetY;startPoint = {x,y}// drawPoints.push({x,y});drawPoints.push([{x,y}]);topCtx.beginPath();topCtx.moveTo(x,y);}//鼠标移动const mousemove = (e)=>{if(isDown){isMove = true;drawCurve(e);}}//鼠标抬起const mouseup = (e)=>{if(isDown&&isMove){isDown = false;isMove = false;drawPoints = [];//把topCan画布生成图片let img = new Image();img.src = topCan.toDataURL('image/png');img.onload = ()=>{partHistory.push(img);//添加到botCtx画布botCtx.drawImage(img,0,0);let historyImg = new Image();historyImg = botCan.toDataURL('image/png');historyImg.onload = ()=>{//添加到历史记录imgHistory.push(historyImg);}//清除topCtx画布topCtx.clearRect(0,0,canvasWidth,canvasHeight);}}}//画带透明度涂鸦const drawCurve = (e)=>{let x = (e||window.event).offsetX;let y = (e||window.event).offsetY;drawPoints.push({x,y});topCtx.strokeStyle = 'rgba(255,0,0,0.2)';topCtx.lineWidth = 10;//清空当前画布内容topCtx.clearRect(0,0,canvasWidth,canvasHeight);//必须每次都beginPath  不然会卡topCtx.beginPath();topCtx.moveTo(drawPoints[0].x,drawPoints[0].y);for(let i=1;i<drawPoints.length;i++){topCtx.lineTo(drawPoints[i].x,drawPoints[i].y);}topCtx.stroke();}//canvas添加鼠标事件topCan.addEventListener('mousedown',mousedown);topCan.addEventListener('mousemove',mousemove);topCan.addEventListener('mouseup',mouseup);//全局添加鼠标抬起事件document.addEventListener('mouseup',()=>{isDown = false;isMove = false;isDrawed = false;});</script>
</body>
</html>

在这里插入图片描述

二、试错,只有lineTo的时候画,只有最后地方是透明度的

test.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>canvas跟随鼠标移动画透明线</title><style>div,canvas,img{user-select: none;}.my_canvas,.bg_img{position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);}.bg_img{width: 674px;height: 495px;background: #ddd;}</style>
</head>
<body><div class="bg_img"></div><canvas id="myCanvasBot" class="my_canvas" width="674" height="495"></canvas><canvas id="myCanvasTop" class="my_canvas" width="674" height="495"></canvas><script>const canvasWidth = 674;const canvasHeight = 495;//底层canvasconst botCan = document.getElementById('myCanvasBot');//顶层canvasconst topCan = document.getElementById('myCanvasTop');//底层画布const botCtx = botCan.getContext('2d');//顶层画布const topCtx = topCan.getContext('2d');//鼠标是否按下  是否移动  是否画图了let isDown = false,isMove = false,isDrawed = false;//需要画图的轨迹let drawPoints = [];//起始点x,ylet startPoint = {x:0,y:0};//图片历史let imgHistory = [];//icon历史let partHistory = [];//鼠标按下const mousedown = (e)=>{isDown = true;let x = (e||window.event).offsetX;let y = (e||window.event).offsetY;startPoint = {x,y}// drawPoints.push({x,y});drawPoints.push([{x,y}]);topCtx.beginPath();topCtx.moveTo(x,y);}//鼠标移动const mousemove = (e)=>{if(isDown){isMove = true;drawCurve(e);}}//鼠标抬起const mouseup = (e)=>{if(isDown&&isMove){isDown = false;isMove = false;drawPoints = [];//把topCan画布生成图片let img = new Image();img.src = topCan.toDataURL('image/png');img.onload = ()=>{partHistory.push(img);//添加到botCtx画布botCtx.drawImage(img,0,0);let historyImg = new Image();historyImg = botCan.toDataURL('image/png');historyImg.onload = ()=>{//添加到历史记录imgHistory.push(historyImg);}//清除topCtx画布topCtx.clearRect(0,0,canvasWidth,canvasHeight);}}}//画带透明度涂鸦const drawCurve = (e)=>{let x = (e||window.event).offsetX;let y = (e||window.event).offsetY;drawPoints.push({x,y});topCtx.strokeStyle = 'rgba(255,0,0,0.2)';topCtx.lineWidth = 10;//清空当前画布内容// topCtx.clearRect(0,0,canvasWidth,canvasHeight);//必须每次都beginPath  不然会卡// topCtx.beginPath();// topCtx.moveTo(drawPoints[0].x,drawPoints[0].y);// for(let i=1;i<drawPoints.length;i++){//     topCtx.lineTo(drawPoints[i].x,drawPoints[i].y);// }topCtx.lineTo(x,y);topCtx.stroke();}//canvas添加鼠标事件topCan.addEventListener('mousedown',mousedown);topCan.addEventListener('mousemove',mousemove);topCan.addEventListener('mouseup',mouseup);//全局添加鼠标抬起事件document.addEventListener('mouseup',()=>{isDown = false;isMove = false;isDrawed = false;});</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跟随鼠标移动画透明线</title><style>div,canvas,img{user-select: none;}.my_canvas,.bg_img{position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);}.bg_img{width: 674px;height: 495px;background: #ddd;}</style>
</head>
<body><div class="bg_img"></div><canvas id="myCanvasBot" class="my_canvas" width="674" height="495"></canvas><canvas id="myCanvasTop" class="my_canvas" width="674" height="495"></canvas><script>const canvasWidth = 674;const canvasHeight = 495;//底层canvasconst botCan = document.getElementById('myCanvasBot');//顶层canvasconst topCan = document.getElementById('myCanvasTop');//底层画布const botCtx = botCan.getContext('2d');//顶层画布const topCtx = topCan.getContext('2d');//鼠标是否按下  是否移动  是否画图了let isDown = false,isMove = false,isDrawed = false;//需要画图的轨迹let drawPoints = [];//起始点x,ylet startPoint = {x:0,y:0};//上一次的点let lastPoint = {x:0,y:0};//图片历史let imgHistory = [];//icon历史let partHistory = [];//鼠标按下const mousedown = (e)=>{isDown = true;let x = (e||window.event).offsetX;let y = (e||window.event).offsetY;startPoint = {x,y}// drawPoints.push({x,y});drawPoints.push([{x,y}]);lastPoint = {x,y}topCtx.beginPath();topCtx.moveTo(x,y);}//鼠标移动const mousemove = (e)=>{if(isDown){isMove = true;drawCurve(e);}}//鼠标抬起const mouseup = (e)=>{if(isDown&&isMove){isDown = false;isMove = false;drawPoints = [];//把topCan画布生成图片let img = new Image();img.src = topCan.toDataURL('image/png');img.onload = ()=>{partHistory.push(img);//添加到botCtx画布botCtx.drawImage(img,0,0);let historyImg = new Image();historyImg = botCan.toDataURL('image/png');historyImg.onload = ()=>{//添加到历史记录imgHistory.push(historyImg);}//清除topCtx画布topCtx.clearRect(0,0,canvasWidth,canvasHeight);}}}//画带透明度涂鸦const drawCurve = (e)=>{let x = (e||window.event).offsetX;let y = (e||window.event).offsetY;drawPoints.push({x,y});topCtx.strokeStyle = 'rgba(255,0,0,0.2)';topCtx.lineWidth = 10;topCtx.beginPath();topCtx.moveTo(lastPoint.x,lastPoint.y);topCtx.lineTo(x,y);topCtx.stroke();lastPoint = {x,y};}//canvas添加鼠标事件topCan.addEventListener('mousedown',mousedown);topCan.addEventListener('mousemove',mousemove);topCan.addEventListener('mouseup',mouseup);//全局添加鼠标抬起事件document.addEventListener('mouseup',()=>{isDown = false;isMove = false;isDrawed = false;});</script>
</body>
</html>

在这里插入图片描述

总结

踩坑路漫漫长@~@

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/763456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux:执行命令的命令eval与Bash解析命令的方式

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 eval命令用于接收参数&#xff0c;并将这些参数作为一行命令执行&#xff0c;这也许会使人困惑&#xff0c;为什么我不能直接执行命令而需要使用eval命令间接执行呢&…

MySQL数据库事务介绍

前言 在MySQL数据库中&#xff0c;事务&#xff08;Transaction&#xff09;是指一组SQL语句的执行序列&#xff0c;这些SQL语句要么全部执行成功&#xff0c;要么全部执行失败&#xff0c;保证数据库的一致性和完整性&#xff1b;用于操作量大、复杂度高的数据。 目录 一、…

Python之Web开发中级教程----Django站点管理

Python之Web开发中级教程----Django站点管理 网站的开发分为两部分&#xff1a;内容发布和公共访问 内容发布是由网站的管理员负责查看、添加、修改、删除数据 Django能够根据定义的模型类自动地生成管理模块 使用Django的管理模块, 需要按照如下步骤操作 : 1.管理界面本地…

Deep Graph Representation Learning and Optimization for Influence Maximization

Abstract 影响力最大化&#xff08;IM&#xff09;被表述为从社交网络中选择一组初始用户&#xff0c;以最大化受影响用户的预期数量。研究人员在设计各种传统方法方面取得了巨大进展&#xff0c;其理论设计和性能增益已接近极限。在过去的几年里&#xff0c;基于学习的IM方法的…

企业如何利用数字工厂管理系统打造自动化产线

随着信息技术的飞速发展&#xff0c;数字化转型已成为企业提升生产效率、降低成本、优化管理的重要手段。数字工厂管理系统作为数字化转型的核心组成部分&#xff0c;其在打造自动化产线方面的作用日益凸显。本文将探讨企业如何利用数字工厂管理系统打造自动化产线&#xff0c;…

【QED】斐波那契游戏

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 总结 题目 题目链接&#x1f517; 斐波那契数列指的是这样一个数列&#xff1a;1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;8&#xff0c;13&#xff0c;21&#xff0c;34&#xff0c;55&#x…

边缘自动隐藏窗体,透明度切换,同步父窗体标签切换winform

一、实现功能 默认的标签栏(superTabControl) 可以设置隐藏,即可实现全屏最大化。通过列表切换打开的标签页。用于定制B/S模式系统显示更个性,自定义样式,简介 安全 兼容性好。 二、主要代码 private void Time_Tick(object sender, EventArgs e) {获取主屏

亚马逊AWS展示高效纠错的全新量子比特!

亚马逊网络服务公司&#xff08;AWS&#xff09;在量子计算的纠错技术领域取得了显著成就&#xff0c;极大地简化了量子系统的复杂性和资源需求。他们的研究人员通过采用“双轨擦除”量子比特&#xff08;dual-rail erasure qubit&#xff09;技术&#xff0c;有效地克服了量子…

推荐一种Bean注入方式——开发经验

我们都知道三种Bean注入的方式分别是属性注入&#xff0c;setter方法注入&#xff0c;构造器注入。这三种Bean注入的方式各有优缺点&#xff0c;但是相对来说更推荐使用构造器注入的方式。 1、构造器注入的优缺点 优点&#xff1a; 1、可以注入不可变对象 因为构造方法注入是…

算法-图的强连通分量,图的最小生成树

1.图的强连通分量 (1). 定义 图的强连通分量是图论中的一个重要概念&#xff0c;主要在有向图中进行讨论。具体来说&#xff0c;如果在一个有向图G中&#xff0c;任意两个顶点vi和vj&#xff08;其中vi大于vj&#xff09;之间都存在一条从vi到vj的有向路径&#xff0c;同时也存…

分享基于PDF.js的pdf阅读器代码

一、前言 有时候开发PC端web页面的时候会遇到PDF预览、下载等功能&#xff0c;为了兼容浏览器&#xff0c;需要找一款前端插件进行开发。比较好的PDF插件&#xff0c;就是mozilla的pdf.js&#xff08;注意是mozilla&#xff0c;如果你百度遇到需要收费的&#xff0c;那应该是下…

python矢量算法-三角形变化寻找对应点

1.算法需求描述 现有随机生成的两个三角形A与B&#xff0c;在三角形A中存在Pa&#xff0c;使用算法计算出三角形B中对应的点Pb 2.python代码 import numpy as np # 计算三角形A的面积 def area_triangle(vertices): return 0.5 * np.abs(np.dot(vertices[0] - vertices[…

品时尚精酿啤酒,探秘时尚背后的故事

在琳琅满目的啤酒市场中&#xff0c;Fendi Club啤酒以其时尚的风格和品质&#xff0c;成为了引人注目的焦点。这款啤酒不仅是一种味觉的享受&#xff0c;更是一种时尚与品味的象征。接下来&#xff0c;让我们一起探索Fendi Club啤酒背后的故事。 一、Fendi Club啤酒的特色 Fen…

师徒互电,眼冒金星,采集系统变电刺激系统!

原文来自微信公众号&#xff1a;工程师看海&#xff0c;很高兴分享我的原创文章&#xff0c;喜欢和支持我的工程师&#xff0c;一定记得给我点赞、收藏、分享哟。 加微信[chunhou0820]与作者进群沟通交流 电的我眼冒金星&#xff0c;以为自己被三体召唤&#xff0c;整个世界为我…

什么是浏览器指纹识别?Maskfog指纹浏览器有用吗?

浏览器指纹识别是好是坏&#xff1f;这现在确实是一个有争议的话题。83%的消费者经常或偶尔会根据浏览历史记录看到广告。其实这就是利用了浏览器指纹技术。 如果您想了解浏览器指纹识别是什么&#xff0c;那就看下去&#xff01; 一、什么是浏览器指纹识别 浏览器指纹是指无…

鸿蒙一次开发,多端部署(四)工程管理

DevEco Studio的基本使用&#xff0c;请参考DevEco Studio使用指南。本章主要介绍如何使用DevEco Studio进行多设备应用开发。 说明&#xff1a; 本章的内容基于DevEco Studio 3.1.1 Release版本进行介绍&#xff0c;如您使用DevEco Studio其它版本&#xff0c;可能存在文档与产…

《妈妈是什么》笔记(一)孩子都有被关注的需求

简介 作者渡渡鸟&#xff0c; 其本名韩谨&#xff0c;微博原创育儿理念、故事、分享妈妈经。毕业于中国社科院哲学系&#xff0c;有过八年记者生涯。育有一儿两女&#xff0c;在中美两国生活&#xff0c;熟悉跨文化养育&#xff0c;有坚定的根文化意识。 渡渡鸟妈妈能够基于孩…

docker基础超详细教程,一篇文章帮助你从零开始学习docker,从入门到实战

docker 概述 docker 官网&#xff1a;http://www.docker.com 官网文档&#xff1a; https://docs.docker.com/get-docker/ Docker Hub官网&#xff1a;https://hub.docker.com &#xff08;仓库&#xff09; 什么是 docker docker 是一个开源的容器化平台&#xff0c;可以…

Python螺旋折线蓝桥杯(来源lanqiao.cn 题目176) 时间超限

题目描述 如图所示的螺旋折线经过平面上所有整点恰好一次。 对于整点(X, Y)&#xff0c;我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。 例如dis(0, 1)3, dis(-2, -1)9 给出整点坐标(X, Y)&#xff0c;你能计算出dis(X, Y)吗&#xff1f; 输入格式 …

js【详解】typeof 运算符

typeof()表示“获取变量的数据类型”&#xff0c;返回的是小写&#xff0c;语法为&#xff1a;&#xff08;两种写法都可以&#xff09; // 写法1 typeof 变量;// 写法2 typeof(变量); typeof 这个运算符的返回结果就是变量的类型。 返回结果&#xff1a; typeof 的代码写法…