I have made the transparent text appear and disappear within 3 seconds, and I want to click the SVG to make the disappeared text appear again and again, is it poosible to make it?
Thanks for any help and creative thougths
<svg>
<text x="0" y="50" font-family="Verdana" font-size="35" fill="blue" opacity="0">Hello
<animate attributeName="opacity" begin="click" dur="0.3s" from="0" to="1" restart="never" fill="freeze"></animate>
<animate attributeName="opacity" begin="click+3" dur="0.3s" from="1" to="0" restart="never" fill="freeze">
</animate>
</text>
</svg>
Don't use 2 animations
For the begin use a list of values separated with semicolons: begin="theSVG.click;theSVG.click+3"
Use repeatCount="indefinite" for an infinite animation.
Instead of using the from and to attributes you can use a values attribute values="0;1;0" where the values are separates by semicolons.
Also the user can't know where the text is so clicking the text may be a problem. Instead you cah give the svg element an id (theSVG - in this case) and use this id to start the animation when the user is clicking the svg element begin="theSVG.click;theSVG.click+3"
You can use any other visible svg element for this.
svg{border:solid}
<svg id="theSVG">
<text x="0" y="50" font-family="Verdana" font-size="35" fill="blue" opacity="0">Hello
<animate attributeName="opacity" begin="theSVG.click;theSVG.click+3" dur="0.3s" values="0;1;0" restart="never" repeatCount="indefinite"></animate>
</text>
</svg>
UPDATE
The OP is commenting:
I am tring to make the "HELLO" re-clickable after it disappear after 3s, what should I do?
In this case you need to delete restart="never"
svg{border:solid}
<svg id="theSVG">
<text x="0" y="50" font-family="Verdana" font-size="35" fill="blue" opacity="0">Hello
<animate attributeName="opacity" begin="theSVG.click" dur="3s" values="0;1;0" repeatCount="1" fill="freeze"></animate>
</text>
</svg>
Related
I have the following SVG I animate with SMIL - this works fine on click, but will be rerun on repeating clicks - how can I prevent this? I want it to only run once and then do nothing on another click!
<g id="Gruppe_703" data-name="Gruppe 703" transform="translate(0 -185)" opacity="0">
<animateTransform
attributeName="transform"
attributeType="XML"
type="translate"
from="0 -185"
to="0 -39"
dur="0.1s"
begin="Gruppe_589.click"
fill="freeze"/>
</g>
Set the pointer-events property to none at the end of the animation then further mouse clicks are ignored.
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<polygon points="60,60 90,120 30,120">
<animateTransform
id="at"
attributeName="transform"
type="translate"
from="0 0"
to="0 -39"
dur="1s"
begin="click"
fill="freeze"/>
<set
attributeName="pointer-events"
to="none"
begin="at.end"/>
</polygon>
</svg>
Consider other options to prevent re-animation after a click:
restart = "whenNotActive"
This value indicates that the animation can only be restarted when it
is not active (i.e. after the active end). Attempts to restart the
animation during its active duration are ignored.
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<polygon points="60,60 90,120 30,120">
<animateTransform
id="at"
attributeName="transform"
type="translate"
from="0 0"
to="0 -39"
dur="3s"
begin="click"
fill="freeze"
restart="whenNotActive"/>
</polygon>
</svg>
restart = "never"
This value indicates that the animation cannot be restarted for the
time the document is loaded.
In other words, the animation fires only once, it cannot be restarted.
The animation can only be started again after reloading the document.
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<polygon points="60,60 90,120 30,120">
<animateTransform
id="at"
attributeName="transform"
type="translate"
from="0 0"
to="0 -39"
dur="3s"
begin="click"
fill="freeze"
restart="never"/>
</polygon>
</svg>
I'm wondering if I can animate a group of paths directly in the svg file?
I have a complex svg file and I would like to scale only one part, which I wrapped in the <g> element.
I tried something like this, but nothing happen.
<g id="Fire">
<path/>
<circle/>
<path fill="#FEC33A" d="M216.562,546.14c-0.13-0.38-0.26-0.75-0.4-1.12C216.302,545.38,216.442,545.76,216.562,546.14z"/>
<path fill="#F27D16" d="M215.032,573.37c-0.15-0.19-0.3-0.37-0.46-0.54C214.742,573.01,214.892,573.19,215.032,573.37z"/>
<animateTransform attributeName="transform"
attributeType="XML"
type="scale"
from="1"
to="1.1"
dur="2s"
repeatCount="indefinite"/>
</g>
If you want to use SMIL animations you may put the group in a <defs> element and reuse it with <use>. Then you may animate the use element
svg{border:1px solid; overflow:visible}
path{stroke:black;}
<svg viewBox="210 540 15 40" width="100">
<defs>
<g id="Fire">
<path d="M216.562,546.14
c-0.13-0.38-0.26-0.75-0.4-1.12C216.302,545.38,216.442,545.76,216.562,546.14z">
</path>
<path d="M215.032,573.37c-0.15-0.19-0.3-0.37-0.46-0.54C214.742,573.01,214.892,573.19,215.032,573.37z"/>
</g>
</defs>
<use xlink:href="#Fire" >
<animateTransform attributeName="transform"
attributeType="XML"
type="scale"
from="1"
to="1.1"
dur="2s"
repeatCount="indefinite"/>
</use>
</svg>
PS I suppose you may have a reason to use such complicated paths instead of a line
I have a path which is similar to circle. The task is to fill the path with a color with animation. The fill animation should be in circle manner and not from top to bottom or bottom to top.
my svg code is :
<svg id="svg_circle" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox = '0 0 450 400'>
<g class="svg_circle" transform = "translate(0,0)">
<path class="path" stroke="#F0F0F0" fill="#fff" stroke-width="1" opacity="1" d="m-0.25,238.11061l88.59461,-82.21665l87.56445,86.40604l-33.99561,0.52367c2.72107,17.03346 46.55824,67.96739 105.37633,63.99055c70.95792,-4.79765 101.17847,-64.19902 103.74816,-97.50561c7.13262,-92.44812 -81.66575,-121.29229 -115.80064,-115.90062c-119.13463,18.8176 -96.38311,112.29843 -96.38311,112.29843l-50.54082,-49.76652l-46.48973,43.1249c-12.30406,-104.7234 83.23188,-194.53124 191.25985,-198.17803c97.87838,-3.30416 202.62703,53.17701 213.76024,178.57248c16.06879,180.98587 -165.14043,220.64431 -208.6094,218.37164c-143.15297,-7.48456 -189.38275,-115.91408 -199.33787,-158.14925l-39.14646,-1.57102z" id="svg_1">
<animate id="project_anim1" attributeName="fill" from="#fff" to="#4DAF4C" begin="1s" dur="1s" fill="freeze" repeatCount="1"></animate>
</path>
</g>
</svg>
The common "dasharray" line drawing technique would work for you, in combination with using the arrow shape as a mask.
This technique is described in this SO question
However, since the head of your arrow shape overlaps the tail, to get a "perfect" result, you may have to divide the sweep into two parts. You would draw the tail part with a tail mask, and then the second half of the shape (including the arrow head) with a separate mask.
Here's a rough imperfect version showing the technique.
<svg id="svg_circle" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox = '0 0 450 400'>
<defs>
<path id="arrow" stroke="#F0F0F0" fill="none" stroke-width="1" opacity="1" d="m-0.25,238.11061l88.59461,-82.21665l87.56445,86.40604l-33.99561,0.52367c2.72107,17.03346 46.55824,67.96739 105.37633,63.99055c70.95792,-4.79765 101.17847,-64.19902 103.74816,-97.50561c7.13262,-92.44812 -81.66575,-121.29229 -115.80064,-115.90062c-119.13463,18.8176 -96.38311,112.29843 -96.38311,112.29843l-50.54082,-49.76652l-46.48973,43.1249c-12.30406,-104.7234 83.23188,-194.53124 191.25985,-198.17803c97.87838,-3.30416 202.62703,53.17701 213.76024,178.57248c16.06879,180.98587 -165.14043,220.64431 -208.6094,218.37164c-143.15297,-7.48456 -189.38275,-115.91408 -199.33787,-158.14925l-39.14646,-1.57102z" id="svg_1"/>
<clipPath id="arrow-clip" clipPathUnits="userSpaceOnUse">
<use xlink:href="#arrow"/>
</clipPath>
</defs>
<g clip-path="url(#arrow-clip)">
<circle cx="244" cy="200" r="158" transform="rotate(-164,244,200)"
fill="none" stroke="#4DAF4C" stroke-width="175"
stroke-dasharray="993 993">
<animate attributeName="stroke-dashoffset" from="993" to="0" begin="1s" dur="1s" fill="freeze" repeatCount="1"/>
</circle>
</g>
<use xlink:href="#arrow"/>
</svg>
Here we are animating a really thick green line, but using your shape as a clipping path so it conforms to the shape you want.
But as I mentioned, the section where the head overlaps the end of the tail is not perfect, so you may need to divide the animation into two parts as described above.
I am trying to get #moon svg group to follow a path and apply timed transforms. I cannot seem to get animateTransform to work in this situation.
When I set the animateMotion it causes the <g> to move out of frame. I adjust that with the attribute transform="translate(-53,-130)" which is fine. When I add the addTransform, the <g> drops down and out of the frame and I cannot adjust the translate to bring it back to frame. So, is there a trick to keeping the <g> in place or re-adjusting it back into frame with the addTransform?
<svg width="100%" height="100%" viewBox="0 0 570 594" preserveAspectRatio="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="padding: 0 10px 0 18px;fill-rule:evenodd;clip-rule:evenodd;stroke-miterlimit:10;">
<path id="orbit" d="M146.719,183.637l-18.408,-7.796l-13.233,-6.252l-12.327,-6.302l-18.44,-9.379l-12.42,-11.695l-16.36,-10.421l-15.546,-10.511l-12.326,-12.281l-14.415,-14.728l-8.426,-16.45l-4.168,-14.276l2.084,-14.272l6.297,-11.239l8.019,-10.103l12.013,-6.302l16.682,-8.426l16.356,-4.169l22.804,-4.217l27.474,-4.168l22.03,0l21.75,1.042l24.881,1.042l20.524,1.042l26.875,3.126l27.917,5.211l41.477,9.293l37.047,10.702l41.159,12.782l35.33,14.012l19.808,8.426l25.874,12.554l18.86,11.423l18.578,11.556l18.815,14.105l17.777,16.951l12.233,16.718l8.345,17.187l1.091,27.64l-7.434,8.207l-11.194,10.466l-15.595,10.559l-24.221,7.844l-22.609,5.211l-30.925,3.265l-43.658,0l-32.546,-2.085" style="fill:none;stroke-width:0px;stroke:#ff6060;"/>
<g id="moon" transform="translate(-53, -130)">
<path d="M77.39,295.34c0,-10.683 -8.658,-19.343 -19.342,-19.343c-10.683,0 -19.344,8.66 -19.344,19.343c0,10.683 8.661,19.343 19.344,19.343c10.684,0 19.342,-8.66 19.342,-19.343" style="fill:#fff;fill-rule:nonzero;"/>
<path d="M61.54,304.476c0,-2.967 -2.404,-5.373 -5.371,-5.373c-2.969,0 -5.373,2.406 -5.373,5.373c0,2.967 2.404,5.373 5.373,5.373c2.967,0 5.371,-2.406 5.371,-5.373" style="fill:#878787;fill-opacity:0.199997;fill-rule:nonzero;"/>
<animateMotion dur="6s" repeatCount="indefinite">
<mpath xlink:href="#orbit" />
</animateMotion>
<animateTransform attributeName="transform"
type="scale"
keyTimes="0;0.2;0.8;1" values="1.5;4;4;1.5"
dur="6s" additive="replace" fill="freeze"
repeatCount="indefinite"/>
</g>
</svg>
animateTransform normally replaces the current transform with the animated value, the additive attribute controls this.
If you set additive="sum" then the animation will be applied on top of the existing transform rather than replacing it.
I have a 17 second long second animation with multiple parts to it. How can I repeat the whole sequence once it's done?
I tried repeatCount = "indefinite" attribute on each <animate>, but that just made things weird. Here's the animation I want repeated, for reference or something.
<rect x="185" y="300" width="300" height="400" fill="#666666">
<animate
attributeName="x"
from="185" to="145"
begin="5s"
dur="2s"
fill="freeze"
/>
<animate
attributeName="x"
from="145" to="185"
begin="9s"
dur="2s"
fill="freeze"
/>
<animate
attributeName="y"
from="300" to="340"
begin="11s"
dur="2s"
fill="freeze"
/>
<animate
attributeName="y"
from="340" to="300"
begin="15s"
dur="2s"
fill="freeze"
/>
</rect>
In addition to animation begin values being clock-based time intervals, they can also be sync-based values that reference other animations.
From MDN Web Docs:
<syncbase-value>Describes a syncbase and an optional offset from that syncbase. The element's animation start time is defined relative to the begin or active end of another animation. A syncbase consists of an ID reference to another animation element followed by either .begin or .end to identify whether to synchronize with the beginning or active end of the referenced animation element.
This means you can chain animations together by referencing each others' IDs as begin values.
Basically, you'll want to start each animation after the previous one ends. When the last animation ends it should trigger the first to start again. The animation begin attribute accepts multiple values so you can specify two values for the first animation: the 5s delay and the end of the last animation.
<svg viewBox="0 0 400 500" width="50%" height="50%">
<rect x="50" y="10" width="300" height="400" fill="#666666">
<animate
id="anim1"
attributeName="x"
from="50" to="10"
begin="5s;anim4.end"
dur="2s"
fill="freeze"
/>
<animate
id="anim2"
attributeName="x"
from="10" to="50"
begin="anim1.end"
dur="2s"
fill="freeze"
/>
<animate
id="anim3"
attributeName="y"
from="10" to="50"
begin="anim2.end"
dur="2s"
fill="freeze"
/>
<animate
id="anim4"
attributeName="y"
from="50" to="10"
begin="anim3.end"
dur="2s"
fill="freeze"
/>
</rect>
</svg>
You can try with this:
<animate attributeName="x" values="185; 145; 185" begin="5s" dur="4s" fill="freeze"/>
<animate attributeName="y" values="300; 340; 300" begin="11s" dur="4s" fill="freeze"/>