JavaScript

Canvas网页涂鸦板再次增强版

Nick · 4月4日 · 2020年 · 本文6562字 · 阅读17分钟818

第一版Canvas涂鸦板

  • 实现功能:在涂鸦板上鼠标按下去拖动的涂鸦效果
  • 实现思路:监听鼠标按下、移动、松开事件,将鼠标按下的值赋值给moveTo的x和y值,作为起始位置。在移动事件中,将鼠标距离可视区x和y值赋给lineTo,再进行描边。
  • 实现代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Canvas案例-网页涂鸦板</title>
    </head>
<body>
    <!--<center></center>表示将标签内所有的内容居中-->
    <center>
       <canvas id="cavsElem">
        你的浏览器不支持canvas,请升级浏览器
       </canvas>
    </center>
    <script>
        (function(){
            //获得画布
            var canvas = document.getElementById('cavsElem');
            //准备画笔(获取上下文对象)
            var context = canvas.getContext('2d');
            //设置标签的宽高和边框
            canvas.width = 900;
            canvas.height = 600;
            canvas.style.border = "1px solid #000";
            //当鼠标按下触发onmousedown事件时,定义一个函数获取鼠标起始坐标
            canvas.onmousedown = function(e) {
                var x = e.clientX - canvas.getBoundingClientRect().left;
                var y = e.clientY - canvas.getBoundingClientRect().top;
                context.beginPath();//开始规划路径
                context.moveTo(x, y);//移动起始点
                //当鼠标移动触发onmousemove事件时,定义一个函数获取绘制线条的坐标
                canvas.onmousemove = function(event) {
                    var x = event.clientX- canvas.getBoundingClientRect().left;
                    var y = event.clientY- canvas.getBoundingClientRect().top;
                    // canvas.clearRect(0, 0, 900, 600);
                    context.lineTo(x, y);//绘制线条
                    context.stroke();//绘制描边
                };
                //当鼠标按键被松开时,onmousemovet函数返回null
                canvas.onmouseup = function(event) {
                    canvas.onmousemove = null;
                };
            };
        }());
    </script>
</body>
</html>
  • 实现效果
    在这里插入图片描述

第二版Canvas涂鸦板

  • 实现功能:
    1. 可以根据颜色板选择涂鸦笔的颜色
    2. 可以选择画笔的粗细
    3. 可以对涂鸦板清屏
  • 实现思路:
    1. 颜色板用Html5的 <input type="color">,可以根据该input对象的value值获取选择的颜色码
    2. 画笔的粗细用了Html5的<input type="number">,来选择数字,然后将获取的数字值赋给画笔context.lineWidth = x; //设置线的粗细
    3. 涂鸦板清屏可以使用canvas自带的clearRect属性
      context.clearRect(0, 0, canvas.width, canvas.height); //清除矩形
  • 实现代码
<code class="language-clike line-numbers"><!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Canvas案例-网页涂鸦板</title>
</head>

<body>
    <!--<center></center>表示将标签内所有的内容居中-->
    <center>
        <canvas id="cavsElem">
            你的浏览器不支持canvas,请升级浏览器
        </canvas><br>
        选择画笔颜色:<input type="color" value="#ff0000" id="mycolor" onchange=colorChange() />   
        <input type="button" value="清除" id="clear" onclick=clearAll()>    
        选择画笔粗细:<input type="number" id="gsize" value="1" min="1" onchange=sizeChange()>
    </center>
    <script>
        //获得画布
        var canvas = document.getElementById('cavsElem');
        //准备画笔(获取上下文对象)
        var context = canvas.getContext('2d');
        //设置标签的宽高和边框
        canvas.width = 900;
        canvas.height = 600;
        context.strokeStyle = document.getElementById("mycolor").value; //设置描边颜色
        canvas.style.border = "1px solid #000";
        //当鼠标按下触发onmousedown事件时,定义一个函数获取鼠标起始坐标
        canvas.onmousedown = function (e) {
            var x = e.clientX - canvas.getBoundingClientRect().left;
            var y = e.clientY - canvas.getBoundingClientRect().top;
            context.beginPath(); //开始规划路径
            context.moveTo(x, y); //移动起始点
            //当鼠标移动触发onmousemove事件时,定义一个函数获取绘制线条的坐标
            canvas.onmousemove = function (event) {
                var x = event.clientX - canvas.getBoundingClientRect().left;
                var y = event.clientY - canvas.getBoundingClientRect().top;
                // canvas.clearRect(0, 0, 900, 600);
                context.lineTo(x, y); //绘制线条
                context.stroke(); //绘制描边
            };
            //当鼠标按键被松开时,onmousemovet函数返回null
            canvas.onmouseup = function (event) {
                canvas.onmousemove = null;
            };
        };
        /* 清除画布 */
        function clearAll() {
            //清除矩形
            context.clearRect(0, 0, 900, 600);
        }
        /* 颜色选择 */
        function colorChange() {
            var mycolor = document.getElementById("mycolor");
            var x = mycolor.value;
            // console.log('x :', x);
            context.strokeStyle = x; //设置描边颜色
        }
        /* 画笔粗细 */
        function sizeChange() {
            var mycolor = document.getElementById("gsize");
            var x = mycolor.value;
            context.lineWidth = x; //设置线的粗细
        }
    </script>
</body>
</html>
  • 实现效果
    在这里插入图片描述

第三版Canvas涂鸦板

  • 实现功能:
    1. 实现涂鸦时上一步和下一步的功能(撤回)
    2. 实现选择画布颜色的功能
    3. 实现对涂鸦的涂鸦板生成图片
  • 实现思路:
    1. 后退和前进(撤回)功能,我的想法是每画一次就将整个画布的数据push到一个数组中,按前进和后退时再将对应的数据取出来,这个可以通过getImageData和putImageData方法实现,这两个方法的使用可以到http://www.w3school.com.cn/tags/html_ref_canvas.asp中查看。
    2. 选择画布颜色功能有两种(获取颜色板的方法和第二版设置画笔颜色相同)
      • 第一种就是将颜色设置为画布的css背景颜色,但是实现生成图片的时候不会把背景颜色生成
      • 第二种就是直接在画布上画一个填充矩形,设置填充颜色,生成图片可以生成颜色
    3. 生成涂鸦图片是先将canvas画板转为base64编码,然后放在了img标签里
  • 实现代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Canvas案例-网页涂鸦板</title>
</head>

<body>
    <!--<center></center>表示将标签内所有的内容居中-->
    <center>
        <canvas id="cavsElem">
            你的浏览器不支持canvas,请升级浏览器
        </canvas><br>
        选择画布颜色:<input type="color" value="#ffffff" id="mycanvasColor"
            onchange="canvasColorChange()" />   
        选择画笔颜色:<input type="color" value="#ff0000" id="mycolor" onchange="colorChange()" />   
        <input type="button" value="清除" id="clear" onclick="clearAll()">    
        选择画笔粗细:<input type="number" id="gsize" value="1" min="1" onchange="sizeChange()">   
        <input type="button" value="上一步" onclick="prevStep()">
        <input type="button" value="下一步" onclick="nextStep()">   
        <button onClick="saveImg()">生成图片</button><br>
        <h4>下面是涂鸦生成的图片</h4>
        <img id='img' alt='请涂鸦……' />
    </center>
    <script>
        //画布数据
        var imgList = [];
        //上一步索引
        var prevIndex = 0;
        //下一步索引
        var nextIndex = 0;
        //当前索引
        var currentIndex = 0;
        //获取图片节点
        var img = document.getElementById('img');
        //获得画布
        var canvas = document.getElementById('cavsElem');
        //准备画笔(获取上下文对象)
        var context = canvas.getContext('2d');
        //设置标签的宽高和边框
        canvas.width = 900;
        canvas.height = 600;
        context.strokeStyle = document.getElementById("mycolor").value; //设置描边颜色
        canvas.style.border = "1px solid #000";
        //当鼠标按下触发onmousedown事件时,定义一个函数获取鼠标起始坐标
        canvas.onmousedown = function (e) {
            upIndex(imgList.length);
            var x = e.clientX - canvas.getBoundingClientRect().left;
            var y = e.clientY - canvas.getBoundingClientRect().top;
            context.beginPath(); //开始规划路径
            context.moveTo(x, y); //移动起始点
            //当鼠标移动触发onmousemove事件时,定义一个函数获取绘制线条的坐标
            canvas.onmousemove = function (event) {
                var x = event.clientX - canvas.getBoundingClientRect().left;
                var y = event.clientY - canvas.getBoundingClientRect().top;
                // canvas.clearRect(0, 0, 900, 600);
                context.lineTo(x, y); //绘制线条
                context.stroke(); //绘制描边
            };
            //当鼠标按键被松开时,onmousemovet函数返回null
            //注意,要用document全局监听
            canvas.onmouseup = function (event) {
                //调用保存画布数据
                pushImg();
                console.log('imgList :', imgList);
                canvas.onmousemove = null;

            };
        };


        /* 清除画布 */
        function clearAll() {
            //清除矩形
            context.clearRect(0, 0, canvas.width, canvas.height);
        }
        /* 画布颜色选择 */
        function canvasColorChange() {
            var canvasColor = document.getElementById("mycanvasColor");
            var x = canvasColor.value;
            // canvas.setAttribute('style', "background:" + x + ";z-index: -1;");   //直接设置背景颜色
            context.fillStyle = x; //设置填充颜色
            context.fillRect(0, 0, canvas.width, canvas.height);

        }
        /* 画笔颜色选择 */
        function colorChange() {
            var mycolor = document.getElementById("mycolor");
            var x = mycolor.value;
            context.strokeStyle = x; //设置描边颜色
        }
        /* 画笔粗细 */
        function sizeChange() {
            var mycolor = document.getElementById("gsize");
            var x = mycolor.value;
            context.lineWidth = x; //设置线的粗细
        }
        /* 保存画布数据 */
        function pushImg() {
            imgList.push(context.getImageData(0, 0, canvas.width, canvas.height));
        }
        /* 上一步 */
        function prevStep() {
            clearAll();
            if (prevIndex >= 0) {
                context.putImageData(imgList[prevIndex], 0, 0);
            }
            upIndex(prevIndex);

        }
        /* 下一步 */
        function nextStep() {

            console.log('nextIndex :', nextIndex);
            if (nextIndex !== imgList.length) {
                clearAll();
                context.putImageData(imgList[nextIndex], 0, 0);
            }
            upIndex(nextIndex);
        }

        /* 更新索引 */
        function upIndex(index) {
            if (index === -1) {
                prevIndex = -1;
            } else {
                prevIndex = index - 1;
            }

            if (index === imgList.length) {
                nextIndex = imgList.length;
            } else {
                nextIndex = index + 1;
            }
            currentIndex = index;
        }

        /* 生成图片 */
        function saveImg() {
            //转为base64编码
            var dataUrl = canvas.toDataURL();
            img.src = dataUrl;
        }
    </script>
</body>

</html>

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

体验涂鸦板

点击这里
http://qkongtao.cn//file/graffiti.html
喜欢的朋友点赞、评论支持一下咯! ^ _ ^

0 条回应
在线人数:1人 来访统计
说谎
林宥嘉
隐藏