0

I'm trying to implement a "marching ants" style animated selection box using svg. The scheme of animating the border's dash pattern seems to work great, except for some reason I can't get true black/true white for the colors.

(Using ff 68.0.2 64-bit, in case that matters)

<svg height="110" width="200">
    <circle cx="100" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /> <!-- for sample overlay -->
  <g fill="none" stroke="#000000" stroke-width="1">
    <path id="solid" stroke-dasharray="" d="M5 40 l215 0" />
  </g>
  <g fill="none" stroke="#ffffff" stroke-width="1">
    <path  stroke-dasharray="4,8,4,0" d="M5 40 l215 0" />
  </g>
  <rect x="1" y="1" width="100" height="100" style="fill:rgba(0,0,0,0);stroke-width:1;stroke:rgb(0,0,0)"/>
  <rect x="1" y="1" id="ants" width="100" height="100" stroke-dasharray="4,8,4,0"  style="fill:rgba(0,0,0,0);stroke-width:1;stroke:#ffffff"/>
  Sorry, your browser does not support inline SVG.
</svg>

JsFiddle

  • 1
    This answer may help: https://stackoverflow.com/questions/23376308/avoiding-lines-between-adjecent-svg-rectangles/23376793#23376793 – Paul LeBeau Aug 28 '19 at 20:12
  • Paul's answer did solve the problem, but has its limitations. Besides having to be 2 pixels wide, there is also a gray halo around curves. If this is acceptable to a person, this is a good solution. I think I prefer living with the aliasing in the answer below. – TheHeadlessSourceMan Aug 28 '19 at 22:40
  • You can do it with 1px strokes. https://jsfiddle.net/6oarhuxj/ – Paul LeBeau Aug 29 '19 at 09:21

1 Answers1

0

After fiddling with this some more I discovered that when increasing the stroke width the colors get closer to desired.

Turns out anti-aliasing is being stupid. If I turn on shape-rendering="crispEdges" then the colors work as expected.

Unfortunately it also leaves the jaggies, which is, of course, why anti-alising exists.

If this is "the solution", I guess I'll settle for it, but if somebody knows how to make anti-aliasing clean up the line edges without dulling the colors so badly, that would be ideal.

UPDATE: I'm going to go ahead and accept this. Once animated, it isn't all that bad.

    @keyframes marchingAnts {
        0% { stroke-dashoffset: 0 }
        100% { stroke-dashoffset: 50 }
    }
    .ants, .antsBackground {
        stroke-width: 1;
        fill: none;
        shape-rendering: crispEdges;
    }
    .ants {
        stroke: #ffffff;
        animation: marchingAnts 2400ms linear infinite;
        stroke-dasharray: 5,5,0,0;
    }
    .antsBackground {
        stroke: #000000;
    }

Here's a JsFiddle of that with css animation, and for comparison, the 2-pixel width solution from the comments on the OP as well.