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

提示:canvas画线

文章目录


前言

一、带透明度的线

test.html

c 复制代码
<!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;
        //底层canvas
        const botCan = document.getElementById('myCanvasBot');
        //顶层canvas
        const topCan = document.getElementById('myCanvasTop');
        //底层画布
        const botCtx = botCan.getContext('2d');
        //顶层画布
        const topCtx = topCan.getContext('2d');
        //鼠标是否按下  是否移动  是否画图了
        let isDown = false,isMove = false,isDrawed = false;
        //需要画图的轨迹
        let drawPoints = [];
        //起始点x,y
        let 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

c 复制代码
<!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;
        //底层canvas
        const botCan = document.getElementById('myCanvasBot');
        //顶层canvas
        const topCan = document.getElementById('myCanvasTop');
        //底层画布
        const botCtx = botCan.getContext('2d');
        //顶层画布
        const topCtx = topCan.getContext('2d');
        //鼠标是否按下  是否移动  是否画图了
        let isDown = false,isMove = false,isDrawed = false;
        //需要画图的轨迹
        let drawPoints = [];
        //起始点x,y
        let 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>

三、试错,只存上一次的点,线会出现断裂的情况

c 复制代码
<!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;
        //底层canvas
        const botCan = document.getElementById('myCanvasBot');
        //顶层canvas
        const topCan = document.getElementById('myCanvasTop');
        //底层画布
        const botCtx = botCan.getContext('2d');
        //顶层画布
        const topCtx = topCan.getContext('2d');
        //鼠标是否按下  是否移动  是否画图了
        let isDown = false,isMove = false,isDrawed = false;
        //需要画图的轨迹
        let drawPoints = [];
        //起始点x,y
        let 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>

总结

踩坑路漫漫长@~@

相关推荐
无限的鲜花5 小时前
反射(原创推荐)
java·开发语言
yongche_shi5 小时前
ragas官方文档中文版(五十)
开发语言·python·ai·ragas·如何评估和改进 rag 应用
一路向北he5 小时前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端
kyriewen6 小时前
豆包和千问同时关了智能体,我用它们搭的 3 个自动化全废了——迁移方案整理
前端·javascript·ai编程
铁皮饭盒6 小时前
用 Bun.cron 定时 7 月 7 日,为啥? 看图1
javascript
AI行业学习7 小时前
Notepad++ 官方下载 + 完整安装 + 全套优化配置(2026最新)
开发语言·人工智能·python·前端框架·html·notepad++
大圣编程7 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
upgrador8 小时前
基础知识:C++ STL构造函数的左闭右开惯例及其实现原理
开发语言·c++
之歆8 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
yoothey9 小时前
报废审批流规则引擎设计——责任链模式完整实现
linux·开发语言·bash