SVG Animation puts back after completed [duplicate] - animation

This question already has an answer here:
XML SVG - persist the end state of an animation
(1 answer)
Closed 1 year ago.
I just made a simple SVG animation using the tag "animate" inside the SVG tag group. It works nicely BUT right after the animation is completed, it goes back to the beginning, to the initial frame, then stops.
How should I modify my code inside the animate tag in order to keep the animation still in the last frame?
Thanks,

How should I modify my code inside the animate tag in order to keep
the animation still in the last frame?
To achieve this use the fill =" freeze " attribute
Below is an example without using fill =" freeze "
As in your description - the figure returns to its original state
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="200" viewBox="0 0 400 200" style="border:1px solid gray;" >
<circle cx="30" cy="100" r="30" fill="purple" >
<animate attributeName="cx" begin="svg1.click" dur="3s" values="30;300" />
</circle>
</svg>
Second example using fill =" freeze "
After the animation ends, the shape will remain in the last frame of the animation.
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="200" viewBox="0 0 400 200" style="border:1px solid gray;" >
<circle cx="30" cy="100" r="30" fill="purple" >
<animate attributeName="cx" begin="svg1.click" dur="3s" values="30;300" fill="freeze" />
</circle>
</svg>

Related

Why does the SVG animation stop when using xlink:href for external file

For some reason my spinner.svg is not animating when using xlink:href. Embedding the SVG on the page and using xlink:href seems to work fine, as the snippet below shows.
The problem: static (and solid!) spinner instead of animation
Why are the animation tags of the SVG suddenly not taking effect? The reference must be working since the image is actually displaying.
EDIT: Could this have to do with the shadow dom and xref?
According to Sara Soueidan "The target element must be part of the current SVG document fragment". I might be overloading what "document fragment" means, but to me document fragments belong in Shadow DOM land, and I suspect that SMIL animations might not work when using <use> statements due to this?
Working versions
.xlinked {
color: green;
}
img {
color: red; // not taking effect - of course! just a test.
}
.embedded {
color: blue;
}
<h1>xlink local</h1>
<svg class="xlinked">
<!-- could not get this external reference to work?
<use xlink:href="http://imgh.us/spinner_1.svg" />
-->
<use xlink:href="#spinner" />
</svg>
<h1>embedded</h1>
<div class="embedded">
<svg id="embedded" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round"/>
<circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round">
<animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502"/>
<animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4"/>
</circle>
</svg>
</div>
<h1>img</h1>
<img src="http://imgh.us/spinner_1.svg" />
<h1>External absolute xlink (not working)</h1>
<svg>
<!-- could not get this external reference to work. should be the same as a local reference? -->
<use xlink:href="http://imgh.us/spinner_1.svg" />
</svg>
<h1>Source SVG with symbols for xlink reference </h1>
<svg xmlns="http://www.w3.org/2000/svg"><symbol id="spinner" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round"/><circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round"><animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502"/><animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4"/></circle></symbol></svg>
In SVG1.1, Use element requires reference to SVG fragment not SVG URL. Try to add id attribute to root svg element of external SVG file and add hash string to href value of use element, like this.
external svg(spinner_1.svg)
<svg xmlns="http://www.w3.org/2000/svg" id="root">
<!--svg structure-->
</svg>
html uses external SVG file
<svg>
<use xlink:href="http://imgh.us/spinner_1.svg#root" />
</svg>
Note:In SVG2, you can set SVG URL to href attribute of use element. See https://www.w3.org/TR/2016/CR-SVG2-20160915/struct.html#UseElement

How to animate the svg rectangle to grow like music wave?

I have a below code,
<div id="akbar">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
width="400" height="200" viewBox="0 0 400 200">
<g transform="scale(1,-1) translate(0,-200)">
<rect x="50" y="0" fill="#f00" width="100" height="100">
<animate attributeName="height"
from="0"
to="100"
dur="0.5s"
fill="freeze" />
</rect>
<rect x="150" y="0" fill="#f70" width="100" height="200">
<animate
attributeName="height"
from="0"
to="200"
dur="0.5s"
fill="freeze" />
</rect>
<rect x="250" y="0" fill="#ec0" width="100" height="150">
<animate
attributeName="height"
from="0"
to="150"
dur="0.5s"
fill="freeze" />
</rect>
</g>
</svg>
</div>
I would like to animate the svg rectangle to grow like music waves.
How can I achieve that?
I need this behavior
You can achieve it using
values,
keyTimes
and keySplines
attributes of an <animate> tag.
JSfiddle example.
I stripped your example to single column only:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
width="400" height="200" viewBox="0 0 400 200">
<g transform="scale(1,-1) translate(0,-200)">
<rect x="50" y="0" fill="#f00" width="100" height="100">
<animate
attributeName="height"
from="0"
to="100"
dur="1s"
fill="freeze"
values="0; 200; 150; 160; 150; 160"
keyTimes="0; 0.2; 0.4; 0.6; 0.8; 1"
keySplines=".42 0 1 1;
0 0 .59 1;
.42 0 1 1;
0 0 .59 1;
.42 0 1 1;
0 0 .59 1;"
/>
</rect>
</g>
</svg>
As it is not perfect yet, you can play around with the attributes to adjust the timing better (keySplines especially) and make it more music waves like.
As you can see on the provided example, single column steps of movements are:
All the way from bottom to top
Then, from top to ~83% of height
Then, from ~83% to ~88%,
Then, from ~88% to ~83%,
Then, from ~83% to ~88%
I guess that increasing the difference between those repeating percentage numbers (83 and 88) will give you slightly better effect than mine (which is based on 75% and 80%, easier to calculate on widht: 200px), but it is close.
Also take a look at CSS tricks article on SVG animation, it is very thorough and covers all the details about mentioned attributes - and much more.

middle-click on svg use element open new tab

With firefox, when I middle-click (or ctrl+click) on a use element, it open the xlink:href url in new tab (like a href)
bug or feature?
<svg viewBox="0 0 400 80">
<circle id="circle" cx="40" cy="40" r="30" fill="#29e"></circle>
<use xlink:href="#circle" transform="translate(70, 0)" style="stroke: red;"></use>
</svg>
<p>ctrl+click on right circle</p>
It's an unresolved bug that they're not really sure how to handle. Trigger is the xlink:href that gets somehow internally treated just like an A.href does (middle-click or ctrl + click open to a new tab.) One workaround is to bury the xlink:href element under an invisible rect:
<svg viewBox="0 0 400 80">
<circle id="circle" cx="40" cy="40" r="30" fill="#29e" />
<use xlink:href="#circle" transform="translate(70, 0)" style="stroke: red;" />
<rect style="opacity:0" x="80" y="10" width="60" height="60" />
</svg>
<p>ctrl+click on right circle - nothing happens</p>
If you have any events that need to trigger, you'll have to tie them to the invisible rect.
As a workaround for the bug linked in previous answer you may also use pointer-events: none CSS rule on the use element:
<svg viewBox="0 0 400 80">
<circle id="circle" cx="40" cy="40" r="30" fill="#29e"></circle>
<use xlink:href="#circle" transform="translate(70, 0)" style="stroke: red; pointer-events: none;"></use>
</svg>
<p>ctrl+click on right circle</p>
Or declare that all use elements must not be clickable with <style>use{pointer-events: none;}</style>.
Obviously, this workaround is applicable only in case the element has NOT to be interactive at all.

Does spline animation work for svg opacity, and if so, how?

In the following SVG document, the first rectangle's opacity is animated using calcMode=discrete, and flashes on and off as I would expect. The second rectangle is supposed to be animated using calcMode=linear, but no animation is visible in Chrome or Firefox.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 400 500">
<rect width="300" height="100" transform="translate(50,50)" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
<animate attributeName="opacity" attributeType="XML" dur="1.2s" values="0.1; 1.0; 0.1" keyTimes="0; 0.33; 0.67" calcMode="discrete" repeatCount="indefinite" />
</rect>
<rect width="300" height="100" transform="translate(50,250)" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
<animate attributeName="opacity" attributeType="XML" dur="1.2s" values="0.1; 1.0; 0.1" keyTimes="0; 0.33; 0.67" calcMode="linear" repeatCount="indefinite" />
</rect>
</svg>
http://jsfiddle.net/aJUnZ/
Is my animation not defined correctly, is this not supported by SVG, or is it simply not implemented by browsers yet?
From the SVG Specification...
For linear and spline animation, the first time value in the list must be 0, and the last time value in the list must be 1. The key time associated with each value defines when the value is set; values are interpolated between the key times.
Your final keyTimes value is not 1 and therefore your animation isn't valid. Change it to 1 and it will work.

Switching between 2 values in an SVG animate element

I want to switch between exactly two values in an SVG animate element. I tried it this way:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="150" height="150" viewBox="0 0 150 150">
<rect x="10" y="10" width="100" height="100" fill="blue" stroke="red">
<animate attributeName="fill-opacity" values="0; 1" dur="1s" repeatCount="indefinite"/>
</rect>
</svg>
I wanted have the fill-opacity switching between the values 0 and 1. But what it does is fading from 0 to 1. I want it to stay on 0 for 1s, then stay on 1 for 1s, back to 0 for 1s and so on.
How do I do that? I tried nearly all possible attribute combinations but didn't manage it.
You want calcMode="discrete" on the animate element the default is linear.

Resources