js实现手绘
使用Canvas实现手绘功能
在JavaScript中,可以通过HTML5的Canvas API实现手绘功能。Canvas提供了绘制路径的方法,适合用于创建绘图应用。
基本实现步骤
创建Canvas元素并设置基本样式
<canvas id="drawingCanvas" width="800" height="600"></canvas>
获取Canvas上下文并设置初始参数
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');
ctx.strokeStyle = '#000000';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
设置鼠标/触摸事件监听器

let isDrawing = false;
let lastX = 0;
let lastY = 0;
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
实现绘图函数
function startDrawing(e) {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
}
function draw(e) {
if (!isDrawing) return;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[lastX, lastY] = [e.offsetX, e.offsetY];
}
function stopDrawing() {
isDrawing = false;
}
添加触摸支持
为支持移动设备,需要添加触摸事件处理
canvas.addEventListener('touchstart', handleTouchStart);
canvas.addEventListener('touchmove', handleTouchMove);
canvas.addEventListener('touchend', handleTouchEnd);
function handleTouchStart(e) {
e.preventDefault();
const touch = e.touches[0];
const rect = canvas.getBoundingClientRect();
startDrawing({
offsetX: touch.clientX - rect.left,
offsetY: touch.clientY - rect.top
});
}
function handleTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
const rect = canvas.getBoundingClientRect();
draw({
offsetX: touch.clientX - rect.left,
offsetY: touch.clientY - rect.top
});
}
function handleTouchEnd() {
stopDrawing();
}
增强功能实现
改变画笔颜色

function changeColor(color) {
ctx.strokeStyle = color;
}
改变画笔粗细
function changeWidth(width) {
ctx.lineWidth = width;
}
清除画布
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
保存绘图
function saveDrawing() {
const dataURL = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = 'drawing.png';
link.href = dataURL;
link.click();
}
使用压力敏感度(适用于支持压感的设备)
canvas.addEventListener('mousemove', (e) => {
if (!isDrawing) return;
const pressure = e.pressure || 0.5; // 默认值
ctx.lineWidth = baseWidth * pressure;
draw(e);
});
优化绘制性能
使用requestAnimationFrame优化绘制性能
function draw(e) {
if (!isDrawing) return;
requestAnimationFrame(() => {
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[lastX, lastY] = [e.offsetX, e.offsetY];
});
}
实现橡皮擦功能
function enableEraser() {
ctx.globalCompositeOperation = 'destination-out';
}
function disableEraser() {
ctx.globalCompositeOperation = 'source-over';
}
这些代码片段提供了完整的绘图功能实现,可以根据需要进一步扩展和定制。






