Embedded SVG animateMotion <fill> Attribute Not Working

I'm trying to develop some SVGs with animation embedded into the SVG. I've got the animations running, but I can't seem to use the fill attribute for SVG animations. In fact setting the attribute in the designer does not translate to an HTML fill attribute when I inspect the element.

Here is my Embedded SVG in the designer

[
  {
    "type": "circle",
    "fill": "blue",
    "elements": [
      {
        "type": "animateMotion",
        "fill": "freeze",
        "begin": "0s",
        "dur": "10s",
        "path": "M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z",
        "repeatCount": 1
      }
    ],
    "r": 1,
    "id": "freezeCircle"
  }
]

My blue circle has animateTransform and the fill set to freeze. The animation runs a single time and resets to coords 0,0. When I inspect the HTML of this blue circle it does not have the fill attribute. Here is the HTML:

<circle id="C-0-1-freezeCircle" r="1" style="fill: blue;">
   <animateMotion begin="0s" dur="10s" path="M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z" repeatCount="1"></animateMotion>
</circle>

Can I not expect to be able to use the fill attribute in SVG animations, or any work around?

I see it right there.

1 Like

That is the "style", which fills the element with a color. Not the animateMotion attribute fill, which defines the final state of the animation.

It has been my experience that there are a few attributes which have collisions and do not work as expected or to their full extent.

IA has done their best to account for many of the SVG and CSS elements and attributes, but they are huge specifications and some lesser known things fall through the cracks. This appears to be one of those attributes.

You could potentially do this with CSS but if it needs to be scalable (I'm betting it does) then that would require some JavaScript, which while not impossible, is not the most maintainable solution.

What exactly are you attempting to accomplish with this animation? I don't know of a work around, but perhaps there is a different approach?

dont think soo, the svg animation fill is not comparable css style fill (eventho they ahve the same name)

I have seen this happen sometimes when I embed an SVG and try to animate fill color. In those cases I can usually resolve the problem by deleting things from the embedded SVG while I have a style applied that is doing the fill I am trying to do. I often have to add a style element to the embedded SVG to animate the fill style.

I do this by trial and error. I think it's usually a "paint" property that causes this but it's been a few months since I had to do this so I don't remember exactly.

I basically look at any property upstream from what I'm trying to animate that might be colliding with the property I'm animating and I start deleting (with a backup of course). Undo works pretty well when you're deleting embedded SVG properties also. I usually find elements by deleting stuff and undoing my delete once I know what element that impacted.

Its a different situation here. the fill=freeze is not comparable to css.

Fill freeze is nothing very crucial though, OP will "just" have to change the svg to start/stop in the position he wants instead of freezing it on the location through the animation

1 Like

I am aware.

What I was saying is that you can do the animation potentially with CSS. But if the path needs to be scalable that would require JavaScript.

The OP is not trying to animate the Fill Style of the circle. They are trying to animate the circle along a path, and then have the circle remain at the position of the last frame. However, the animateMotion fill attribute is not generated when with the HTML. The result is that the circle jumps back to its original position.

For reference, the Blue circle is what the OP wants, the Red circle is what they get.

animation

1 Like

This demo is actualy not quite right.
There should be a dot on the poisition red ends. cuz that where the circle actualy starts.
can you paste the code here for me to change? @lrose

i think you just gotta give the circle coorditante matching the end of the animiation, than you dont need freeze

Sure, but the red circle demo, except for being offset by 100px so it doesn't overlap, is exactly what the OP has output by Ignition.

<svg viewBox="0 -10 220 150" xmlns="http://www.w3.org/2000/svg">
  <circle fill="Blue" r=5>
    <animateMotion
      begin="0s"
      dur="10s"
      fill="freeze"
      path="M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z"
      repeatCount="1" />
  </circle>
  <path d="M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z" style="fill-opacity:0;stroke:rgb(0,0,0)">
  </path>
  <circle fill="Red" r=5 cx=100>
    <animateMotion
      begin="0s"
      dur="10s"
      path="M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z"
      repeatCount="1" />
  </circle>
  <path d="M145,0 L168,30 C150,50,155,50,170,75 L167,78 C150,70,140,80,153,97 L150,100 C130,75,130,60,157,68 L135,40 Q160,25,138,0 Z" style="fill-opacity:0;stroke:rgb(0,0,0)" >
  </path>
</svg>

html,
body,
svg {
  height: 100%;
}

Oh I see.

I probably should have loaded it to see exactly what he's having a problem with. I was just glancing over it while waiting for something to load.

I'm going to keep an eye on this thread. I have seen this animation issue with some things I was working on and it looks like a thread that I could learn from.

Ah it seems "just" changing the staring coordinates is not enough you will ahve to change lal the coordinates in the animation accordingly

Which may or may not be possible, depending on what the OP is actually trying to model.

(note this demo used cx=145 instead of the wanted cx45 cuz its drawing 2 circles)

<circle fill="Red" r=5 cx=145>
    <animateMotion
      begin="0s"
      dur="10s"
      path="M0,0 L23,30 C5,50,5,50,25,75 L22,78 C5,70,-5,80,8,97 L5,100 C-15,75,-15,60,12,68 L-10,40 Q15,25,-7,0 Z"
      repeatCount="1" />
  </circle>

use this @nicoli.liedtke

[{
  "type": "circle",
  "fill": "blue",
  "id": "freezeCircle",
  "elements": [
    {
      "type": "animateMotion",
      "begin": "0s",
      "dur": "5s",
      "path": "M0,0 L23,30 C5,50,5,50,25,75 L22,78 C5,70,-5,80,8,97 L5,100 C-15,75,-15,60,12,68 L-10,40 Q15,25,-7,0 Z",
      "repeatCount": 1
    }
  ],
  "r": 1,
  "cx": 45
}]

Bascilly you want to start the animatio with M0,0 and instead move the coordate of the animated object (circle) to the correct starting position (45,0)
And adjust the path coordates acodrinly (in this case just -45x on everything)

edit hm actualy the curves might be slighty off (the middle potion isnt a strait -45x), but if you need such precision you will have to fix it yourself^^
some ref to fix it:

2 Likes

I appreciate all the effort for the workarounds with moving the position of the circle so that it just finishes/resets at wherever the end point of the animation is. Unfortunately for my use case, the paths may change based on different user inputs and the end position may not be the start position.

I'm thinking a workaround still could be some script that calculates the coordinates for the end position based on the input SVG path.

Sharing another workaround that I thought of using keyPoints and keyTimes I can have the animation last for 100,000 seconds rather than 10 seconds while completing the animated path in the first 10 seconds. The animation then would sit at the end point for the remaining 999,990 seconds (~27.7 hours) or even longer.

<svg viewBox="0 -10 220 150" xmlns="http://www.w3.org/2000/svg">
  <circle fill="Blue" r=5>
    <animateMotion
      begin="0s"
      dur="10s"
      fill="freeze"
      path="M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z"
      repeatCount="1" />
  </circle>
  <path d="M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z" style="fill-opacity:0;stroke:rgb(0,0,0)">
  </path>
  <circle fill="Red" r=5 cx=100>
    <animateMotion
      begin="0s"
      dur="100000s"
      keyTimes="0; 0.0001; 1"
      keyPoints="0;1;1"
      path="M45,0 L68,30 C50,50,55,50,70,75 L67,78 C50,70,40,80,53,97 L50,100 C30,75,30,60,57,68 L35,40 Q60,25,38,0 Z"
      repeatCount="1" />
  </circle>
  <path d="M145,0 L168,30 C150,50,155,50,170,75 L167,78 C150,70,140,80,153,97 L150,100 C130,75,130,60,157,68 L135,40 Q160,25,138,0 Z" style="fill-opacity:0;stroke:rgb(0,0,0)" >
  </path>
</svg>