d3.js - 为什么笔画模糊,除非偏移 0.5?

mar*_*fen 2 javascript css svg stroke d3.js

我正在尝试使用 d3 构建仪表板,并将布局构建为响应式网格。我正在使用 d3 为网格中的每个项目添加一个 svg 元素,当我添加 svg 元素时,我还添加了一个相对于每个网格项目的大小进行定位和缩放的矩形。rect 的笔触 (stroke-width=1) 总是被画得很模糊,唯一让它清晰的方法是在 rect 的 x 和 y 位置加上 0.5。

模糊: 模糊的笔触

清脆(矩形偏移 0.5): 清晰的笔触,矩形偏移 0.5

我了解抗锯齿是什么以及这从根本上是什么导致了模糊的线条。我试图了解如何/在哪里/为什么将 rects 放置 0.5 off,或者默认情况下它们是否放置在像素之间。

模糊检查

我使用 .clientHeight/.clientWidth 来设置 svg 元素的视图框,并设置矩形的大小。这两个变量都返回整数。我使用“fr”单位来定义网格,我尝试切换到绝对像素值,但没有帮助。

非常感谢,这里有一个片段和一个 codepen 项目:

  let rect = svg.selectAll('rect').data([null]);
  rect.enter().append('rect')
    .merge(rect)
      .attr('x', 10) // if I make these values '10.5'
      .attr('y', 10) // then everything looks crisp...
      .attr('width', props.width - 20)
      .attr('height', props.height - 20)
      .style('fill', 'none')
      .style('stroke', '#FFFFFF')
      .style('stroke-width', '1')
Run Code Online (Sandbox Code Playgroud)

https://codepen.io/markersniffen/project/editor/AKmYea

Dai*_*Dai 5

这是因为在 SVG(和 HTML5 的<canvas>)中,每个“像素”坐标点都存在于像素之间的一条线上。

因此,如果您有一条 1px 宽的垂直线从(0,0)到 ,(0,5)那么如果该线的笔触转换为矩形,则其坐标将为:

(插图不是按比例绘制的):

   (-0.5, -0.5)  +-------+  (0.5, -0.5)
                 |       |
                 |       |
                 |       |
                 |       |
                 |<-1px->|
                 |       |
                 |       |
                 |       |
                 |       |
   (-0.5,  5.5)  +-------+  (0.5,  5.5)

Run Code Online (Sandbox Code Playgroud)

正如您所注意到的,通过将您自己的0.5px偏移量应用于点坐标,然后线条再次捕捉到像素网格:

         (0, 0)  +-------+  (1, 0)
                 |       |
                 |       |
                 |       |
                 |       |
                 |<-1px->|
                 |       |
                 |       |
                 |       |
                 |       |
         (0, 6)  +-------+  (1, 6)

Run Code Online (Sandbox Code Playgroud)

为了纠正这个问题(没有双关语),您可以继续使用您的+0.5px-offset 方法,或确保像素对齐线的所有笔划都是2px宽度的倍数(但这确实意味着您不能拥有 1px 宽的笔划线或路径沿整数像素坐标点)。

您还可以更改每个 SVG 路径/形状元素上的抗锯齿设置,但我不建议这样做,因为如果您有任何与像素网格不完全对齐的笔触或点(即您的 SVG 文件有超过只是水平线和垂直线),那么结果在屏幕上看起来很难看,尤其是在低 DPI 设备上。