ZetCode

JavaScript Canvas addHitRegion 教程

最后修改于 2025 年 4 月 3 日

本教程探讨 JavaScript 中的 Canvas addHitRegion 方法。它能够创建 canvas 元素上的交互式区域,这些区域可以响应用户输入。这对于游戏开发和复杂的 UI 尤其有用。

基本定义

addHitRegion 方法将一个命中区域添加到 canvas 路径中。该区域变得可交互,响应鼠标和触摸事件。它简化了复杂 canvas 绘图的事件处理。

命中区域可以具有唯一的 ID 或控制属性。它们与现有的 canvas 路径一起工作。请注意,此功能曾是实验性的,可能并非在所有浏览器中都有效。为了获得更广泛的支持,请考虑使用 polyfills。

基本命中区域示例

此示例演示了如何创建一个带有命中区域的简单可点击矩形。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic Hit Region</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>
<p id="output">Click the rectangle</p>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    const output = document.getElementById('output');
    
    // Draw rectangle
    ctx.beginPath();
    ctx.rect(50, 50, 200, 100);
    ctx.fillStyle = 'blue';
    ctx.fill();
    
    // Add hit region
    ctx.addHitRegion({ id: 'myRect' });
    
    // Handle clicks
    canvas.addEventListener('click', function(e) {
        if (e.region) {
            output.textContent = `Clicked region: ${e.region}`;
        }
    });
</script>

</body>
</html>

此代码创建一个蓝色矩形,并为其分配一个 ID 为 'myRect' 的命中区域。当点击时,事件处理程序会检查区域属性并显示它。

addHitRegion 方法在定义路径后被调用。点击事件通过事件对象的 region 属性提供区域信息。

多个命中区域

此示例展示了如何创建和处理多个交互式区域。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Multiple Hit Regions</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>
<p id="output">Click any shape</p>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    const output = document.getElementById('output');
    
    // Circle
    ctx.beginPath();
    ctx.arc(100, 100, 50, 0, Math.PI * 2);
    ctx.fillStyle = 'red';
    ctx.fill();
    ctx.addHitRegion({ id: 'circle' });
    
    // Triangle
    ctx.beginPath();
    ctx.moveTo(300, 100);
    ctx.lineTo(350, 200);
    ctx.lineTo(250, 200);
    ctx.closePath();
    ctx.fillStyle = 'green';
    ctx.fill();
    ctx.addHitRegion({ id: 'triangle' });
    
    // Event handling
    canvas.addEventListener('click', function(e) {
        if (e.region) {
            output.textContent = `Clicked ${e.region}`;
        }
    });
</script>

</body>
</html>

这里我们创建了两个形状:一个红色的圆和一个绿色的三角形。每个形状都有自己带有唯一 ID 的命中区域。点击处理程序会识别哪个区域被点击了。

这演示了命中区域如何区分不同的 canvas 元素。通过检查 e.region,相同的事件处理程序可以用于所有区域。

带有自定义控件的命中区域

此示例展示了如何将命中区域与表单控件关联。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Hit Region with Control</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>
<input type="checkbox" id="myCheckbox"> Toggle me via canvas

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    const checkbox = document.getElementById('myCheckbox');
    
    // Draw button
    ctx.beginPath();
    ctx.rect(50, 50, 200, 100);
    ctx.fillStyle = checkbox.checked ? 'green' : 'gray';
    ctx.fill();
    ctx.strokeStyle = 'black';
    ctx.stroke();
    
    // Add hit region linked to checkbox
    ctx.addHitRegion({ control: checkbox });
    
    // Update canvas when checkbox changes
    checkbox.addEventListener('change', function() {
        ctx.fillStyle = this.checked ? 'green' : 'gray';
        ctx.fill();
    });
</script>

</body>
</html>

此代码将 canvas 矩形链接到一个复选框控件。点击矩形会切换复选框,反之亦然。视觉状态会相应更新。

addHitRegion 中的 control 属性创建了这种关联。复选框的 change 事件会重绘 canvas 以反映其状态。

可访问的命中区域

此示例演示了如何使用标签使命中区域可访问。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Accessible Hit Regions</title>
</head>
<body>

<canvas id="myCanvas" width="300" height="200"></canvas>
<p id="output">Interact with the buttons</p>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    const output = document.getElementById('output');
    
    // Play button
    ctx.beginPath();
    ctx.rect(50, 50, 80, 40);
    ctx.fillStyle = 'green';
    ctx.fill();
    ctx.addHitRegion({
        id: 'play',
        label: 'Play button',
        role: 'button'
    });
    
    // Stop button
    ctx.beginPath();
    ctx.rect(170, 50, 80, 40);
    ctx.fillStyle = 'red';
    ctx.fill();
    ctx.addHitRegion({
        id: 'stop',
        label: 'Stop button',
        role: 'button'
    });
    
    // Handle interactions
    canvas.addEventListener('click', function(e) {
        if (e.region) {
            output.textContent = `${e.region} activated`;
        }
    });
</script>

</body>
</html>

这创建了两个具有正确的可访问性属性的按钮。label 提供了文本描述,而 role 表明了元素类型。

屏幕阅读器可以使用此信息来描述交互式区域。当区域被激活时,点击处理程序会提供反馈。

带有命中区域的复杂路径

此示例展示了一个具有单个命中区域的复杂自定义路径。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Complex Path Hit Region</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>
<p id="output">Click the star shape</p>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    const output = document.getElementById('output');
    
    // Draw star shape
    ctx.beginPath();
    ctx.moveTo(200, 50);
    ctx.lineTo(225, 100);
    ctx.lineTo(280, 110);
    ctx.lineTo(240, 150);
    ctx.lineTo(250, 200);
    ctx.lineTo(200, 175);
    ctx.lineTo(150, 200);
    ctx.lineTo(160, 150);
    ctx.lineTo(120, 110);
    ctx.lineTo(175, 100);
    ctx.closePath();
    
    ctx.fillStyle = 'gold';
    ctx.fill();
    ctx.strokeStyle = 'orange';
    ctx.lineWidth = 2;
    ctx.stroke();
    
    // Add hit region for entire star
    ctx.addHitRegion({ id: 'star' });
    
    // Handle clicks
    canvas.addEventListener('click', function(e) {
        if (e.region === 'star') {
            output.textContent = 'You clicked the star!';
        }
    });
</script>

</body>
</html>

此代码创建了一个复杂的星形,并用一个覆盖整个路径的命中区域。点击处理程序会专门检查 'star' 区域。

该示例表明,命中区域可以与任何路径一起使用,无论其复杂程度如何。整个形状作为一个整体变得可交互。

来源

MDN Canvas addHitRegion 文档

本教程通过实际示例涵盖了 addHitRegion 方法。虽然功能强大,但请记住浏览器支持可能有所不同。请考虑在生产环境中使用回退方案。

作者

我叫 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 JS Canvas 教程