h5实现毛笔
使用Canvas绘制毛笔效果
在H5中实现毛笔效果,可以通过Canvas的路径绘制和笔触样式模拟。Canvas的lineTo方法结合适当的线条样式可以创造出类似毛笔的笔触。
const canvas = document.getElementById('canvas');
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;
draw(e);
}
function draw(e) {
if (!isDrawing) return;
ctx.lineWidth = 20;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.strokeStyle = '#000';
ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
}
function stopDrawing() {
isDrawing = false;
ctx.beginPath();
}
添加压力感应效果
为了更真实地模拟毛笔,可以根据绘制速度动态调整线条宽度。快速移动时线条变细,慢速时线条变粗。
let lastX, lastY, velocity = 0;
function draw(e) {
if (!isDrawing) return;
const currentX = e.clientX - canvas.offsetLeft;
const currentY = e.clientY - canvas.offsetTop;
if (lastX && lastY) {
const dist = Math.sqrt(Math.pow(currentX - lastX, 2) + Math.pow(currentY - lastY, 2));
velocity = dist * 0.2 + velocity * 0.8;
}
const lineWidth = Math.max(5, 30 - velocity);
ctx.lineWidth = lineWidth;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.strokeStyle = '#000';
ctx.lineTo(currentX, currentY);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(currentX, currentY);
lastX = currentX;
lastY = currentY;
}
实现毛笔纹理效果
使用带有透明度的图像作为笔刷图案,可以模拟毛笔的纹理。创建一个带有纹理的Canvas图案,然后将其作为填充样式。
const textureCanvas = document.createElement('canvas');
const textureCtx = textureCanvas.getContext('2d');
textureCanvas.width = 50;
textureCanvas.height = 50;
// 创建简单的纹理
textureCtx.fillStyle = '#000';
for (let i = 0; i < 200; i++) {
const x = Math.random() * textureCanvas.width;
const y = Math.random() * textureCanvas.height;
const radius = Math.random() * 3;
textureCtx.beginPath();
textureCtx.arc(x, y, radius, 0, Math.PI * 2);
textureCtx.fill();
}
const pattern = ctx.createPattern(textureCanvas, 'repeat');
function draw(e) {
// ...之前的绘制代码...
ctx.strokeStyle = pattern;
// ...继续绘制...
}
触摸设备支持
为了在移动设备上使用,需要添加触摸事件的支持。触摸事件的处理与鼠标事件类似,但需要考虑多点触控。
canvas.addEventListener('touchstart', handleTouchStart);
canvas.addEventListener('touchmove', handleTouchMove);
canvas.addEventListener('touchend', handleTouchEnd);
function handleTouchStart(e) {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent('mousedown', {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}
function handleTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent('mousemove', {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}
function handleTouchEnd(e) {
e.preventDefault();
const mouseEvent = new MouseEvent('mouseup', {});
canvas.dispatchEvent(mouseEvent);
}
优化性能
频繁的Canvas操作可能导致性能问题,特别是在移动设备上。使用requestAnimationFrame进行节流,并考虑使用离屏Canvas进行绘制。

let requestId;
function draw(e) {
if (!isDrawing) return;
cancelAnimationFrame(requestId);
requestId = requestAnimationFrame(() => {
// 绘制逻辑...
});
}
这些方法结合起来可以创建一个在H5中模拟毛笔书写效果的功能实现。根据具体需求,可以进一步调整笔触样式、纹理和交互细节。
