SVG - animateMotion does not work with USE element in Firefox - animation

The following code is extracted from some produced by Tesla Powerwall gateway. The expected behaviour is that a green circle will traverse a path, and this is what Chrome shows. Under Firefox (66.0.5 in my case) it just sits at the left of the screen doing nothing.
Should it work under Firefox, and this is a bug in same, of is there something missing/wrong that I can tell Tesla about in the hope that they might get round to fixing it, even though they say they don't support Firefox?
Thanks, Sylvia.
<html>
<body bgcolor="#000000">
<svg width="250" height="100" viewBox="0 0 250 100">
<defs>
<g id="curvedArrow" stroke-width="1">
<path id="curvedPath" d="M 125 75 l 0 -45 a 5,5 0 0 1 5,-5 L 250 25" fill="none"></path>
<circle cx="0" cy="0" r="7" fill-opacity="0.5" stroke-opacity="0">
<animateMotion dur="1000ms" repeatCount="indefinite">
<mpath xlink:href="#curvedPath"></mpath>
</animateMotion>
</circle>
<circle cx="0" cy="0" r="1.5" stroke-opacity="0">
<animateMotion dur="1000ms" repeatCount="indefinite">
<mpath xlink:href="#curvedPath"></mpath>
</animateMotion>
</circle>
</g>
</defs>
<use id="battery-to-home" xlink:href="#curvedArrow" fill="#00D000" x="3" y="28"></use>
</svg>
</body>
</html>

This is a bug from Firefox, the code is fine.
I opened an issue here, note that it is a regression, so hopefully, it will get fixed quickly.
The gist of the issue is that Firefox quite recently modified <use> element's behavior so that they set their cloned content in the Shadow-DOM of the <use>, like the specs now ask to. Seems that they broke something while doing so.
For the time being, if you ever need a workaround, well... don't use an <use>...
Fixed in today's nightly 68.

Firefox supports (at least in this example) animation via animate elements in use elements but not the animateMotion element. You'll want to tweak the values array to get close to the behavior of the arc in the path, but it's possible.
So something like this works in FF.
<svg width="250" height="100" viewBox="0 0 250 100">
<defs>
<g id="curvedArrow" stroke-width="1">
<path id="curvedPath" d="M 125 75 l 0 -45 a 5,5 0 0 1 5,-5 L 250 25" fill="none"></path>
<circle cx="0" cy="0" r="7" fill-opacity="0.5" stroke-opacity="0">
<animate attributeName="cx" values="125; 125; 250" dur="3s" fill="freeze"/>
<animate attributeName="cy" values="75; 30; 30" dur="3s" fill="freeze"/>
</circle>
<circle cx="0" cy="0" r="1.5" stroke-opacity="0">
<animate attributeName="cx" values="125; 125; 250" dur="3s"/>
<animate attributeName="cy" values="75; 30; 30" dur="3s"/>
</circle>
</g>
</defs>
<use id="battery-to-home" xlink:href="#curvedArrow" fill="#00D000" x="3" y="28"></use>
</svg>

Related

How to animate the rotation of a specific element on its own axis in an SVG (SVG animation tag only)?

I want to animate the two flags, rotate them a little from left to right (or right to left), but I want to do it on their own axis, I don't know how to do it, this is the result I got with the right flag:
(I don't know much but I have been investigating how to make animations with svg, I know that rotate receives the degrees, the x and y position, but I can't understand clearly.
<svg xmlns="http://www.w3.org/2000/svg" width="864" height="864" viewBox="0 0 864 864">
<g id="Grupo_76" data-name="Grupo 76" transform="translate(-682 -189)">
<g id="right-flag" transform="translate(-283.11 -185.563) rotate(11)">
<!-- How can I rotate it on its own axis -->
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0"
to="360"
dur="9s"
repeatCount="indefinite"
/>
<path id="Trazado_128" data-name="Trazado 128" d="M5074,508.573v427.9" transform="translate(-3544.956 -60.656)"
fill="none" stroke="#cab9a9" stroke-width="8" />
<g id="Grupo_53" data-name="Grupo 53" transform="translate(1522 262)">
<rect id="Rectángulo_1" data-name="Rectángulo 1" width="319.344" height="196.249" transform="translate(0 0)"
fill="#999" />
<rect id="Rectángulo_2" data-name="Rectángulo 2" width="319.344" height="196.249" transform="translate(0 0)"
fill="rgba(92,92,92,0.77)" />
</g>
</g>
<g id="left-flag" transform="matrix(0.978, -0.208, 0.208, 0.978, -779.086, 487.436)">
<path id="Trazado_128-2" data-name="Trazado 128" d="M5074,508.573V936.468"
transform="translate(-3239.704 -60.658)" fill="none" stroke="#cab9a9" stroke-width="8" />
<g id="Grupo_53-2" data-name="Grupo 53" transform="translate(1522 262)">
<rect id="Rectángulo_1-2" data-name="Rectángulo 1" width="312.46" height="192.018" transform="translate(0 0)"
fill="rgba(208,191,184,0.35)" />
<rect id="Rectángulo_2-2" data-name="Rectángulo 2" width="312.46" height="192.018" transform="translate(0 0)"
fill="rgba(53,53,53,0.77)" />
</g>
</g>
<circle id="Elipse_1" data-name="Elipse 1" cx="432" cy="432" r="432" transform="translate(682 189)"
fill="rgba(208,191,184,0.35)" opacity="0.83" />
</g>
</svg>
The file was exported from adobe XD and I add the animation tag.
I always suggest that when you are creating svgs to use on the web you better create them in Inkscape as it is a Native svg editor and produces a clearer and cleanest code.
Now the good stuff:
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="864" height="864" viewBox="0 0 864 864" id="svg2" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="aa.svg">
<path style="opacity:0.82999998" d="M 864,432 A 432,432 0 0 1 432,864 432,432 0 0 1 0,432 432,432 0 0 1 432,0 432,432 0 0 1 864,432 Z" id="Elipse_1"/>
<g inkscape:transform-center-x="-148.56934" inkscape:transform-center-y="42.976369">
<path style="fill:none;stroke:#cab9a9;stroke-width:8" d="M 450.37451,356.87985 368.72733,776.91812"/>
<path d="M 478.9346,173.03462 792.41135,233.96833 754.96528,426.61167 441.48853,365.67796 Z"/>
<animateTransform attributeName="transform" type="rotate" from="-5 432 432" to="5 432 432" dur="0.5s" repeatCount="indefinite" />
</g>
<g inkscape:transform-center-y="42.976369" inkscape:transform-center-x="148.56932">
<path style="fill:none;stroke:#cab9a9;stroke-width:8" d="m 413.62551,356.87985 81.64718,420.03827"/>
<path d="M 385.06542,173.03462 71.588665,233.96833 109.03474,426.61167 422.51149,365.67796 Z"/>
<animateTransform attributeName="transform" type="rotate" from="5 432 432" to="-5 432 432" dur="0.5s" repeatCount="indefinite" />
</g>
</svg>
Basically you have to set each flag's group rotation center to the background circle's rotation center. In Inkscape it is an easy task and I think that Illustrator should make it easy too.
In this case the flag's rotation center is inkscape:transform-center-x="-148.56934" inkscape:transform-center-y="42.976369", what basically means that the original flag's group rotation center is been translated -148.56934px on the x axis and 42.976369px on the y axis to make it coincide with the circle's rotation center.
Then let's add the animation. As the circle's with and height coincide with the viewbox width and height, which is 864px, you just have to calculate the half, in this case it's 432px, which places it at 432px in both axis. This is the animation itself: <animateTransform attributeName="transform" type="rotate" from="-5 432 432" to="5 432 432" dur="0.5s" repeatCount="indefinite" /> EXPLANATION: You set 432 as the flag's animation rotating center in both axis on the from, stablish -5 degrees and 5 degrees with the same rotation center to the to, set a duration in seconds and to repeatCount you can stablish a number to state the number of repetitions or indefinite to loop forever. The result is that the flag will rotate in its center from -5 degrees to 5 degrees in 0.5 seconds and will do it forever.
For the other flag just copy and paste the same animation but interchange the values of the rotation degrees to make the second flag rotate in the other direction.
And that's it, hope you understood. If any doubt, just add a comment.

Animating straight SVG path into curved?

I have two SVG's, both made out of 3 lines.
In the first SVG the lines are straight:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1000 521.8" style="enable-background:new 0 0 1000 521.8;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:none;stroke:#000000;stroke-width:106;stroke-miterlimit:10;}
</style>
<g>
<path class="st0" d="M0,261.9h77c27.5,0,72.5,0,100,0h823"/>
<path class="st1" d="M0,261.9h77c27.5,0,72.5,0,100,0h823"/>
</g>
<g>
<path class="st0" d="M0,463.9h77c27.5,0,72.5,0,100,0h823"/>
<path class="st1" d="M0,463.9h77c27.5,0,72.5,0,100,0h823"/>
</g>
<g>
<path class="st1" d="M0,59.9h77c27.5,0,72.5,0,100,0h823"/>
</g>
</svg>
and in the second one I have the same three lines but just braided together:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1000 521.8" style="enable-background:new 0 0 1000 521.8;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:none;stroke:#000000;stroke-width:106;stroke-miterlimit:10;}
</style>
<g>
<path class="st0" d="M0,261.9h77c27.5,0,71.7-5.9,98.3-13.1L825.7,72.9c26.5-7.2,70.8-13.1,98.3-13.1h76"/>
<path class="st1" d="M0,261.9h77c27.5,0,71.7-5.9,98.3-13.1L825.7,72.9c26.5-7.2,70.8-13.1,98.3-13.1h76"/>
</g>
<g>
<path class="st0" d="M0,463.9h77c27.5,0,71.7-5.9,98.3-13.1l650.5-175.9c26.5-7.2,70.8-13.1,98.3-13.1h76"/>
<path class="st1" d="M0,463.9h77c27.5,0,71.7-5.9,98.3-13.1l650.5-175.9c26.5-7.2,70.8-13.1,98.3-13.1h76"/>
</g>
<g>
<path class="st1" d="M0,59.9h77c27.5,0,69.8,10.7,94,23.8l660,356.5c24.2,13.1,66.5,23.8,94,23.8h75"/>
</g>
</svg>
I'm wondering if there is some kind of transition feature? Or how else it would work
Yes it is possible. There are plenty of examples online (and on this site). Search for "svg path tweening" or "svg path morphing".
The important rule to know is that the original line and the final line have to have the same set of path commands, in the same order. At the moment your original lines have "Mhch", but your braided lines are "MhcLch".
Original: M 0,261.9
h 77
c 27.5,0,72.5,0,100,0
h 823
Final: M 0,261.9
h 77
c 27.5,0,71.7-5.9,98.3-13.1
L 825.7,72.9
c 26.5-7.2,70.8-13.1,98.3-13.1
h 76
In order for animation of the d attribute to work. You'll need to change the original paths so that the are also "MhcLch".

animation not animating instead jumping to end

I am trying to use the SVG animate tag to change the path from a half fill to a complete fill
<svg class="background-gradient" viewBox="0 0 100 100" preserveAspectRatio="none">
<defs>
<linearGradient id="grad">
<stop offset="0%" stop-color="rgba(82,181,244,.1)" stop-opacity="1"></stop>
<stop offset="100%" stop-color="rgba(70,215,255,.7)" stop-opacity="1"></stop>
</linearGradient>
</defs>
<path id="scroll-path" d="M0 0 H100 v 100" fill="url(#grad)">
<animate attributeName="d" from="M0 0 H100 v 100" to="M0 0 H100 L100 100 L0 100" dur="1s" repeatCount="indefinite" />
</path>
</svg>
Currently it just jumps from the beginning to the end of the animation and does not show the smooth fill I was hoping for in between.
Any ideas?
For an animation to be smooth the path must have the same number and types of commands.
Your first path has 3 commands M H v
Your second path has 4 commands M H L L
You'll need to write the first path using 2 L commands instead of the v or the second as a v instead of the two L commands.

Ellipse not working properly in SVG masks

While I am absolutely sure this is something I'm missing, I have a problem with SVG masks.
I have an SVG of a simple padlock icon (link to JSFiddle below) that worked fine before, but now the ellipse part of the keyhole is not working. I have the fill set to black in the mask.
I have tried a bunch of things, including changing the entire bottom part to a path (it didn't look right), changing the mask to a clip path (opposite of what I wanted) and even swapping the ellipse and the polygon. Nothing worked.
Here's a JSFiddle of the icon.
Code:
<svg viewBox="0 0 32 32" version="1.1" width="256" height="256" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="lock-mask">
<rect x="0" y="0" width="32" height="32" fill="white" />
<ellipse cx="16" cy="19" rx="3" ry="2" fill="black" />
<polygon points="15,20 14,26 18,26 17,20" fill="black" />
</mask>
</defs>
<rect x="2" y="13" width="28" height="16" rx="2" ry="2" mask="url(#lock-mask)" />
<path d="M6.5 14 V 9 A 10 6 0 0 1 25.5 9 V 14 H 22.5 V 9 A 8 5 0 0 0 9.5 9 V 14 Z" />
</svg>

SVG animations not chaining correctly

I have the following svg and I am trying to animate the shape.
<svg class="svg" viewBox="0 0 100 100">
<path fill="white">
<animate id="close" begin="0s;open.end" attributeName="d" dur="1s"
from="..." to="..." />
<animate id="open" begin="close.end" attributeName="d" dur="1s"
from="..." to="...0" />
</path>
</svg>
The problem I am facing is that the 1st animation (#close) only happens once at the start then never again. The second animation (#open) repeats as normal.
Here's a codepen with my code and simpler animation I based mine off of (which works correctly)
http://codepen.io/dogoku/pen/yxKjs
Thanks for any help
One way would be to put it in the same animation
<animate id="close" begin="0s" repeatCount="indefinite" attributeName="d" dur="2s"
values="M 0,0 L 100,0 100,50 100,100 0,100 0,50; M 0,50 L 100,50 75,50 100,
50 0,50 25,50; M 0,50 L 100,50 75,50 100,50 0,50 25,50; M 0,0 L 100,0 100,
50 100,100 0,100 0,50" />

Resources