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

如何在HTML对角输入框上方点击按钮绘制Canvas对角线(类三星图案密码)

解决方案:在对角输入框上方绘制Canvas对角线(无需绝对定位输入框)

核心思路

无需给输入框设置absolute定位,通过网格容器相对定位+Canvas绝对定位的组合,让Canvas依附在输入框所在容器内,同时动态获取输入框的实际坐标来精准绘制对角线,既保证布局正常又实现需求效果。

关键改动点

  • 给#grid容器添加position: relative,作为内部绝对定位元素的参考基准
  • 动态获取对角输入框的实际坐标(相对于容器),替代硬编码的固定坐标
  • 将Canvas插入到#grid容器内,而非直接追加到body,确保层级和位置匹配
  • 保留输入框默认流式布局,彻底避免重叠问题

修改后的完整代码

<!DOCTYPE html>
<html>
<head>
    <style>
        #grid {
            position: relative; /* 关键:让内部绝对定位元素以它为基准 */
            display: inline-block; /* 收缩到内容宽度,避免Canvas占满整行 */
        }
        input {
            /* 保留默认布局,无需absolute */
            width: 50px;
            height: 50px;
            font-size: 24px;
            text-align: center;
            margin: 5px;
        }
        canvas {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1; /* 确保在输入框上方 */
            pointer-events: none; /* 避免Canvas遮挡输入框的交互操作 */
        }
        #draw_btn {
            margin-top: 10px;
        }
    </style>
</head>
<body>
<div id="grid">
    <script>
        for(let i = 0; i < 2; i++){
            for(let j = 0; j < 2; j++){
                document.getElementById("grid").innerHTML += `<input type="text" id="cell-${i}-${j}" maxlength="1" value="${2*i+j}" pattern="[A-Za-z]"/>`;
            }
            document.getElementById("grid").innerHTML += "<br/>";
        }
    </script>
    <button onclick="draw()" id="draw_btn">Draw Line</button>
</div>
<script>
    function draw(){
        // 移除已存在的Canvas,避免重复绘制
        const existingCanvas = document.querySelector('#grid canvas');
        if(existingCanvas) existingCanvas.remove();

        const canvas = document.createElement("canvas");
        const grid = document.getElementById('grid');
        // 设置Canvas尺寸为容器实际大小
        canvas.width = grid.offsetWidth;
        canvas.height = grid.offsetHeight;

        const ctx = canvas.getContext("2d");
        ctx.strokeStyle = "#ff0000";
        ctx.lineWidth = 10;
        ctx.lineCap = 'round'; // 让线条端点更圆润,贴近图案解锁样式

        // 获取两个对角输入框元素
        const cell1 = document.getElementById('cell-0-0');
        const cell2 = document.getElementById('cell-1-1');

        // 计算输入框相对于网格容器的中心坐标
        const gridRect = grid.getBoundingClientRect();
        
        const rect1 = cell1.getBoundingClientRect();
        const x1 = rect1.left - gridRect.left + cell1.offsetWidth / 2;
        const y1 = rect1.top - gridRect.top + cell1.offsetHeight / 2;

        const rect2 = cell2.getBoundingClientRect();
        const x2 = rect2.left - gridRect.left + cell2.offsetWidth / 2;
        const y2 = rect2.top - gridRect.top + cell2.offsetHeight / 2;

        // 绘制对角线
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.stroke();

        // 将Canvas插入网格容器
        grid.appendChild(canvas);
    }
</script>
</body>
</html>

额外说明

  • pointer-events: none 确保Canvas不会拦截输入框的点击、输入等交互
  • 每次绘制前移除旧Canvas,避免线条重复叠加
  • 通过getBoundingClientRect()获取坐标,即使输入框布局变化,线条也能精准连接对角输入框中心

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:15:55