Strikers
Strikers

Reputation: 4776

colour issues when 2 SVG lines are overlapping

while playing with lines came across this issue.

When 2 svg lines of thickness 1px or 1.5px overlap the colour of the lines is becoming dark even if bothare given the same color

var myLine = lineGraph.append("svg:line") .attr("x1", 40) .attr("y1", 50) .attr("x2", 450) .attr("y2", 50) .style("stroke", "rgb(6,120,155)") .style("stroke-width", 1);

The same issue is not happening when the thickness of the line is greater than 2.

here is the example which I'v worked out

Upvotes: 2

Views: 2320

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101956

This will generally happen with all odd widths, but it will be less noticeable than with a width of 1.

The reason is because you are drawing your 1 pixel line exactly on a pixel boundary. This means that because of antialiasing, the renderer is drawing 50% of the line on one row of pixels, and 50% on the row of pixels below.

You can't actually draw half a pixel, so what it is doing is draw the pixel at 50% opacity on each line.

+---+---+---+
|50%|50%|50%|
+---+---+---+  ...etc...
|50%|50%|50%|
+---+---+---+

For the first line it is drawing a mix of 50% white (the background) and 50% blue.

For the overdrawn line, it is drawing a mix of 50% blue-white mix and 50% blue. Resulting in a darker blue.

The solution

Make sure your one pixel lines are drawn at the half pixel point so that the line is not split over two rows of pixels. For example:

var myLine = lineGraph.append("svg:line")
    .attr("x1", 40)
    .attr("y1", 100.5)
    .attr("x2", 450)
    .attr("y2", 100.5)
    .style("stroke", "rgb(6,120,155)")
    .style("stroke-width", 1);

Demo here

Obviously, for vertical lines, you would need to add 0.5 to the X coordinate instead.

If, for some reason, you can't do that, then an alternative solution is to set the shape-rendering attribute to crispEdges.

var myLine = lineGraph.append("svg:line")
    .attr("x1", 40)
    .attr("y1", 100)
    .attr("x2", 450)
    .attr("y2", 100)
    .attr('shape-rendering', 'crispEdges')
    .style("stroke", "rgb(6,120,155)")
    .style("stroke-width", 1);

Demo here

But beware, this turns off anti-aliasing for the line, so if it isn't perfectly horizontal or vertical, it will look bad.

Upvotes: 2

Related Questions