Why is SVG stroke-width : 1 making lines transparent?

故事扮演 提交于 2019-12-20 08:36:02

问题


I'm creating stock charts with svg and I'm having a problem when I set the stroke-width of my path elements to 1. Instead of making the lines more narrow, it just makes it the same size as stroke-width:2 but slightly transparent. I can't post an image of it though because I don't have enough reputation points...

My svg tag looks like so:

<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>

And I'm adding path elements dynamically using 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);

I left out the value for the path's d attribute as it was kind of long. Also, color is a string variable that is determined before hand as either "green", "red", or "black".

Is there something wrong in my code that is causing this or is it a different issue?


回答1:


This is probably due to the anti-aliasing applied in most SVG implementations. When the line width goes near or below 1, antialiasing makes it so that half-covered pixels are rendered partially opaque. With the default transforms and viewport in place, your one-pixel line probably sits exactly on the border between two physical pixels, so they're each half covered, leading to an overall 50% transparency. With a black line on a white background, this yields a 50% gray.




回答2:


If the lines are straight horizontal or vertical just place the lines at half a pixel off, like x="1.5px".

Another way is to apply some CSS to the lines:

.thelines{
    shape-rendering:crispEdges
}

The spec chapter on shape-rendering property.




回答3:


maybe a little late, but the real reason for this is that when you draw on a grid-line which is infinite small the line with stroke-width 1 is rendered as a half pixel left and right (or above/below) from the grid line. I solved this by adding a group around all objects with transform 0.5,0.5 so everything is shifted a half grid line.

So everything you draw is now exactly in the middle between 2 grid-lines. A line with stroke width 1 wil have now half a pixel to the left and half a pixel to the left, but both from the middle. Resulting in a line with exactly the thickness you wanted: 1 pixel...

Example:

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



回答4:


If its D3js then try adding below style attribute to your d3 element:

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

This makes the line thinner.

If you want to achieve the same with CSS, then add the below style:

.the_Line_CLass{
  shape-rendering: crispEdges;
}



回答5:


The answer by user616586 seems fine.

The problem i see is that the lines don't have the same distance from the center of the shape because one of them is offset by 1 px. In most situations thats probably acceptable, but sometimes it isn't.

Another option:

  • use a stroke-width of 2px (having 1px rendered outside and 1px rendered inside of the shape)
  • apply the shape to itself as a clip-path (removes the rendering of the outer 1px)



回答6:


fix:

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

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



来源:https://stackoverflow.com/questions/7401369/why-is-svg-stroke-width-1-making-lines-transparent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!