【问题标题】:Why is SVG stroke-width : 1 making lines transparent?为什么 SVG stroke-width : 1 使线条透明?
【发布时间】:2011-11-16 02:43:10
【问题描述】:

我正在使用 svg 创建股票图表,当我将路径元素的笔画宽度设置为 1 时遇到问题。不是让线条更窄,而是让它的大小与笔画相同 -宽度:2 但略微透明。我无法发布它的图片,因为我没有足够的声望点...

我的 svg 标签如下所示:

<div style="height:300px; width:400px; overflow:hidden">
<svg style="position:relative" height="10000" width="10000" version="1.1" xmlns="http://www.w3.org/2000/svg">
</svg>
</div>

我正在使用 javascript/jquery 动态添加路径元素:

var shape = document.createElementNS("http://www.w3.org/2000/svg", "path");
$(shape).attr({"d":"...",
               "fill":"none",
               "stroke":color,
               "stroke-width":"1"});
$("svg").append(shape);

我省略了路径的d 属性的值,因为它有点长。此外,color 是一个字符串变量,预先确定为“green”、“red”或“black”。

我的代码中是否有问题导致此问题,还是其他问题?

【问题讨论】:

  • 如果不能发图,大概可以发个jsfiddle。

标签: svg width transparent stroke


【解决方案1】:

这可能是由于大多数 SVG 实现中应用了抗锯齿。当线宽接近或低于 1 时,抗锯齿会使得半覆盖的像素呈现部分不透明。使用默认变换和视口,您的单像素线可能正好位于两个物理像素之间的边界上,因此它们都被覆盖了一半,从而导致整体 50% 的透明度。在白色背景上有一条黑线,这会产生 50% 的灰色。

【讨论】:

  • 有什么办法可以改变吗?当我在 w3schools.com 上玩 svg 示例时,stroke-width:1 的线条在没有透明度的情况下显示得很好。
  • 取决于渲染器;不知道是否有办法影响这一点。可能有一种方法可以打开抗锯齿,但我知道没有标准方法。
  • 好的,我用谷歌搜索了这个并且能够弄清楚。我所要做的就是将 shape-rendering:crispEdges 添加到路径元素的样式中,它现在显示为 1px 宽的线。感谢您的帮助!
  • @MattL922 您可以尝试减小图形大小,例如而是在根标签中使用height="10000" width="10000",使用适合普通屏幕的内容。之后尝试使用整数而不是浮点数作为坐标。这样一来,在一个完整的像素上渲染一条线的概率就会高得多。
  • @feeela 是的,接下来我将通过缩放和转换 svg 来着手解决这个问题。现在我正在绘制整个价格历史并根据滑块值向左/向右移动 svg - 这就是尺寸如此巨大的原因。此外,我将价格转换为美分,这样我就不会得到浮动坐标,这确实有帮助。
【解决方案2】:

如果线条是水平的或垂直的,只需将线条放置在半个像素处,例如x="1.5px"

另一种方法是在线条上应用一些 CSS:

.thelines{
    shape-rendering:crispEdges
}

The spec chapter on shape-rendering property.

【讨论】:

  • 谢谢,萨米尔!但实际上这不是作弊,因为如果将实际线放置在精确坐标处,则在其两侧绘制笔划,并且您实际上会看到两像素半透明线,而不是一像素不透明线。
  • 非常感谢。从过去的两个小时开始,我一直在努力解决这个问题:P 减少笔画宽度根本没有效果。
【解决方案3】:

可能有点晚了,但真正的原因是,当您在无限小的网格线上绘制时,笔画宽度为 1 的线会呈现为左右(或上方/下方)半像素从网格线。我通过使用变换 0.5,0.5 在所有对象周围添加一个组来解决这个问题,因此所有内容都移动了半个网格线。

因此,您绘制的所有内容现在正好位于 2 条网格线的中间。笔画宽度为 1 的线现在将在左侧有半个像素,在左侧有半个像素,但两者都从中间开始。得到一条与您想要的厚度完全一致的线:1 像素...

例子:

<g transform="translate(0.5,0.5)">
 <g>
   <path />
   <path />
 </g>
 <g>
   <path />
   <path />
 </g>
</g>

【讨论】:

  • 这实际上解决了任何问题,酷!我只是将变换放在主节点上,其余的看起来都清晰且抗锯齿。
【解决方案4】:

user616586 的回答似乎很好。

我看到的问题是线条与形状中心的距离不同,因为其中一条线偏移了 1 px。在大多数情况下,这可能是可以接受的,但有时不是。

另一种选择:

  • 使用 2px 的描边宽度(在形状外部渲染 1px,在形状内部渲染 1px)
  • 将形状应用到自身作为剪辑路径(移除外部 1px 的渲染)

【讨论】:

    【解决方案5】:

    修复:

    <line
      x1="10" y1="1"
      x2="90" y2="1.0001" // hack: horizontal line in SVG not visible in Chrome
      stroke="#FF0000"
      strokeWidth="1"/>
    

    参考:http://code.tonytuan.org/2016/09/svg-horizontal-line-not-visible-in.html

    【讨论】:

      【解决方案6】:

      如果它的 D3js 则尝试将以下样式属性添加到您的 d3 元素:

      .style('shape-rendering','crispEdges')
      

      这会使线条变细。

      如果你想用 CSS 实现同样的效果,那么添加下面的样式:

      .the_Line_CLass{
        shape-rendering: crispEdges;
      }
      

      【讨论】:

        猜你喜欢
        • 2016-04-26
        • 1970-01-01
        • 1970-01-01
        • 2018-12-27
        • 1970-01-01
        • 2018-05-12
        • 2021-06-21
        • 2015-08-21
        • 1970-01-01
        相关资源
        最近更新 更多