js实现白板
实现白板的基本思路
使用HTML5的Canvas API可以轻松实现一个简单的白板功能。Canvas提供了绘制路径、形状、文本和图像的方法,结合鼠标事件监听可以实现自由绘制。
基础代码结构
<!DOCTYPE html>
<html>
<head>
<title>简易白板</title>
<style>
#drawing-board {
border: 1px solid #000;
cursor: crosshair;
}
</style>
</head>
<body>
<canvas id="drawing-board" width="800" height="600"></canvas>
<script src="script.js"></script>
</body>
</html>
JavaScript实现
const canvas = document.getElementById('drawing-board');
const ctx = canvas.getContext('2d');
let isDrawing = false;
let lastX = 0;
let lastY = 0;
// 设置画笔样式
ctx.strokeStyle = '#000';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
// 鼠标按下事件
canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
});
// 鼠标移动事件
canvas.addEventListener('mousemove', (e) => {
if (!isDrawing) return;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[lastX, lastY] = [e.offsetX, e.offsetY];
});
// 鼠标释放事件
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);
功能扩展
颜色选择器
const colorPicker = document.createElement('input');
colorPicker.type = 'color';
document.body.prepend(colorPicker);
colorPicker.addEventListener('change', (e) => {
ctx.strokeStyle = e.target.value;
});
画笔粗细调整
const brushSize = document.createElement('input');
brushSize.type = 'range';
brushSize.min = '1';
brushSize.max = '50';
document.body.prepend(brushSize);
brushSize.addEventListener('change', (e) => {
ctx.lineWidth = e.target.value;
});
清除画布
const clearBtn = document.createElement('button');
clearBtn.textContent = '清除';
document.body.prepend(clearBtn);
clearBtn.addEventListener('click', () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
触摸屏支持
// 触摸开始
canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
isDrawing = true;
const rect = canvas.getBoundingClientRect();
[lastX, lastY] = [e.touches[0].clientX - rect.left, e.touches[0].clientY - rect.top];
});
// 触摸移动
canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
if (!isDrawing) return;
const rect = canvas.getBoundingClientRect();
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(e.touches[0].clientX - rect.left, e.touches[0].clientY - rect.top);
ctx.stroke();
[lastX, lastY] = [e.touches[0].clientX - rect.left, e.touches[0].clientY - rect.top];
});
// 触摸结束
canvas.addEventListener('touchend', () => isDrawing = false);
保存绘图
const saveBtn = document.createElement('button');
saveBtn.textContent = '保存';
document.body.prepend(saveBtn);
saveBtn.addEventListener('click', () => {
const link = document.createElement('a');
link.download = 'drawing.png';
link.href = canvas.toDataURL('image/png');
link.click();
});
优化绘图性能
对于复杂绘图,可以使用requestAnimationFrame优化性能:
function draw(x, y) {
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.stroke();
[lastX, lastY] = [x, y];
}
function throttle(callback, delay) {
let previousCall = new Date().getTime();
return function() {
const time = new Date().getTime();
if ((time - previousCall) >= delay) {
previousCall = time;
callback.apply(null, arguments);
}
};
}
canvas.addEventListener('mousemove', throttle((e) => {
if (!isDrawing) return;
draw(e.offsetX, e.offsetY);
}, 10));
以上代码实现了一个功能完整的简易白板,支持鼠标和触摸绘制、颜色选择、画笔粗细调整、清除画布和保存图片等功能。可以根据需要进一步扩展,如添加形状工具、文字工具或撤销重做功能。







