当前位置:首页 > HTML

h5实现毛笔

2026-03-06 12:59:47HTML

使用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进行绘制。

h5实现毛笔

let requestId;

function draw(e) {
    if (!isDrawing) return;

    cancelAnimationFrame(requestId);
    requestId = requestAnimationFrame(() => {
        // 绘制逻辑...
    });
}

这些方法结合起来可以创建一个在H5中模拟毛笔书写效果的功能实现。根据具体需求,可以进一步调整笔触样式、纹理和交互细节。

标签: 毛笔
分享给朋友: