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>

总结

踩坑路漫漫长@~@

相关推荐
晨非辰20 分钟前
#C语言——学习攻略:自定义类型路线--结构体--结构体类型,结构体变量的创建和初始化,结构体内存对齐,结构体传参,结构体实现位段
c语言·开发语言·经验分享·学习·其他·学习方法·visual studio
赵英英俊44 分钟前
Python day43
开发语言·python
Warren981 小时前
公司项目用户密码加密方案推荐(兼顾安全、可靠与通用性)
java·开发语言·前端·javascript·vue.js·python·安全
·白小白1 小时前
【数据结构】——栈(Stack)的原理与实现
c语言·开发语言·数据结构
野犬寒鸦2 小时前
Java Stream API 中常用方法复习及项目实战示例
java·服务器·开发语言·数据库
提笔惊蚂蚁2 小时前
Python 高级语法
开发语言·python
q567315233 小时前
使用reqwest+select实现简单网页爬虫
开发语言·爬虫·golang·kotlin
1024小神3 小时前
vue3 + vite项目,如果在build的时候对代码加密混淆
前端·javascript
郝学胜-神的一滴3 小时前
C++中的`auto`与`std::any`:功能、区别与选择建议
开发语言·c++·程序人生·算法
轻语呢喃3 小时前
useRef :掌握 DOM 访问与持久化状态的利器
前端·javascript·react.js