实现一个canvas小画板
<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端举例):
- 点击鼠标
- 滑动鼠标
- 松开鼠标
一笔完成
所以我们要监听上面三点的鼠标事件,然后拿到其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()
};
最后画板完成:
感兴趣的同学可以点击上方源码了解详情,本人在源码上有详细注释。