How do I build a generator for SVG loaders with SaaS and SMIL options?

While learning Vue.js, I started creating free web tools, including SVG Search, with the goal of learning something about both! Let’s take a look at one of these tools: a generator that generates SVG loaders and lets you choose between SMIL or Sass animation, different styles, colors, shapes and effects. It even lets you paste it into a custom path or text, and then download the final SVG, copy the code, or open a demo on the code pane.

How did it start

Three coincidences forced me to build a generator for SVG loaders.

Coincidence 1: Sarah Dresner’s book.

I first read about Sass Lopez in Sarah Dresner. SVG animations. They show how to tweak animations with SaaS function (as in Chapter 6, “Animating Data Visualization”).

I was impressed with this chapter and the possibilities of Sass Lopez.

Coincidence 2: A GIF

At that point in my life, I was asked to copy a “loader” element, similar to Apple’s old classic.

A round segment spinner where each segment is blurred one after the other to create a circular effect.
This is a loader makeup that I was asked to make.

I cited Sarah’s example to make that happen. This is the SaaS loop code I landed on:

@for $i from 1 to 12 {
  .loader:nth-of-type(#{$i}) {
    animation: 1s $i * 0.08s opacityLoader infinite;
  }
}
@keyframes opacityLoader {
 to { opacity: 0; }
}

It defines a variable for a number (i1 to 12 which increases the animation delay with each. :nth-child This element was the best use case to animate as many elements as I wanted with just two lines of sauce, saving me the CSS declaration for every delay I needed. It’s the same animation, but to show the difference, Vanilla CSS reads:

.loader:nth-of-type(1) {
  animation: 1s 0.08s opacityLoader infinite;
}
.loader:nth-of-type(2) {
  animation: 1s 0.16s opacityLoader infinite;
}

/* ... */

.loader:nth-of-type(12) {
  animation: 1s 0.96s opacityLoader infinite;
}
@keyframes opacityLoader {
  to { opacity: 0; }
}

Coincidence 3: An idea.

As these things went through my mind, I had an idea for one. Gallery Loaders, where each loader is made from the same sauce loop. I always strive to find these kinds of things online, so I thought it might be useful for others, not to mention myself.

I had made this kind of thing before as a personal project, so I stopped making a loader generator. Let me know if you find bugs in it!

One loader, two outputs.

I was blocked by my developer skills while building a generator that produces the correct SaaS output. I decided to try another animation approach with SMIL animation, and that’s what I decided to use.

But then I got some help (thanks, Ekrov!) And finally got my mother-in-law to work.

So, I finished adding. both of them Generator options I found it a challenge to get both languages ​​back to the same result. In fact, they sometimes do. Different Results

SMIL vs. CSS / SAS.

I learned a little bit about SMIL and CSS / Sass animations along the way. Here are some key points that helped me build the generator:

  • SMIL does not rely on any external resources. It activates SVG through presentation attributes directly in SVG markup. This is something that neither CSS nor SAS can do.
  • SMIL animation is saved when embedded as an SVG image or as a background image. It is possible to add a CSS. <style> Block directly inside the SVG, but not with the sauce, of course. This is why the generator has the option to download the original SVG file when selecting the SMIL option.
  • The SMIL animation looks a bit more fluid. I can’t find the reason, although it was related to GPU acceleration, but it looks like they both use the same motion engine.
Two spinners, one left and one right.  They are both red and consist of circles that disappear one after the other as an animated GIF.
SMIL (left) and Saas (right)

You may notice a difference. Chain Animations between the two languages:

  • I used additive="sum" Adding one animated image after another to SMIL. This ensures that each new animation effect avoids subverting the previous animation.
  • That said, in CSS / Sass, W3C indicates that. [when] Multiple animations are trying to edit the same property, then the animation closest to the end of the name list wins.

This is why the order in which the animation is applied can change the SaaS output.

Working with changes.

Working with loader style changes was a big problem. I applied. transform: rotate Inline in each shape because it’s a simple way to circle them together and point the face to the center.

<svg>
  <!-- etc. -->
  <use class="loader" xlink:href="#loader" transform="rotate(0 50 50)" />
  <use class="loader" xlink:href="#loader" transform="rotate(30 50 50)" />
  <use class="loader" xlink:href="#loader" transform="rotate(60 50 50)" />
  <!-- etc. -->
</svg>

I can announce that type With SMIL <animateTransform> (E.g. scale Or translate) To include this specific change in the actual change of each shape:

<animateTransform
  attributeName="transform"
  type="translate"
  additive="sum"
  dur="1s"
  :begin="`${i * 0.08}s`"
  repeatCount="indefinite"
  from="0 0"
  to="10"
/>

But instead, transform CSS was subverting any previous changes to online SVG. In other words, the original position was reset to 0 and the result was very different from the output of SMIL. This means that the animations look the same no matter what.

Same two red spinners as before but with different results.  The SMIL version on the left appears to work as expected but the SaaS on the right does not move in a circle as it should.

The solution to make SAS look like SMIL (not pretty) was to keep each shape within a group (<g>) Apply inline rotation to elements, and groups, and animation to shapes. That way, the inline transform is not affected by animation.

<svg>
  <!-- etc. -->
  <g class="loader" transform="rotate(0 50 50)">
    <use xlink:href="#loader" />
  </g>
  <g class="loader" transform="rotate(30 50 50)">
    <use xlink:href="#loader" />
  </g>
  <!-- etc. -->
</svg>

Now the result of both languages ​​is very similar.

The technology I used.

I used Vue.js and Nuxt.js. Both have excellent documentation, but there are more specific reasons why I choose them.

I like Vue for a lot of reasons:

  • View combines HTML, CSS, and JavaScript as a “single file component” where all the code resides in a single file that is easy to work with.
  • The way Wave triggers and activates HTML or SVG attributes is very intuitive.
  • HTML and SVG do not require any additional changes (such as making the code compatible with JSX).

As far as Nuxt goes:

  • It has a fast boiler plate that helps you focus on development rather than configuration.
  • Automatic routing and it supports auto import components.
  • This is a good project structure with pages, components and layouts.
  • Meta tags make SEO easy to optimize.

Let’s look at some examples of loaders.

What I do like about the end result is that the Generator One truck is not a pony. There is no way to use it. Since it outputs both SMIL and CSS / Sass, there are several ways to integrate the loader into your project.

Download SMIL SVG and use it as a background image in CSS.

As I mentioned earlier, SMIL properties are protected when SVG is used as a background image file. So, just download SVG from the generator, upload it to your server, and reference it as a background image in CSS.

Similarly, we can use SVG as a pseudo-element background image.

Drop SVG straight into HTML markup.

SVG should not have a background image. It’s just code, after all. This means we can just leave the code from the generator in our markup and let SMIL do its job.

Use the sauce loop on the inline SVG.

This is what I was originally encouraged to do, but encountered some obstacles. Instead of writing a CSS declaration for each animation, we can use the generator-generated sauce loop. Loop target a .loader Class that already applies to output SVG. So, once the sauce is set in CSS, we get a nice rotating animation.

I’m still working on it.

My favorite part of the generator is the custom shape option where you can add text, emojis or any SVG element to the mix.

Same circle spinner but using custom SVG shapes: one word, one pop emoji, and bright pink and orange star.
Custom text, emoji, and SVG.

All I want to do is add a third option to just one element for style where you work with your SVG element. Thus, it allows less production, while easier to operate.

The challenge with this project is working with custom values ​​for many things, such as duration, direction, distance and degree. Personally, I am becoming more aware of another challenge view because I want to go back and clean up this dirty code. That said, the project is open source, and bridge applications are welcome! Feel free to send suggestions, feedback, or even WAV course recommendations, especially regarding building an SVG or generator.

It all started with a sauce loop that I read in a book. It’s not the cleanest code in the world, but I’m blown away by the power of SMIL animations. I highly recommend Sarah Sweden’s guide to dive deeper into what SMIL is capable of doing.

This is a good reason if you are interested in protecting SMIL. There was a time when Chrome was completely deprecating SMIL (see opening note in MDN). But this obsolescence has been suspended and (apparently) not talked about for a while.

Can I use SMIL?

Desktop

Chrome Firefox IE the edge Safari
5. 4. no 79 6.

Mobile / tablet.

Android Chrome. Android Firefox. Android iOS Safari.
92. 90 3. 6.0-6.1.

Leave a Reply

Your email address will not be published.