Animated glowing SVG line drawing not working across browsers

1k views Asked by At

I'm trying to create an animation that uses SVG filters and the stroke-dasharray approach to create a progressively drawn "glowing" line effect. After quite a bit of research I was able to put together something that sort of works:

JSFiddle (the SVG paths make this too big for an SO snippet)

My attempted solution uses two sets of coordinates, the first being the lines themselves, followed by the same paths with the SVG glow filter applied. For the most part, the animation looks ok and close to what I'd like as far as the appearance.

The problem is that the animation is obviously resource intensive and is super clunky in FireFox and Safari. How can I achieve this same animated "glowing line" effect while getting it to run smoothly in those browsers? Is there a way around the performance hit with such a large set of coordinates, or is there a better way to achieve the glow effect without using two sets of paths?

Also for what it's worth...I'm not using an image of R2-D2, but the actual line drawing is comprised of a similarly large set of coords, so this makes for a representative example.

I'm new to working with animated SVGs, and I realize my approach here may be a bit obtuse. Any help is very much appreciated.

2

There are 2 answers

0
ccprog On BEST ANSWER

There are quite a few optimisations you can do to tweak performance. The base pattern you should use looks like this:

<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
  <g id="lines">
    <!--one set of paths, no classes, no attributes besides d-->
    <path d="..." />
  </g>
  <filter id="glow">
    <feGaussianBlur stdDeviation="4 4" result="glow"/>
    <feComponentTransfer>
      <feFuncA type="linear" slope="8"/>
    </feComponentTransfer>
  </filter>
</defs>
  <use xlink:href="#lines" class="line" />
  <use xlink:href="#lines" class="glow" filter="url(#glow)" />
</svg>

CSS:

body {
  background: black;
}

#lines {
  stroke-dasharray: 3400;
  stroke-dashoffset: 3400;
  animation: draw 16s forwards ease;
}

.line {
  stroke: white;
  stroke-width: 1;
}

.glow {
  stroke: lime;
  stroke-width: .7;
  fill: none;
  opacity: .5;
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

Key points to note

  • only one set of paths
  • only one animation, applied to the <g> arround the paths
  • styles and filter applied to <use>
  • simpler filter with only 2 computation steps instead of 9
2
Michael Mullany On

Well, what you're trying to do is avoid all those recalculated filters. So what you can do is to draw the glowing drawing first, then draw a 4pxish black stroked copy of top of it, and then reverse-animate the over-drawing - thereby revealing the original.