js插件实现画笔绘图
使用HTML5 Canvas实现画笔绘图
HTML5的Canvas API是浏览器原生支持的绘图工具,无需额外插件即可实现画笔功能。以下是一个基础实现示例:
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
function startDrawing(e) {
isDrawing = true;
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
}
function draw(e) {
if (!isDrawing) return;
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
}
function stopDrawing() {
isDrawing = false;
}
使用第三方库Fabric.js
Fabric.js是一个功能强大的Canvas库,提供更高级的绘图功能:

const canvas = new fabric.Canvas('drawingCanvas');
let isDrawing = false;
canvas.on('mouse:down', (o) => {
isDrawing = true;
const pointer = canvas.getPointer(o.e);
canvas.freeDrawingBrush.startFrom({ x: pointer.x, y: pointer.y });
});
canvas.on('mouse:move', (o) => {
if (!isDrawing) return;
const pointer = canvas.getPointer(o.e);
canvas.freeDrawingBrush.moveTo({ x: pointer.x, y: pointer.y });
});
canvas.on('mouse:up', () => {
isDrawing = false;
});
// 设置画笔样式
canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);
canvas.freeDrawingBrush.color = '#000000';
canvas.freeDrawingBrush.width = 5;
使用SVG实现矢量绘图
SVG也是浏览器原生支持的矢量绘图方案:
const svg = document.getElementById('drawingSvg');
let isDrawing = false;
let currentPath;
svg.addEventListener('mousedown', (e) => {
isDrawing = true;
currentPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
currentPath.setAttribute('stroke', 'black');
currentPath.setAttribute('fill', 'none');
currentPath.setAttribute('stroke-width', '2');
const startPoint = `M ${e.offsetX} ${e.offsetY} `;
currentPath.setAttribute('d', startPoint);
svg.appendChild(currentPath);
});
svg.addEventListener('mousemove', (e) => {
if (!isDrawing) return;
const newPoint = `L ${e.offsetX} ${e.offsetY}`;
const existingPath = currentPath.getAttribute('d');
currentPath.setAttribute('d', existingPath + newPoint);
});
svg.addEventListener('mouseup', () => {
isDrawing = false;
});
添加触摸屏支持
为移动设备添加触摸事件支持:

canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent('mousedown', {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
});
canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent('mousemove', {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
});
canvas.addEventListener('touchend', (e) => {
e.preventDefault();
const mouseEvent = new MouseEvent('mouseup', {});
canvas.dispatchEvent(mouseEvent);
});
实现撤销重做功能
为绘图工具添加历史记录功能:
const history = [];
let historyIndex = -1;
function saveState() {
historyIndex++;
if (historyIndex < history.length) {
history.length = historyIndex;
}
history.push(canvas.toDataURL());
}
function undo() {
if (historyIndex <= 0) return;
historyIndex--;
const img = new Image();
img.onload = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
};
img.src = history[historyIndex];
}
function redo() {
if (historyIndex >= history.length - 1) return;
historyIndex++;
const img = new Image();
img.onload = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
};
img.src = history[historyIndex];
}
添加画笔样式选项
提供多种画笔样式选择:
function setBrushColor(color) {
ctx.strokeStyle = color;
ctx.fillStyle = color;
}
function setBrushSize(size) {
ctx.lineWidth = size;
}
function setBrushType(type) {
switch(type) {
case 'pencil':
ctx.globalCompositeOperation = 'source-over';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
break;
case 'marker':
ctx.globalCompositeOperation = 'multiply';
ctx.lineCap = 'square';
ctx.lineJoin = 'bevel';
break;
case 'eraser':
ctx.globalCompositeOperation = 'destination-out';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
break;
}
}






