实现一个canvas小画板

时间:2024-04-04 11:28:16

<canvas>是HTML5新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染。

——摘自MDN      canvas MDN

canvas有许多的API,可以插入图片,可以编写文字,可以处理视频。按照MDN给出的canvasPAI,可以将canvas学的很好,但是前端学习的精髓是用到什么学什么,如果只是停留在理论以及API上的学习的话,这样很容易忘记而且不够形象。

所以前端最好的学习方法是完成一个小作品,它要用到什么API我们就去学什么,顺带将相关的API熟悉理解。

今天我向大家分享我的一个canvas画板小作品,作品功能包含(支持PC与移动端、画笔选色,橡皮擦、清空画板、保存画布)。


1、首先在html中定义canvas标签。

<meta name="viewport" content="width=device-width, initial-scale=1.0">表示宽度等于设备宽度,简单的理解:这一行适配移动端的代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>画板</title>
</head>
<body>
<canvas id="canvas" class="cursor1" width="500" height="500"></canvas>
<script src="canvas-demo.js"></script>
</body>
</html>

js:取到html中canvas的id,并且声明canvas的内容为2d。

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');

到这里canvas的基础设置就完成了。

 

2、定义画布的宽高

我们需要设置画布的宽高,但是在html中的canvas标签设置是不够的,因为它的宽高只能定死不能随着视口的改变而变化。

另外,用css的vw,vh长度单位来定义canvas的宽高看起来是可以的,但是它会像img图片一样拉伸变形,具体你试试就知道了。

所以这里我们要用到js的方法。

wh()
//    canvas与屏幕宽高一致
function wh() {
    let pageWidth = document.documentElement.clientWidth;
    let pageHeight = document.documentElement.clientHeight;
    canvas.width = pageWidth;
    canvas.height = pageHeight;
}

在进入页面时执行wh( )函数,获取设备的宽高,然后将值赋给canvas中的宽高,使画布与设备宽高一致。

 

3、特性检测

通过检测是否有document.body.ontouchstart这个API来确定是否支持触屏设备,如果支持就走触屏设备的逻辑,如果支持则走非触屏设备的逻辑。

/特性检测
if (document.body.ontouchstart !== undefined) {
//触屏设备
}else{
//非触屏设备
}

 

4、鼠标点击事件,鼠标滑动事件,鼠标松开事件

现在要准备开始画画了,在画画之前我们要了解一下在canvas画一笔的具体步骤(以PC端举例):

  1. 点击鼠标
  2. 滑动鼠标
  3. 松开鼠标

一笔完成

所以我们要监听上面三点的鼠标事件,然后拿到其x,y轴对应视口的坐标点。

当鼠标点击时用一个变量记录下该坐标点(x1),鼠标开始滑动时记录滑动到的第一坐标点(x2),这样我们就有了2个坐标点,再通过canvas中的stroke()事件将第一个坐标点与第二个坐标点连接起来变成线。

然后将(x2)坐标点赋值给(x1),继续滑动鼠标。这时(x1)的值为滑动到的第一个坐标点,(x2)为当前坐标点,继续连线。

最后松开鼠标,触发我们人为设置的控制开关painting = false,循环终止,坐标轴停止赋值。一段线段便完成。

// 非触屏设备
// 按下鼠标(mouse)
    //鼠标点击事件(onmousedown)
    canvas.onmousedown = function (e) {
        let x = e.offsetX;
        let y = e.offsetY;
        painting = true;
        if (EraserEnabled) {
            ctx.clearRect(x - 15, y - 15, 30, 30)
        }
        startPoint = {x: x, y: y};
    };

//    滑动鼠标
//    鼠标滑动事件(onmousemove)
    canvas.onmousemove = function (e) {
        let x = e.offsetX;
        let y = e.offsetY;
        let newPoint = {x: x, y: y};
        if (painting) {
            if (EraserEnabled) {
                ctx.clearRect(x - 15, y - 15, 30, 30)
            } else {
                drawLine(startPoint.x, startPoint.y, newPoint.x, newPoint.y);
            }
            startPoint = newPoint;
        }
    };
//    松开鼠标
//    鼠标松开事件(onmouseup)
    canvas.onmouseup = function () {
        painting = false;
    };

 

5、触屏设备中的开始,滑动,结束事件

在移动端中是没有鼠标的,因此与其相对应的有一个触摸事件touch。

步骤与步骤4同理,但需要注意一点:移动设备是支持多点触摸的,因此这里的x、y轴需要从e.touches[0]数组第一个中取。

//触屏设备
    canvas.ontouchstart = function (e) {
        //[0]表示touch第一个触碰点
        let x = e.touches[0].clientX;
        let y = e.touches[0].clientY;
        painting = true;
        if (EraserEnabled) {
            ctx.clearRect(x - 20, y - 20, 40, 40)
        }
        startPoint = {x: x, y: y};
    };
    canvas.ontouchmove = function (e) {
        let x = e.touches[0].clientX;
        let y = e.touches[0].clientY;
        let newPoint = {x: x, y: y};
        if (painting) {
            if (EraserEnabled) {
                ctx.clearRect(x - 15, y - 15, 30, 30)
            } else {
                drawLine(startPoint.x, startPoint.y, newPoint.x, newPoint.y);
            }
            startPoint = newPoint;
        }
    };
    canvas.ontouchend = function () {
        painting = false;
    };

 

6、橡皮擦

通过EraserEnabled是否等于true开启橡皮擦功能

如果等于true,则用clearRect绘制一个空白矩形,重复步骤4,点击、滑动、松开即可达到擦除的效果。

let EraserEnabled = false;
if (EraserEnabled) {
                ctx.clearRect(x - 15, y - 15, 30, 30)
            } else {
                drawLine(startPoint.x, startPoint.y, newPoint.x, newPoint.y);
            }

 

7、选择画笔的颜色

通过canvas中的strokeStyle来改变描边的颜色即可,笔画粗细同理。

然后在css中设置样式,当点击黄色则表示黄色线条,红色则红色线条。

线宽同理,设置为变量,控制它们的传值即可。

//笔画颜色
    ctx.strokeStyle = 'black';
//线宽
    ctx.lineWidth = 2;

 

8、保存为图片

先用canvas.toDataURL获取到画好的画板,然后通过a标签的download事件下载即可

/保存
save.onclick = function() {
    let url = canvas.toDataURL('image/jpg');
    let a = document.createElement('a');
    document.body.appendChild(a);
    a.href = url;
    a.download = '草稿纸';
    a.target = '_blank';
    a.click()
};

 

最后画板完成:

实现一个canvas小画板

 

                                                                              我的canvas在线画板

                                                                                     github源码

 

感兴趣的同学可以点击上方源码了解详情,本人在源码上有详细注释。