Wait, no. THIS is how to make an SVG fire effect
leimapapa

leimapapa @leimapapa

About: Hugs not shrugs

Joined:
Jun 15, 2022

Wait, no. THIS is how to make an SVG fire effect

Publish Date: Jul 2
0 0

made fire

I wrote an article explaining how to achieve a fire effect and it got somewhat… complex.

Any time that you have to have some advanced knowledge of an SVG path’s d attribute to make an effect, you’re in baaad territory. That is to say, tedious, boring territory.

confused
(shapes + turbulence + displacement) = (headache + despair + violent rage)

However, fear not! I, your SVG fire Sherpa am here at last with a way to avoid all that.

In the last article, I explained that applying a turbulence filter, animating a group containing the shape you want to be on fire up, while you animate the shape itself down creates a pretty solid fire effect.

This is fine and perfectly easy for shapes like circles where you animate the cy up by 5000 and the y offset of the group down by 5000 using .

However, it gets super silly once anything more complex like , , or god forbid, s get involved.

In the case of s, you have to animate the d attribute itself, which requires all of the points to be relative to one another and not absolute (e.g. M0 0 h 100and not M 0 0 H 100) which requires converting the path itself using an external tool. Barf.

All this trouble stems from the fact that having 2 components offset one another and the shape does not appear to move at all.

So what we need is to animate the y position of a containing element down, and then use the on the group containing that element to animate it up.

So why not just have 2 group components, animate the y of one group up and the group inside use down?

Good question. You’re so smart. The fact of the matter is that the element does not have a y attribute attached to it representing its y position in the svg... All is lost!

its over
It’s never been more over than it is right now

Well not so fast Doomer McDoomerton, there certainly has to be another element that has a y attribute that we can put our set-me-on-fire path (or groups of paths) inside of so we don’t have to animate their paths.

Enter ! Our savior!

we back
we are so back!

The element lets you define a piece of SVG content once , and then reuse it multiple times elsewhere in your SVG document using the element. And guess what attribute the has…

Ding ding ding! That’s correct, it has a y attribute. Therefore, any thing we want to include inside of a can be animated using the following format:

<use href="mySymbol">
  <animate attributeName="y" 
    values="0; 5000" 
    dur="100s" begin="0s" 
    repeatCount="indefinite" additive="sum" />
</use>
Enter fullscreen mode Exit fullscreen mode

Then, with a simple offset in the opposite direction, the fire effect is complete:

<g filter="url(#fireTurbulence)">
  <use href="mySymbol">
    <animate attributeName="y" 
      values="0; 5000" 
      dur="100s" begin="0s" 
      repeatCount="indefinite" additive="sum" />
  </use>
  <animateTransform attributeName="transform" 
    attributeType="XML" type="translate" 
    values="0 0; 0 -5000" 
    dur="100s" begin="0s" 
    repeatCount="indefinite" additive="sum" />
</g>
Enter fullscreen mode Exit fullscreen mode

And now the symbol itself can include any number of erstwhile impossibly-complex shapes to which we want to add a fire effect. Like so:

<symbol id="star" viewBox="0 0 100 100">
  <polygon 
    points="50,0 61,35 98,35 68,57 79,91 50,70 21,91 32,57 2,35 39,35"
    fill="gold" stroke="black" />
</symbol>
Enter fullscreen mode Exit fullscreen mode

giving us finally:

<symbol id="star" viewBox="0 0 100 100">
  <polygon 
    points="50,0 61,35 98,35 68,57 79,91 50,70 21,91 32,57 2,35 39,35"
    fill="gold" stroke="black" />
</symbol>
<g filter="url(#fireTurbulence)">
  <use href="mySymbol">
    <animate attributeName="y" 
      values="0; 5000" 
      dur="100s" begin="0s" 
      repeatCount="indefinite" additive="sum" />
  </use>
  <animateTransform attributeName="transform" 
    attributeType="XML" type="translate" 
    values="0 0; 0 -5000" 
    dur="100s" begin="0s" 
    repeatCount="indefinite" additive="sum" />
</g>
Enter fullscreen mode Exit fullscreen mode

Which, when we apply our fire turbulence filter (and a cool fire gradient instead of just gold fill), gives us something like this:

star fire
Star Fire!

One quick note on the fire filter. When turbulence and displacement are applied, it will shift the shape to which you apply your filter down and to the right by ~25–33% of the displacement scale. There’s complex math involved in how the randomness of the turbulence is generated, but I won’t get into it here.

For now, here is the turbulence filter used for my fire effect:

<filter id="fireTurbulence" x="-100%" y="-100%" width="300%" height="300%">
  <feTurbulence type="turbulence" seed="69"
    baseFrequency="0.05" numOctaves="2.5" 
    result="turbulence"/>
  <feDisplacementMap 
    in="SourceGraphic" in2="turbulence" 
    scale="30" 
    result="displacement" />
  <!-- feOffset counteracts the scale of the displacement map -->
  <!-- this will re-center the shape to which it is applied -->
  <feOffset in="displacement" 
    dx="-10" dy="-10" 
    result="offset" />
</filter>
Enter fullscreen mode Exit fullscreen mode

Aaaaand here’s the full code for our fiery star. Nestled safe inside of the to which the fire filter is applied:

<svg viewBox="0 0 100 100">
 <defs>
  <filter id="fireTurbulence" x="-100%" y="-100%" width="300%" height="300%">
   <feTurbulence type="turbulence" seed="69" baseFrequency="0.05" numOctaves="2.5" result="turbulence" />
   <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="30" result="displacement" />
   <feOffset in="displacement" dx="-10" dy="-10" result="offset" />
  </filter>
  <radialGradient id="fireGrad" cx="50%" cy="80%" fx="50%">
   <stop offset="0%" stop-color="#aaf" />
   <stop offset="20%" stop-color="#fff" />
   <stop offset="60%" stop-color="gold" />
   <stop offset="100%" stop-color="darkorange" />
  </radialGradient>
  <symbol id="star" viewBox="0 0 100 100">
   <polygon points="50,0 61,35 98,35 68,57 79,91 50,70 21,91 32,57 2,35 39,35" fill="url(#fireGrad)" />
  </symbol>
 </defs>
 <g filter="url(#fireTurbulence)">
  <use href="#star">
   <animate attributeName="y" values="0; 5000" dur="100s" begin="0s" repeatCount="indefinite" additive="sum" />
  </use>
  <animateTransform attributeName="transform" attributeType="XML" type="translate" values="0 0; 0 -5000" dur="100s" begin="0s" repeatCount="indefinite" additive="sum" />
 </g>
</svg>
Enter fullscreen mode Exit fullscreen mode

This opens up all sorts of possibilities beyond just fire. You could, for example, generate turbulence against lines so that they look like electricity:

Or you could scale the values way back and apply them in the x direction to create a waving flag effect:

The world is your fiery oyster.

Now go forth armed with this knowledge and set the world on fire! Metaphorically of course…

set fires
Legally: “in Minecraft”

Comments 0 total

    Add comment