svg trigger single animation - javascript

I figured out a problem with SVG I couldn't solve yet. Given is a svg with multiple animations depending on each other with the begin attribute. So the animations got different ID's like 'circle' and begin tags with values like 'circle.end'. These svg is rendered / used multiple times on the page. In the first point is it not valid to have a id multiple times. At the second point all svg's doing the animation depending on circle.end when I start it with circle.beginElement() of the first svg.
So how can I start an animation depending on another animation without using id's or how can I start the animation on only one svg?
Here is a sample code
<svg>
<defs>
<path d="asdasd" id="circle-image">
<animateTransform id="circle" attributeName="transform" type="translate" from="0, 0" to="15, 0" begin="indefinite"/>
<animateTransform attributeName="transform" type="translate" from="15, 0" to="0, 0" begin="circle.end"/>
</path>
</defs>
</svg>
<svg viewBox="0 0 34 24" width="45px" height="24px" class="first">
<use xlink:href="#circle-image"/>
</svg>
<svg viewBox="0 0 34 24" width="45px" height="24px" class="second">
<use xlink:href="#circle-image"/>
</svg>
I want to somehow trigger .first #circle animation and .second #circle animation. The depending animation should only trigger within it's use element and not globally for all.
Can someone help here?
Thanks in advance
Regards Thomas

Related

Keeping parts of an SVG at fixed size

Essentially I needed to make the center "cut-out" keep a fixed shape and size regardless of vector scale. Is there a way to achieve this?
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none" style="fill-rule:evenodd;" viewBox="0 0 2802 2657">
<path d="M290 4c-95,733 -191,1466 -286,2200 760,150 1520,300 2279,450 172,-223 343,-446 515,-669 -114,-572 -229,-1144 -343,-1716 -722,-88 -1444,-176 -2165,-264zm696 1027c-103,111 -205,222 -308,333 94,111 188,222 282,333 342,-205 684,-410 1026,-616 -333,-17 -667,-34 -1000,-51z"/>
</svg>
So I managed to do something after some editing to your SVG.
To achieve what you're asking you'll need to use / have :
- the SVG mask attribute
- A very large shape for the mask ( as much large as the max scale you want to use on the visible shape )
- The shape that you want to resize
- Resize the shape with transforms
Your SVG should looks like the following
<svg>
<defs>
<mask id="theMask">
<path fill="#ffffff" d=""/>
</mask>
</defs>
<g mask="url(#theMask)">
<path fill="#ffffff" id="shapetoresize" d=""/>
</g>
</svg>
I posted a pen as a "Proof of concept"
Feel free to fork it and use it to achieve what you're trying to do.
Codepen
note: as pointed out by #thioutp , The JS is only for demo purposes, you don't need GSAP to achieve this.

Cutting out a text shape from background that can be resized dynamically

I'm trying to create a box that is opaque, but has a block of text in it that you can see through (to like the background image of the page or some element underneath).
It's hard to explain so I've made some crude diagrams:
I am attempting to use SVG files to do this and use Javascript/jquery to modify the rectangle width and height but I'm not proficient at the SVG format... I've managed to piece this together using the evenodd filter:
https://jsfiddle.net/PhoenixFieryn/sqvLgqbq/
<svg id="coverimage" width="80pcm" height="30cm" viewBox="0 0 2000 2000" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>Example fillrule-evenodd - demonstrates fill-rule:evenodd</desc>
<defs>
<rect x="1" y="1" width="2000" height="1000"
fill="white" stroke="blue" />
</defs>
<g fill-rule="evenodd" fill="white" >
<path d="M0 0 h1000 v1000 h-1000z M841,396.8c-2.4-4-1.6-8.8,2.4-11.2c68-44,95.2-105.6,95.2-172.8c0-116-96.8-205.6-211.2-205.6H610.6H469.8
h-6.4c-4,0-5.6,1.6-8.8,6.4L315.4,320c-4,6.4-8,6.4-11.2,0l-140-306.4c-2.4-4.8-4.8-6.4-8.8-6.4H9c-5.6,0-8.8,4-6.4,9.6l264,554.4
c1.6,4,5.6,6.4,9.6,6.4h66.4c4,0,7.2-1.6,8.8-5.6l110.4-230.8v228.4c0,4.8,3.2,8,8,8h146.4c4.8,0,8-3.2,8-8V426.4c0-4.8,3.2-8,8-8
h42.4c4,0,8,1.6,9.6,5.6l76,148c1.6,4,5.6,5.6,9.6,5.6h158.4c5.6,0,8.8-4,5.6-9.6L841,396.8z M701.8,276h-69.6c-4.8,0-8-3.2-8-8
V158.4c0-4.8,3.2-8,8-8h75.2c36.8,0,68,28.8,68,62.4C775.4,244,750.6,276,701.8,276z"/>
</g>
I don't know how to modify the size/position of the text and rectangle independently well. I can barely understand what I wrote and why the margin is so big.
If anyone could help me, through this or any other method, thank you!
Edit: someone pointed out that there may be a duplicate, but that solution does not work in Firefox unfortunately. I am looking for a cross “platform” solution. But thanks for the link, it’s very helpful nonetheless.
My suggestion is to create a mask using the text. We then create a blue rectangle that we mask with the our text mask.
We can postion the SVG and have it size the way we want using SVG width and height. But we also make the blue rectangle very large and have the SVG set to overflow: visible. This allows us to easily have the SVG size be responsive and also have the blue extend to all the way to the edges of the screen.
body {
background-image: url('http://austinhou.com/img/cover.jpg');
background-size: cover;
margin: 0;
padding: 0;
}
#coverimage {
width: 40%;
height: 100vh;
overflow: visible;
}
<body>
<svg id="coverimage" viewBox="0 0 950 600" preserveAspectRatio="xMinYMid meet">
<defs>
<mask id="vr">
<rect x="0" y="-1000%" width="1000%" height="3000%" fill="white"/>
<path fill="black" d="M841,396.8c-2.4-4-1.6-8.8,2.4-11.2c68-44,95.2-105.6,95.2-172.8c0-116-96.8-205.6-211.2-205.6H610.6H469.8
h-6.4c-4,0-5.6,1.6-8.8,6.4L315.4,320c-4,6.4-8,6.4-11.2,0l-140-306.4c-2.4-4.8-4.8-6.4-8.8-6.4H9c-5.6,0-8.8,4-6.4,9.6l264,554.4
c1.6,4,5.6,6.4,9.6,6.4h66.4c4,0,7.2-1.6,8.8-5.6l110.4-230.8v228.4c0,4.8,3.2,8,8,8h146.4c4.8,0,8-3.2,8-8V426.4c0-4.8,3.2-8,8-8
h42.4c4,0,8,1.6,9.6,5.6l76,148c1.6,4,5.6,5.6,9.6,5.6h158.4c5.6,0,8.8-4,5.6-9.6L841,396.8z M701.8,276h-69.6c-4.8,0-8-3.2-8-8
V158.4c0-4.8,3.2-8,8-8h75.2c36.8,0,68,28.8,68,62.4C775.4,244,750.6,276,701.8,276z" transform="translate(-210 0)"/>
</mask>
</defs>
<rect x="0" y="-1000%" width="1000%" height="3000%" fill="#09f" mask="url(#vr)"/>
</svg>
</body>
JSFiddle version

svg animate tag changing

I am trying to make a rectangule in svg move down and them,when you tap it,to go to the right but it seems that it doesn't work.The console doesn't show any error.
Here is a JSFiddle:https://jsfiddle.net/troosfx8/
Update:Thanks for the answers.But now I want to know how can I make the second animation begin if a variable is 5 for example.Is there any way I can make a svg animation begin based on a condition?
There is a much simpler solution than how you are attempting to do it above.
All you need to do is add another <animate> element that begins on a click.
<svg width="360" height="400"
style="border:#9999ff dotted 7px; border-radius:12px;" >
<rect id="Rect" x="70" y="70" width="50" height="50"
style="stroke:yellow; stroke-width:5px; fill:orange;">
<animate id="pos" attributeName="y" from="70" to="140" dur="1s"
repeatCount="none" fill="freeze"/>
<animate id="pos" attributeName="x" from="70" to="140" dur="1s"
repeatCount="none" fill="freeze" begin="click"/>
</rect>
</svg>

SVG Hover State with Multiple Elements

Good afternoon everyone,
I'm defining an SVG on my page with the following defs.
<svg width="0" height="0">
<defs>
<g id="stroke-hexagon">
<polygon fill="#002663" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="12" points="57.8,185 5.8,95 57.8,5 161.8,5 213.8,95 161.8,185 "/>
</g>
<g id="hexagon">
<polygon fill="#006890" points="52,180 0,90 52,0 156,0 208,90 156,180 "/>
</g>
</defs>
</svg>
...and implementing it later in the HTML using this:
<svg width="208px" height="180px" viewBox="0 0 208 180" >
<use xlink:href="#hexagon"></use>
<text class="faicon" x="50%" y="70px" fill="white" font-size="80px" text-anchor="middle">&#xf040</text>
<text text-anchor="middle" x="50%" y="70%" fill="white">Logo Here</text>
</svg>
Works totally fine. I am also able to style the polygon's fill with simple CSS. Looks like this:
#hexagon:hover polygon {
fill:#990000;
}
The hover effect fails, however, whenever the mouse leaves the polygon and instead hovers over either of the 'text' elements within the svg. Is there a way to define a CSS rule that prevents this behavior. Or, would it be better (easier) to change the attribute using JS / jQuery?
Thanks!
Your texts are rendered on top of your polygon and are therefore intercepting mouse events. You should set up a css rule like
text {
pointer-events: none;
}
This will prevent the text from becoming a target of mouse events which should give you the desired hover effect for the polygon.

How can I animate a drawing effect? (Preferably css3 only)

I want to make a drawing effect of tree that looks something like this one with a progressive line like here. I would prefer using only css3 with svg/canvas and js. Do you have any ideas?
More info:
I tried to cut a tree into pieces and animate piece by piece the appearance but it's not cursive cause it's to much details on syncronizing delays and durations because every piece has a different length and so on. All of this is made without svg. I want to now if i can animate a line path.
Yes, take a look at this rendering of the Bahamas Logo using CSS 3
It describes his process, and techniques. Also you can view the source.
There are more that can be found here
Update:
Also maybe this Sencha Animator product may help?
You can do this with plain SVG. SVG provides the <animate> element for declarative animation.
What you want (as I understand it) is a line that appears as if it was drawn in front of the viewer's eyes. You can use the stroke-dasharray property for this purpose. This property defines a dash pattern using a series of values that defines the length of dashes and gaps. The strategy would be: First we have a dash that has length 0 and a gap that is at least as long as the whole path. This means we see nothing (or only the first point at the start of the path). In the end we want a dash that's at least the full length of the path. We want the dash to gradually become longer and longer until it reaches its final length (the length of the full path).
The simplest case would be:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<!-- This is the path of a spiral -->
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305">
<!-- This defines the animation:
The path is roughly 2305 units long, it will be drawn in 5 seconds -->
<animate from="0,2305" to="2305,0" dur="5s"
attributeName="stroke-dasharray" repeatCount="indefinite"/>
</path>
</svg>
More sophisticated things can be done using multiple values (using the values attribute) instead of one from and one to value:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305">
<animate attributeName="stroke-dasharray" dur="5s" repeatCount="indefinite"
values="0,2305;
2000,305;
2305,0"/>
</path>
</svg>
You can specify the precise timing (when which value listed in values will be reached) using the keyTimes attribute:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305">
<animate attributeName="stroke-dasharray" dur="5s" repeatCount="indefinite"
values="0,2305;
2000,305;
2305,0"
keyTimes="0;.9;1"/>
</path>
</svg>
See this in action on Tinkerbin.
Something similar can be done using CSS3:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<style type="text/css">
path {
animation-name:animateDash;
animation-duration:5s;
animation-iteration-count:infinite;
}
#keyframes animateDash {
from{stroke-dasharray:0,2305}
to {stroke-dasharray:2305,0}
}
</style>
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305"/>
</svg>
Decide for yourself which method you prefer.

Categories

Resources