插件窝 干货文章 如何在HTML5 Canvas上实现压力感知的签名笔触粗细变化?

如何在HTML5 Canvas上实现压力感知的签名笔触粗细变化?

压力 Canvas pressure 笔触 555    来源:    2025-03-21

在HTML5 Canvas上实现压力感知的签名笔触粗细变化,通常需要结合使用Pointer Events API和Canvas的绘图功能。Pointer Events API可以捕获到触摸或触笔的压力信息,而Canvas则用于绘制笔触。

以下是一个简单的实现步骤:

1. 设置Canvas和事件监听器

首先,创建一个Canvas元素,并为其添加Pointer Events的事件监听器。

<canvas id="signatureCanvas" width="800" height="600"></canvas>
const canvas = document.getElementById('signatureCanvas');
const ctx = canvas.getContext('2d');

// 设置初始样式
ctx.strokeStyle = '#000000';
ctx.lineJoin = 'round';
ctx.lineCap = 'round';

// 标志是否正在绘制
let isDrawing = false;

// 记录上一次的坐标
let lastX = 0;
let lastY = 0;

// 记录当前压力值
let pressure = 0.5; // 默认压力值

2. 监听Pointer Events

通过Pointer Events API来捕获触摸或触笔的压力信息。

canvas.addEventListener('pointerdown', (e) => {
    isDrawing = true;
    [lastX, lastY] = [e.offsetX, e.offsetY];
    pressure = e.pressure || 0.5; // 获取压力值,如果没有压力信息则使用默认值
});

canvas.addEventListener('pointermove', (e) => {
    if (!isDrawing) return;

    // 获取当前压力值
    pressure = e.pressure || 0.5;

    // 根据压力值调整笔触粗细
    ctx.lineWidth = pressure * 10; // 压力值范围是0到1,乘以10来调整粗细

    // 开始绘制
    ctx.beginPath();
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();

    // 更新上一次的坐标
    [lastX, lastY] = [e.offsetX, e.offsetY];
});

canvas.addEventListener('pointerup', () => {
    isDrawing = false;
});

canvas.addEventListener('pointerout', () => {
    isDrawing = false;
});

3. 处理压力值

pointermove事件中,通过e.pressure获取当前的压力值。压力值的范围通常是0到1,0表示没有压力,1表示最大压力。你可以根据这个值来动态调整笔触的粗细。

ctx.lineWidth = pressure * 10; // 压力值范围是0到1,乘以10来调整粗细

4. 绘制笔触

pointermove事件中,使用ctx.lineTo()ctx.stroke()来绘制笔触。根据压力值调整ctx.lineWidth,从而实现笔触粗细的变化。

5. 兼容性处理

需要注意的是,e.pressure属性在部分设备上可能不可用。为了兼容性,可以设置一个默认的压力值(如0.5),在没有压力信息时使用。

pressure = e.pressure || 0.5; // 获取压力值,如果没有压力信息则使用默认值

6. 完整代码示例

以下是完整的代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pressure Sensitive Signature</title>
    <style>
        canvas {
            border: 1px solid #000;
        }
    </style>
</head>
<body>
    <canvas id="signatureCanvas" width="800" height="600"></canvas>

    <script>
        const canvas = document.getElementById('signatureCanvas');
        const ctx = canvas.getContext('2d');

        ctx.strokeStyle = '#000000';
        ctx.lineJoin = 'round';
        ctx.lineCap = 'round';

        let isDrawing = false;
        let lastX = 0;
        let lastY = 0;
        let pressure = 0.5;

        canvas.addEventListener('pointerdown', (e) => {
            isDrawing = true;
            [lastX, lastY] = [e.offsetX, e.offsetY];
            pressure = e.pressure || 0.5;
        });

        canvas.addEventListener('pointermove', (e) => {
            if (!isDrawing) return;

            pressure = e.pressure || 0.5;
            ctx.lineWidth = pressure * 10;

            ctx.beginPath();
            ctx.moveTo(lastX, lastY);
            ctx.lineTo(e.offsetX, e.offsetY);
            ctx.stroke();

            [lastX, lastY] = [e.offsetX, e.offsetY];
        });

        canvas.addEventListener('pointerup', () => {
            isDrawing = false;
        });

        canvas.addEventListener('pointerout', () => {
            isDrawing = false;
        });
    </script>
</body>
</html>

7. 测试

在支持压力感应的设备上(如带有触笔的平板电脑),你可以测试这个实现。当你用不同的压力绘制时,笔触的粗细会相应变化。

8. 进一步优化

  • 平滑处理:可以通过插值或贝塞尔曲线来平滑笔触。
  • 颜色变化:除了粗细,还可以根据压力值调整笔触的颜色或透明度。
  • 撤销功能:可以添加撤销功能,允许用户撤销之前的绘制操作。

通过这些步骤,你可以在HTML5 Canvas上实现一个简单的压力感知的签名笔触粗细变化效果。