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

HTML Canvas绘制网格线条粗糊问题求助

解决Canvas网格线条过粗、模糊的问题

问题原因

你遇到的异常是两个问题叠加导致的:

  • 线条对齐错误:Canvas绘制lineWidth=1的线条时,若坐标为整数,线条中心会落在像素边界上,导致线条覆盖相邻两个像素并触发抗锯齿,看起来模糊且变粗(在DPR=2的屏幕上会显示为2物理像素)。
  • 高DPI适配不完整:之前的适配代码仅调整了画布尺寸和上下文缩放,但未修正绘制坐标的偏移,无法解决线条对齐的根本问题。

解决方案

要实现1物理像素粗的清晰网格,需要同时处理高DPI适配和线条像素对齐:

修改后的完整JS代码

const canvas = document.getElementById('gridCanvas') as HTMLCanvasElement;
const context = canvas.getContext('2d') as CanvasRenderingContext2D;

const squareSize = 20; // CSS像素下的方格大小
const numRows = 10;
const numCols = 15;
const dpr = window.devicePixelRatio || 1;

// 1. 设置Canvas的CSS尺寸(显示大小)
canvas.style.width = `${numCols * squareSize}px`;
canvas.style.height = `${numRows * squareSize}px`;

// 2. 设置Canvas的实际像素尺寸(绘制缓冲区大小)
canvas.width = numCols * squareSize * dpr;
canvas.height = numRows * squareSize * dpr;

// 3. 缩放绘图上下文,适配高DPI
context.scale(dpr, dpr);

// 修正:添加0.5px偏移,让线条对齐像素中心
const offset = 0.5;

function drawGrid() {
    context.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr);

    context.strokeStyle = 'black';
    context.lineWidth = 1; // CSS像素下的线条宽度,对应1物理像素(dpr=2时实际是2设备像素)
    context.globalAlpha = 1.0;

    // 绘制水平线
    for (let row = 0; row <= numRows; row++) {
        context.beginPath();
        context.moveTo(offset, row * squareSize + offset);
        context.lineTo(numCols * squareSize + offset, row * squareSize + offset);
        context.stroke();
    }

    // 绘制垂直线
    for (let col = 0; col <= numCols; col++) {
        context.beginPath();
        context.moveTo(col * squareSize + offset, offset);
        context.lineTo(col * squareSize + offset, numRows * squareSize + offset);
        context.stroke();
    }
}

window.onload = drawGrid;

对应的HTML代码(无需修改,保持原结构即可)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas Grid</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
    </style>
</head>
<body>
    <canvas id="gridCanvas"></canvas>
    <script src="../dist/main.js"></script>
</body>
</html>

关键说明

  • 像素对齐偏移:添加0.5的偏移量,让线条的中心正好落在CSS像素的中心位置,避免抗锯齿导致的模糊。
  • 高DPI适配:通过dpr缩放画布尺寸和上下文,确保绘制的内容在高分辨率屏幕上显示清晰,lineWidth=1在CSS像素下对应1物理像素(设备像素为1*dpr)。
  • 若仍有轻微模糊,可添加context.imageSmoothingEnabled = false;关闭图像平滑,但对齐像素中心后通常不需要这一步。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:53:14