You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript实现点击Canvas后填充指定区域的功能

实现方案

你可以通过坐标判断+Canvas路径奇偶填充规则实现需求,核心思路如下:

  • 给Canvas绑定点击事件,获取点击位置相对于画布的坐标
  • 对点击坐标做两层判断:是否在圆形范围内、是否不在正方形范围内
  • 满足判断条件时,复用原有路径,使用evenodd填充规则填充目标区域即可

完整可运行代码

<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
 <canvas width="300" height="300" id="myCanvas" style="border:1px solid #000000;"></canvas>
 <script>
    const canvas = document.getElementById('myCanvas');
    const context = canvas.getContext('2d');
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    const radius = 70;
    // 正方形边长与位置参数
    const squareSize = 50;
    const squareLeft = centerX - squareSize/2;
    const squareTop = centerY - squareSize/2;

    // 绘制初始描边
    function drawOutline() {
        context.beginPath();
        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
        context.rect(squareLeft, squareTop, squareSize, squareSize);
        context.lineWidth = 5;
        context.strokeStyle = '#003300';
        context.stroke();
    }
    drawOutline();

    // 判断点是否在圆内
    function isPointInCircle(x, y) {
        const dx = x - centerX;
        const dy = y - centerY;
        return dx*dx + dy*dy <= radius*radius;
    }

    // 判断点是否在正方形内
    function isPointInSquare(x, y) {
        return x >= squareLeft && x <= squareLeft + squareSize && y >= squareTop && y <= squareTop + squareSize;
    }

    // 点击事件绑定
    canvas.addEventListener('click', function(e) {
        // 获取点击位置相对于canvas的坐标
        const rect = canvas.getBoundingClientRect();
        const clickX = e.clientX - rect.left;
        const clickY = e.clientY - rect.top;

        // 满足点击区域要求:圆内且正方形外
        if (isPointInCircle(clickX, clickY) && !isPointInSquare(clickX, clickY)) {
            // 重绘路径后用evenodd规则填充,自动镂空正方形区域
            context.beginPath();
            context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
            context.rect(squareLeft, squareTop, squareSize, squareSize);
            context.fillStyle = '#99cc99'; // 可自定义填充颜色
            context.fill('evenodd');
            // 重绘描边避免填充覆盖边框
            drawOutline();
        }
    })
 </script>
</body>
</html>

核心实现说明

  • evenodd填充规则:计算路径重叠次数,奇数区域填充、偶数区域镂空,刚好适配你需要的「圆形扣掉正方形」的填充范围
  • 坐标判断逻辑避免了误触:只有点击目标区域才会触发填充,点击正方形内部、圆形外部都不会有反应
  • 填充后重绘描边是为了避免填充色覆盖半透明的边框线条,保证显示效果和初始样式一致

内容的提问来源于stack exchange,提问作者Allen Ye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:39:01