I'm trying to restart SVG animation sequence from Javascript. Restart-button below will broke SVG animation sequence. How to restart/reset entire sequence?
document.getElementById("button").addEventListener("click", function() {
document.getElementById("fore").beginElement();
});
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 150">
<path id="track" fill="none" stroke="#000000" stroke-width="1" stroke-dasharray="10,10" d="M 50 100 L 950 50"/>
<path id="plane" d="M-10 -10 L10 0L-10 10z" fill="red" />
<animateMotion xlink:href="#plane"
id="fore"
begin="0s;back.end"
dur="2s"
fill="freeze"
repeatCount="1"
rotate="auto"
keyPoints="0;1"
keyTimes="0;1"
><mpath xlink:href="#track" /></animateMotion>
<animateMotion xlink:href="#plane"
id="back"
begin="fore.end"
dur="2s"
fill="freeze"
repeatCount="1"
rotate="auto-reverse"
keyPoints="1;0"
keyTimes="0;1"
><mpath xlink:href="#track" /></animateMotion>
</svg>
<button id="button">RESTART</button>
You can use setCurrentTime on the entire svg element. I added an id of svgEl to the svg node and then when rest is clicked we do:
document.getElementById('svgEl').setCurrentTime(0);
Have a look at this:
document.getElementById("button").addEventListener("click", function() {
document.getElementById('svgEl').setCurrentTime(0);
});
<svg id="svgEl" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 150">
<path id="track" fill="none" stroke="#000000" stroke-width="1" stroke-dasharray="10,10" d="M 50 100 L 950 50"/>
<path id="plane" d="M-10 -10 L10 0L-10 10z" fill="red" />
<animateMotion xlink:href="#plane"
id="fore"
begin="0s;back.end"
dur="2s"
fill="freeze"
repeatCount="1"
rotate="auto"
keyPoints="0;1"
keyTimes="0;1"
restart="always"
><mpath xlink:href="#track" /></animateMotion>
<animateMotion xlink:href="#plane"
id="back"
begin="fore.end"
dur="2s"
fill="freeze"
repeatCount="1"
rotate="auto-reverse"
keyPoints="1;0"
keyTimes="0;1"
restart="always"
><mpath xlink:href="#track" /></animateMotion>
</svg>
<button id="button">RESTART</button>
Related
Move.gif
I want to animate this path up and down (vertically). I use animationMotion for this, but my path is moving in different directions.
<svg width="698" height="745" viewBox="0 0 698 645" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="bottom-arrow" d="M404.767 578.541L414.523 592.852L397.251 594.146L404.767 578.541Z" stroke="#EEE8FB" stroke-width="2"
>
<animateMotion
path="M0,0 0 50 90 0 90 10"
begin="0s" dur="2s" repeatCount="indefinite"
/>
</path>
</svg>
Hope you got my point
You just need to give proper path for animateMotion. In your code it should be path="M0,0 0 90 0 0"
For more information, check this link
<svg width="698" height="745" viewBox="0 0 698 645" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="bottom-arrow" d="M404.767 578.541L414.523 592.852L397.251 594.146L404.767 578.541Z" stroke="#EEE8FB" stroke-width="2"
>
<animateMotion
path="M0,0 0 90 0 0"
begin="0s" dur="2s" repeatCount="indefinite"
/>
</path>
</svg>
I have a path which represent half of the circle, I want it to render in a circular way.
as it is only path I tried of svg but it couldn't work.
<svg version="1.1" x="0px"
y="0px" width="131.45px" height="131.451px" viewBox="0 0 131.45 131.451" enable-background="new 0 0 131.45 131.451"
xml:space="preserve">
<g id="Group_952" transform="translate(0 0)">
<g id="Path_211">
<path fill="#0088CE" d="M86.692,128.579l-6.314-20.938c17.843-5.735,29.832-22.563,29.832-41.875
c0-23.389-17.711-42.625-40.314-43.793l1.059-21.9c33.925,1.752,60.5,30.606,60.5,65.69
C131.452,94.733,113.463,119.974,86.692,128.579z"/>
</g>
<svg>
Your semicircle is drawn using a double path see image below
Therefore, you can animate figure drawing only with the help of filter ormask
I suggest using the technique of drawing a figure from the top point to a semicircle, by changing the 'stroke-dasharray' of the middle line of the figure.
The middle line turned out - a circle with the center of (70.70) and a radius of 50
Next, set stroke-width ="20" and stroke-dasharray = "157 157" to get half the circle
Turn the semicircle counterclockwise 90 degrees so that its beginning is at the top
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="131.45px" height="131.451px" viewBox="0 0 131.45 131.451" >
<circle transform="rotate(-90 70 70)" cx="70" cy="70" r="50" fill="none" stroke="#0088CE"
stroke-width="20" stroke-dasharray="157 157">
</circle>
</svg>
To animate the drawing from the top point to half the circle, change the stroke-dasharray from ="0 314" to ="157 157"
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="131.45px" height="131.451px" viewBox="0 0 131.45 131.451" >
<circle transform="rotate(-90 70 70)" cx="70" cy="70" r="50" fill="none" stroke="#0088CE"
stroke-width="20" stroke-dasharray="157 157">
<animate
attributeName="stroke-dasharray"
values="0 314;157 157"
dur="5s"
fill="freeze" />
</circle>
</svg>
CSS animation
.crc1 {
fill:none;
stroke:#0088CE;
stroke-width:20;
stroke-dasharray:157.07;
animation: dash 4s ;
}
#keyframes dash {
0% {stroke-dasharray: 0 314}
100% {stroke-dasharray: 157 157}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="131.45px" height="131.451px" viewBox="0 0 131.45 131.451" >
<circle class="crc1" transform="rotate(-90 70 70)" cx="70" cy="70" r="50"> </circle>
</svg>
Semicircle rotation animation
For animation the change of attribute stroke-dashoffset is used:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="131.45px" height="131.451px" viewBox="0 0 131.45 131.451" >
<circle cx="70" cy="70" r="50" fill="none" stroke="#EDEDED"
stroke-width="20" />
<circle transform="rotate(-90 70 70)" cx="70" cy="70" r="50" fill="none" stroke="#0088CE"
stroke-width="20" stroke-dasharray="157.07" stroke-dashoffset="-314">
<animate
attributeName="stroke-dashoffset"
values="0;-314"
dur="2s"
repeatCount="indefinite" />
</circle>
</svg>
Complex animation of drawing and rotation
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="131.45px" height="131.451px" viewBox="0 0 131.45 131.451" >
<circle cx="70" cy="70" r="50" fill="none" stroke="#EDEDED"
stroke-width="20" />
<circle transform="rotate(-90 70 70)" cx="70" cy="70" r="50" fill="none" stroke="#0088CE"
stroke-width="20" stroke-dasharray="157.07" stroke-dashoffset="-314">
<animate id="an_dasharray"
attributeName="stroke-dasharray"
values="0 314;157 157"
begin="0s;an_dashoffset.end+0.5s"
dur="2s"
fill="freeze" />
<animate id="an_dashoffset"
attributeName="stroke-dashoffset"
values="0;-314"
begin="an_dasharray.end"
dur="2s"
repeatCount="2" />
</circle>
</svg>
I found this code at codepen and I tested on jsfiddle, on codepen but...when I add it to a localhost test page the click event doesn't do anything!
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
<!-- bar 1 -->
<path fill="#D8D8D8" d="M0,0 L6,0 L6,16 L0,16 L0,0 Z" id="bar1">
<animate xlink:href="#bar1"
attributeName="d"
from="M0,0 L6,0 L6,16 L0,16 L0,0 Z"
to="M0,0 L6,3.20001221 L6,12.7999878 L0,16 L0,0 Z"
dur="0.3s"
fill="freeze"
begin="startAnimation.begin" />
<animate xlink:href="#bar1"
attributeName="d"
from="M0,0 L6,3.20001221 L6,12.7999878 L0,16 L0,0 Z"
to="M0,0 L6,0 L6,16 L0,16 L0,0 Z"
dur="0.3s"
fill="freeze"
begin="reverseAnimation.begin" />
</path>
<!-- horizontal line -->
<path fill="#D8D8D8" d="M10,0 L16,0 L16,16 L10,16 Z" id="bar2">
<animate attributeName="d"
from="M10,0 L16,0 L16,16 L10,16 Z"
to="M5.9944458,3.20001221 L15,8 L15,8 L5.9944458,12.7999878 Z"
dur="0.3s"
fill="freeze"
begin="startAnimation.begin" />
<animate attributeName="d"
from="M5.9944458,3.20001221 L15,8 L15,8 L5.9944458,12.7999878 Z"
to="M10,0 L16,0 L16,16 L10,16 Z"
dur="0.3s"
fill="freeze"
begin="reverseAnimation.begin" />
</path>
<!-- controls -->
<!-- these are on top of the visible icon. Their radius changes depending on which is active
Opacity is set to 0 so you can't see them-->
<circle cx="16" cy="16" r="16" fill-opacity="0">
<animate dur="0.01s" id="startAnimation" attributeName="r" values="16; 0" fill="freeze" begin="click" />
<animate dur="0.01s" attributeName="r" values="0; 16" fill="freeze" begin="reverseAnimation.end" />
</circle>
<circle cx="16" cy="16" r="0" fill-opacity="0">
<animate dur="0.001s" id="reverseAnimation" attributeName="r" values="16; 0" fill="freeze" begin="click" />
<animate dur="0.001s" attributeName="r" values="0; 16" begin="startAnimation.end" fill="freeze" />
</circle>
</svg>
Does anybody had experienced sth similar?
I can't find what I do wrong here...
PS: I also added this style:
/*
* Play
* ----
*/
.play {
position: absolute;
z-index: 1000;
top: 35%;
left: 35%;
cursor: pointer;
margin: 0;
padding: 0.4em;
width: 30%;
height: 30%;
}
and modified the 1st line like
<svg class="play" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
still with no result!
On codepen, if you change the view to look at debug mode it will open a new tab with a full screen view of the page.
View the source and you will see that the page contains the normal HTML head and body tags.
Sample
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test - YouTube Play Pause Button</title>
<style>
body {
background: #111;
text-align: center;
}
svg {
margin-top: 45vh;
width: 40px;
height: 40px;
cursor: pointer;
}
</style>
</head>
<body translate="no">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
<!-- bar 1 -->
<path fill="#D8D8D8" d="M0,0 L6,0 L6,16 L0,16 L0,0 Z" id="bar1">
<animate xlink:href="#bar1"
attributeName="d"
from="M0,0 L6,0 L6,16 L0,16 L0,0 Z"
to="M0,0 L6,3.20001221 L6,12.7999878 L0,16 L0,0 Z"
dur="0.3s"
fill="freeze"
begin="startAnimation.begin" />
<animate xlink:href="#bar1"
attributeName="d"
from="M0,0 L6,3.20001221 L6,12.7999878 L0,16 L0,0 Z"
to="M0,0 L6,0 L6,16 L0,16 L0,0 Z"
dur="0.3s"
fill="freeze"
begin="reverseAnimation.begin" />
</path>
<!-- horizontal line -->
<path fill="#D8D8D8" d="M10,0 L16,0 L16,16 L10,16 Z" id="bar2">
<animate attributeName="d"
from="M10,0 L16,0 L16,16 L10,16 Z"
to="M5.9944458,3.20001221 L15,8 L15,8 L5.9944458,12.7999878 Z"
dur="0.3s"
fill="freeze"
begin="startAnimation.begin" />
<animate attributeName="d"
from="M5.9944458,3.20001221 L15,8 L15,8 L5.9944458,12.7999878 Z"
to="M10,0 L16,0 L16,16 L10,16 Z"
dur="0.3s"
fill="freeze"
begin="reverseAnimation.begin" />
</path>
<!-- controls -->
<!-- these are on top of the visible icon. Their radius changes depending on which is active
Opacity is set to 0 so you can't see them-->
<circle cx="16" cy="16" r="16" fill-opacity="0">
<animate dur="0.01s" id="startAnimation" attributeName="r" values="16; 0" fill="freeze" begin="click" />
<animate dur="0.01s" attributeName="r" values="0; 16" fill="freeze" begin="reverseAnimation.end" />
</circle>
<circle cx="16" cy="16" r="0" fill-opacity="0">
<animate dur="0.001s" id="reverseAnimation" attributeName="r" values="16; 0" fill="freeze" begin="click" />
<animate dur="0.001s" attributeName="r" values="0; 16" begin="startAnimation.end" fill="freeze" />
</circle>
</svg>
</body>
</html>
I am using SVG to try and animate a gradient path - to create a tail / shooting star effect. In doing this, I want to animate an object at the front of the tail, which I have shown in my example below (the circles).
The example works barely in Google Chrome, haven't checked others... You can see I've got 5 circles/paths and only 1 of them is working properly. The curved one animates the gradient at a different speed to the object and the others don't work properly at all except for the "almost-horizontal" one.
Can someone please provide some insight into why this doesn't work, recommend a way I could do this and provide an example if possible?
I'm almost to the point where i'll just write my own render code in canvas and using a JS library... :(
<svg style="height: 400px; width: 100%" viewBox="0 0 500 200">
<path id="circlePath1" stroke-width="2" d="M10 100 Q 100 10, 150 80 T 300 100" stroke="url(#grad)" fill="transparent"></path>
<path id="circlePath2" stroke-width="2" d="M30 20 L 130 19" stroke="url(#grad)" fill="transparent"></path>
<path id="circlePath3" stroke-width="2" d="M30 10 L 130 10" stroke="url(#grad)" fill="transparent"></path>
<path id="circlePath4" stroke-width="2" d="M10 10 L 10 110" stroke="url(#grad)" fill="transparent"></path>
<path id="circlePath5" stroke-width="2" d="M10 20 L 20 110" stroke="url(#grad)" fill="transparent"></path>
<linearGradient id='grad'>
<stop stop-opacity="0" stop-color='#800'>
<animate attributeName="offset" dur="2s" values='-0.20;0.80' repeatCount="indefinite" ></animate>
</stop>
<stop stop-color='#800' stop-opacity=".5">
<animate attributeName="offset" dur="2s" values='-0.02;0.98' repeatCount="indefinite" ></animate>
</stop>
<stop stop-opacity="0.5" stop-color='#800'>
<animate attributeName="offset" dur="2s" values='-0;1' repeatCount="indefinite" ></animate>
</stop>
<stop stop-opacity="0" stop-color='#800'>
<animate attributeName="offset" dur="2s" values='-0;1' repeatCount="indefinite" ></animate>
</stop>
</linearGradient>
<circle id="c1" r="2.5" cx="" cy="" fill="#880000">
<animateMotion dur="2s" repeatCount="indefinite">
<mpath href="#circlePath1"></mpath>
</animateMotion>
</circle>
<circle id="c2" r="2.5" cx="" cy="" fill="#880000">
<animateMotion dur="2s" repeatCount="indefinite">
<mpath href="#circlePath2"></mpath>
</animateMotion>
</circle>
<circle id="c3" r="2.5" cx="" cy="" fill="#880000">
<animateMotion dur="2s" repeatCount="indefinite">
<mpath href="#circlePath3"></mpath>
</animateMotion>
</circle>
<circle id="c4" r="2.5" cx="" cy="" fill="#880000">
<animateMotion dur="2s" repeatCount="indefinite">
<mpath href="#circlePath4"></mpath>
</animateMotion>
</circle>
<circle id="c5" r="2.5" cx="" cy="" fill="#880000">
<animateMotion dur="2s" repeatCount="indefinite">
<mpath href="#circlePath5"></mpath>
</animateMotion>
</circle>
</svg>
In this attempt I use a radial gradient that is masked by the line to create the trail, then a separate dot.
<svg width="500" height="300" viewBox="0 0 500 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="motion-path" stroke-width="2" d="M202.4 58.3c-13.8.1-33.3.4-44.8 9.2-14 10.7-26.2 29.2-31.9 45.6-7.8 22.2-13.5 48-3.5 70.2 12.8 28.2 47.1 43.6 68.8 63.6 19.6 18.1 43.4 26.1 69.5 29.4 21.7 2.7 43.6 3.3 65.4 4.7 19.4 1.3 33.9-7.7 51.2-15.3 24.4-10.7 38.2-44 40.9-68.9 1.8-16.7 3.4-34.9-10.3-46.5-9.5-8-22.6-8.1-33.2-14.1-13.7-7.7-27.4-17.2-39.7-26.8-5.4-4.2-10.4-8.8-15.8-12.9-4.5-3.5-8.1-8.3-13.2-11-6.2-3.3-14.3-5.4-20.9-8.2-5-2.1-9.5-5.2-14.3-7.6-6.5-3.3-12.1-7.4-19.3-8.9-6-1.2-12.4-1.3-18.6-1.5-10.2-.3-20.2-1.5-30.3-1" stroke="#666" fill="none"/>
<mask id="path-mask">
<use xlink:href="#motion-path" stroke="#666"/>
</mask>
<symbol id="ball">
<circle id="ball" r="2.5" fill="#800">
<animateMotion dur="5s" repeatCount="indefinite">
<mpath xlink:href="#motion-path"/>
</animateMotion>
</circle>
</symbol>
<symbol id="trail">
<circle r="30" fill="url(#grad)">
<animateMotion dur="5s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#motion-path"/>
</animateMotion>
</circle>
</symbol>
<linearGradient id="grad">
<stop offset="0" stop-opacity="0" stop-color="#800"/>
<stop offset=".5" stop-opacity=".8" stop-color="#800"/>
<stop offset=".5" stop-opacity="0" stop-color="#800"/>
</linearGradient>
</defs>
<use xlink:href="#ball"/>
<use xlink:href="#trail" mask="url(#path-mask)"/>
</svg>
It has its limitations (if the path gets too close you get the trail showing on both bits) but hopefully this gives you an idea to play with.
I would like to have my svg animation run when clicking an html button. I thought I could make that work by setting begin="click in my animateTransform and then trigger a click event on the animateTransform (or the svg element containing the animateTransform, I tried both) using js.
Any advice would be a great help.
var needle = $('#needle'),
tape = $('#tape'),
btn = $('#muhBtn');
btn.on('click', function() {
needle.click();
tape.click();
});
#tape {
fill: #ED1C24;
}
#needle {
fill: #8DC63F;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;"
xml:space="preserve">
<circle cx="100" cy="100" r="100" class="background"/>
<path class="st0" id="tape" d="M182.7,100c0,45.7-37,82.7-82.7,82.7V17.3C145.7,17.3,182.7,54.3,182.7,100z">
<animateTransform id="animateTape"
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 100 100"
to="180 100 100"
dur="5s"
begin="click"
repeatCount="1"/>
</path>
<path d="M200,100c0,55.2-44.8,100-100,100V0C155.2,0,200,44.8,200,100z" class="mask"/>
<polygon class="st1" id="needle" points="96,100 104,100 104,192 100,200 96,192">
<animateTransform id="animateNeedle"
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 100 100"
to="180 100 100"
dur="5s"
begin="click"
repeatCount="1"/>
</polygon>
</svg>
<button class="btn btn-warning" id="muhBtn">Begin!</button>
If you want to start the animations just do it directly via javascript and the beginElement method, no need for all that click event rigmarole. Note that I've changed the begin on the animation from click to indefinite to make it clearer what's happening.
var needle = $('#animateNeedle'),
tape = $('#animateTape');
btn = $('#muhBtn');
btn.on('click', function(){
needle[0].beginElement();
tape[0].beginElement();
});
#tape{
fill:#ED1C24;
}
#needle{
fill:#8DC63F;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200px" height="200px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<circle cx="100" cy="100" r="100" class="background"/>
<path class="st0" id="tape" d="M182.7,100c0,45.7-37,82.7-82.7,82.7V17.3C145.7,17.3,182.7,54.3,182.7,100z">
<animateTransform id="animateTape"
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 100 100"
to="180 100 100"
dur="5s"
begin="indefinite"
repeatCount="1"/>
</path>
<path d="M200,100c0,55.2-44.8,100-100,100V0C155.2,0,200,44.8,200,100z" class="mask"/>
<polygon class="st1" id="needle" points="96,100 104,100 104,192 100,200 96,192">
<animateTransform id="animateNeedle"
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 100 100"
to="180 100 100"
dur="5s"
begin="indefinite"
repeatCount="1"/>
</polygon>
</svg>
<button class="btn btn-warning" id="muhBtn">Begin!</button>