Spent two whole days deep diving into native SVG animation technique. I ripped apart an animation I saw in a tutorial, looked under the hood, and put it back together again. I was ultimately able to create my own version. Got quite a ways down the rabbit hole with this one but I did end up learning a lot.
It’s called SMIL and is it dead? Has it died and ben revived?! WTF. It was deprecated and the deprecation was paused. Clearly it is still a thing.
SMIL lets you do complex animations without CSS or JS by using the tag.
“Today, designers and developers can choose to animate the SVG with CSS, SMIL, or JavaScript. If they pick JavaScript, they can further choose among libraries such as GSAP, Snap.svg, SVG.js, and Velocity.js, just to name a few. And, of course, they can also pick the rough path and animate with raw JavaScript. For those avoiding coding, there are other great options, such as SVGator, Keyshape, Lottie, and SpiritApp.”
“- SMIL is now supported in all major browsers: [1]
The overall frame is 602 by 602 with X and Y at 49 and clip content selected. All Tracks in a Group. Group and all items show 15% pass through. “path_0” is the biggest track and is 600 by 600 and has X and Y at 1. No Fill. Radial Center Stroke of 1 with stop at 33% with black color and 100% with black color. The animation line is from center to bottom of the item. 0 for rotation.
“path_1” is the top right chain link. It is 330.15W and 471H and X is 300.85 and Y is 1. It is 15% pass through. No Fill. Radial Center Stroke of 1 with stop at 33% with black color and 100% with black color. The animation line is 1 pixel in from center to bottom of the total frame, same as path_0. 0 for rotation. The center of the stroke touches the center of the bounding box stroke (If there was one).
“path_2” is the bottom right of the chain link. Same as the others except X is 1 and Y is 130. W is 300.15 and H is 471.
All Vectors: Everything is in the top left corner of the overall frame/viewbox of 602 x 602. The center of an ellipse is in the exact top left corner of the viewbox. In the case of the lines the right most part is on the 0, 0 mark. All vectors have constraints of scale and not top left, (not sure if this does anything at all).
Individual Vectors all named “Vector” and from the top are sequenced line, circle, line, circle.
All ellipses denoted by circle graphic: All had a width and height of 2.15 pixels. 6 of the 7 ellipses had no stroke. the one that did have a stroke, the last one, had an inside solid black stroke with a width of 1. The X and Y were all 1.07 and some variation of positives and negatives. We also see the angle being added to the mix. They all had solid fills with no stroke. Ellipses 6 and 7 are black and I do not belive they were used.
1 1.07, -1.07 -90
2 -1.07, -1.07, 0
3 1.07, 1.07, 180
4 1.07, -1.07, -90
5 1.07, -1.07, -90
6 -1.07, -1.07, 0
7 -1.07, -1.07, 0 Has inside black stroke of 1
All Lines denoted by horizontal line graphic: All are 25.75 in Width and 25.78 in Height. The “line” part is the diagonal of a square. The bounding square sits like diamond. Mostly all of them have their right-most part of the line exactly on the top left corner of the viewbox.
The stroke is a center linear black stroke with a width of 1 and the gradient stops are at 0 and 1. There is no fill. The opacity/pass through is 100%.
1 -36.8, -.38, 45
2 -18.21, 18.21, -45
3 -18.23, -18.23, -135
4 -36.44, -.02, 45
5 -36.8, -0.38, 45
6 -18.21, -18.21, -45
7 -18.21, -18.21, -45
Although the angles for all lines may be different they all are at 9 o’clock if the 0, 0 mark of the viewbox was the center of a clock. The Gradient Line is the same.
Trying to recreate the triangle with the line I get the icon but can’t add height to the line?
Using the pen tool and drawing a straight line I still get the same graphics. I can get a square bounding box but the line is not on the diagonal of the square but on one of the sides.
Instead of a single line with a linear stroke gradient can’t you just have a rectangle with a linear fill gradient?
Seeing Exported SVG Code
Need to delete width and height on the SVG tag itself. Delete extra g and clip path if you used an extra artboard in Figma. Delete “rect” element if you used a white background in Figma. The stops only have offset and no other properties. There should be a “stopColor” and “stopOpacity” on both. Stop colors are added if you don’t use black as a color.
<stop offset="0.333333" stopColor="#FBFBFB" />
<stop offset="1" stopColor="white" stopOpacity="0" />
Gradients are already Linked Up with url and that’s great.
If the elements you are animating along the path are self closing you need to convert to having closing tag because we will add “animateMotion” tags inside.
<circle id="circle-16" r="1" fill="#56CCFF"/>
// becomes
<circle id="circle-16" r="1" fill="#56CCFF"></circle>
We have to add the “animateMotion” tags with enclosed “mpaths” ourselves.
<animateMotion dur="8s" begin="4" repeatCount="indefinite" rotate="auto">
<mpath xlinkHref="#path_0" />
</animateMotion>
Although all the layers were named “Vector” they were sequenced in the code, “Vector2, Vector_3”, etc.
The layers get reversed in the code. So tracks that were in the bottom on Figma are now on the top in the code.
My Line looks pretty similar although all lines and ellipses are missing the transform=”translate and rotate” and the paths for the ellipse are now much more complex.
no fill rule or clip rule of even-odd on any of the “tracks”
fixing the gradient stops worked got a line with gradient moving.
Couldn’t really get radial gradient working but it was because the opacity on the track was set so low.
Viewbox dimensions changed. Due to no containing artboard?
My version did not work. Checked the clip mask and exported again. This fixed it.
The tail did not come in. Needed to select the tail and hit enter to begin “edit mode” and then mode so the right edge of the line was exactly on 0, 0.
Also brought in a copy of a layer from the other project. They both appeared in the SVG.
It is now working and I am pumped.
The electron is clipped on the ends since it overflows the viewbox, simple fix.
tail 1 (mine) versus tail 2 (original) looks differently and it is likely due to not having height and a bounding box whereas the original has width and height an bounding box whereas mine only has height. Need to work on this or just use the original.
Curious how you would reverse path?
May not be so easy. I tried a “keypoints/keytimes” solution with no luck. But from looking at the original. You can have a path be a candy-cane-like track that can force a different direction.
Another thing that is interesting about that is on the main track that is a full chain link the “electron” would do the inside loop and then “jump” to the outside loop. For the other candy can parts of the loop this doesn’t happen.
Duplicating the items moving and creating more gradients from existing gradients is pretty easy from inside the code. I wonder about duplicating tracks with the transform and scale properties. Could you use CSS to target and transform a track and have the moving element still traverse it?
Was ultimately able to render a legit custom SVG BG Animation using this technique, (custom paths, elements, etc.).
Used map function and referenced variables in JSX, no issues in TS project either.
{colors.map((color, index) => {
return (
<circle r="2" fill={color}>
<animateMotion dur={dur} begin={0.1 + index * beginMultiplier} repeatCount="indefinite">
<mpath xlinkHref="#F" />
</animateMotion>
</circle>
)
})}