canvas进阶之如何画出平滑的曲线

2020-04-21 07:04:34易采站长站整理

背景概要

相信大家平时在学习canvas 或 项目开发中使用canvas的时候应该都遇到过这样的需求:实现一个可以书写的画板小工具。

嗯,相信这对canvas使用较熟的童鞋来说仅仅只是几十行代码就可以搞掂的事情,以下demo就是一个再也简单不过的例子了:


<!DOCTYPE html>
<html>
<head>
<title>Sketchpad demo</title>
<style type="text/css">
canvas {
border: 1px blue solid;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="500"></canvas>
<script type="text/javascript">
let isDown = false;
let beginPoint = null;
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

// 设置线条颜色
ctx.strokeStyle = 'red';
ctx.lineWidth = 1;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';

canvas.addEventListener('mousedown', down, false);
canvas.addEventListener('mousemove', move, false);
canvas.addEventListener('mouseup', up, false);
canvas.addEventListener('mouseout', up, false);

function down(evt) {
isDown = true;
beginPoint = getPos(evt);
}

function move(evt) {
if (!isDown) return;
const endPoint = getPos(evt);
drawLine(beginPoint, endPoint);
beginPoint = endPoint;
}

function up(evt) {
if (!isDown) return;

const endPoint = getPos(evt);
drawLine(beginPoint, endPoint);

beginPoint = null;
isDown = false;
}

function getPos(evt) {
return {
x: evt.clientX,
y: evt.clientY
}
}

function drawLine(beginPoint, endPoint) {
ctx.beginPath();
ctx.moveTo(beginPoint.x, beginPoint.y);
ctx.lineTo(endPoint.x, endPoint.y);
ctx.stroke();
ctx.closePath();
}
</script>
</body>
</html>

它的实现逻辑也很简单:

我们在canvas画布上主要监听了三个事件:

mousedown
mouseup
mousemove
,同时我们也创建了一个
isDown
变量;
当用户按下鼠标(
mousedown
,即起笔)时将
isDown
置为
true
,而放下鼠标(
mouseup
)的时候将它置为
false
,这样做的好处就是可以判断用户当前是否处于绘画状态;
通过
mousemove
事件不断采集鼠标经过的坐标点,当且仅当