I had an exsits path that represent line with arrow:
<path {...lineProps} id={id} />
it looks like:
is there a chance to add the next svg in the middle of the current link:
<svg width="32" height="18" viewBox="0 0 32 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="32" height="18" rx="9" fill="#F8788F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 10.9423L12 9.28917L10.3468 10.9423L10.0577 10.6532L11.7109 9.00003L10.0577 7.34693L10.3468 7.05784L12 8.71094L13.6531 7.05784L13.9421 7.34693L12.289 9.00003L13.9421 10.6532L13.6531 10.9423Z" fill="#FEFEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 11.4001L12 9.74695L10.3468 11.4001L9.59993 10.6532L11.2531 9.00003L9.59992 7.34693L10.3468 6.60006L12 8.25316L13.6531 6.60006L14.3999 7.34693L12.7468 9.00003L14.3999 10.6532L13.6531 11.4001ZM12.289 9.00003L13.9421 7.34693L13.6531 7.05784L12 8.71094L10.3468 7.05784L10.0577 7.34693L11.7109 9.00003L10.0577 10.6532L10.3468 10.9423L12 9.28917L13.6531 10.9423L13.9421 10.6532L12.289 9.00003Z" fill="#FEFEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0001 13.7081C13.3154 13.1808 14.0955 12.8115 14.6823 11.926C15.302 10.9909 15.7984 9.31606 15.8863 5.9205C14.5265 5.74148 13.1976 5.26052 12.0002 4.4796C10.8027 5.26052 9.4738 5.74148 8.11402 5.9205C8.20188 9.31606 8.69829 10.9909 9.31803 11.926C9.90483 12.8115 10.6849 13.1808 12.0001 13.7081ZM11.7768 14.911C11.9199 14.968 12.0804 14.968 12.2235 14.911L12.2434 14.9031C15.0408 13.7903 16.9994 13.0112 17.0964 5.40383C17.1006 5.07248 16.8312 4.80237 16.5007 4.77785C15.0545 4.67052 13.6299 4.17427 12.3834 3.2891C12.1546 3.12662 11.8457 3.12662 11.6169 3.2891C10.3705 4.17427 8.94583 4.67052 7.49961 4.77785C7.16914 4.80237 6.8997 5.07248 6.90392 5.40383C7.00086 13.0112 8.95954 13.7903 11.7569 14.9031L11.7768 14.911Z" fill="#FEFEFF"/>
</svg>
it looks like:
eventually it should look like:
As #AKX commented you need to find the point in the middle of the path. You can do it using the getTotalLength and getPointAtLength methods.
As for the tag you can put it inside a symbol and use the symbol with <use>. The use element can take an x and y attributes, the x and y of the point in the middle of the path. In order to center the use element around the point you need also to translate the use element backward half width and height
//the path length
let l = thePath.getTotalLength();
//the point in the middle of the path
let p = thePath.getPointAtLength(l/2);
//set the x andy attributes in the middle of the path
theUse.setAttribute("x", p.x);
theUse.setAttribute("y", p.y);
<svg viewBox="0 0 300 200" width="300">
<symbol viewBox="0 0 32 18" fill="none" id="s">
<rect width="32" height="18" rx="9" fill="#F8788F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 10.9423L12 9.28917L10.3468 10.9423L10.0577 10.6532L11.7109 9.00003L10.0577 7.34693L10.3468 7.05784L12 8.71094L13.6531 7.05784L13.9421 7.34693L12.289 9.00003L13.9421 10.6532L13.6531 10.9423Z" fill="#FEFEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.6531 11.4001L12 9.74695L10.3468 11.4001L9.59993 10.6532L11.2531 9.00003L9.59992 7.34693L10.3468 6.60006L12 8.25316L13.6531 6.60006L14.3999 7.34693L12.7468 9.00003L14.3999 10.6532L13.6531 11.4001ZM12.289 9.00003L13.9421 7.34693L13.6531 7.05784L12 8.71094L10.3468 7.05784L10.0577 7.34693L11.7109 9.00003L10.0577 10.6532L10.3468 10.9423L12 9.28917L13.6531 10.9423L13.9421 10.6532L12.289 9.00003Z" fill="#FEFEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0001 13.7081C13.3154 13.1808 14.0955 12.8115 14.6823 11.926C15.302 10.9909 15.7984 9.31606 15.8863 5.9205C14.5265 5.74148 13.1976 5.26052 12.0002 4.4796C10.8027 5.26052 9.4738 5.74148 8.11402 5.9205C8.20188 9.31606 8.69829 10.9909 9.31803 11.926C9.90483 12.8115 10.6849 13.1808 12.0001 13.7081ZM11.7768 14.911C11.9199 14.968 12.0804 14.968 12.2235 14.911L12.2434 14.9031C15.0408 13.7903 16.9994 13.0112 17.0964 5.40383C17.1006 5.07248 16.8312 4.80237 16.5007 4.77785C15.0545 4.67052 13.6299 4.17427 12.3834 3.2891C12.1546 3.12662 11.8457 3.12662 11.6169 3.2891C10.3705 4.17427 8.94583 4.67052 7.49961 4.77785C7.16914 4.80237 6.8997 5.07248 6.90392 5.40383C7.00086 13.0112 8.95954 13.7903 11.7569 14.9031L11.7768 14.911Z" fill="#FEFEFF"/>
</symbol>
<marker id="mk" viewBox="0 0 4 4" markerWidth="4" markerHeight="4" refX="0" refY="2" orient="auto-start-reverse">
<polygon points="0,0 4,2 0,4" fill="black" />
</marker>
<path id="thePath" d="M10,10 L270,160" stroke="black" stroke-width="4" stroke-dasharray="5" marker-end="url(#mk)" />
<use id="theUse" xlink:href="#s" width="32" height="18" transform="translate(-16,-9)" />
<svg>
I'm making a website where you can create your own character in order to learn more about SVGs. I want the user to be able to select different poses.
I was wondering how I could toggle the visibility of an SVG on the website to make one disappear and another appear.
Here is my SVG code:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 720 720" style="enable-background:new 0 0 720 720;" xml:space="preserve">
<g id="skin">
<circle class="skin" cx="364.42" cy="383" r="278" />
</g>
<g id="mouth">
<path class="mouth" d="M172.92,383c127.67,0,255.33,0,383,0c0,105.05-86.45,191.5-191.5,191.5S172.92,488.05,172.92,383z"/>
</g>
<g id="hair">
<path class = "hair" d="M107.4,276.86c-2.76-50.59,10.76-81.24,24.2-100.13C189.57,95.31,331.92,112,341.92,57.91
c2.04-11.03-2.07-21.46-6.93-29.61c18.47-6.31,81.92-25.39,151.28,3.28c94.59,39.09,121.88,137.21,127.56,160.84
c7.93,32.98,7.18,61.32,5.46,79.42c-38.79-64.73-78.17-85.57-107.42-92.42c-43.32-10.15-60.72,11.26-139.64,11.71
c-67.77,0.39-78.13-15.27-119.49-10.14C216.75,185.45,165.19,204.69,107.4,276.86z"/>
</g>
<g id="eyes">
<g>
<circle class = "eyes" cx="251.17" cy="271.25" r="52.4"/>
<circle class = "eyes" cx="477.67" cy="271.25" r="52.4"/>
</g>
</g>
<g id="clothing">
<rect x="236.92" y="644.4" width="255" height="180"/>
</g>
<g id="tie">
<rect class="tie" x="341.82" y="653.68" transform="matrix(0.7071 0.7071 -0.7071 0.7071 584.9371 -59.6038)" class="st0" width="45.2" height="45.2"/>
<path class="tie" d="M364.95,927.93c-6.29-12.71-12.59-25.42-18.88-38.13c3.44-63.19,6.89-126.39,10.33-189.58
c5.1,0.25,10.2,0.49,15.29,0.74c4.13,62.75,8.25,125.49,12.38,188.24C377.7,902.11,371.32,915.02,364.95,927.93z"/>
</g>
</svg>
The SVG is just a sample right now before I make the actual assets.
I'm trying to achieve a svg path fill animation like the gif below, tried clipPath but no luck, any help, idea how to achieve that kind of animation (gif image below)? tried gsap or any svg animation library but none of them cater my needs.
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 263.42 187.39">
<defs>
<clipPath id="clip1">
<path class="cls-1" fill="#c2a01e" d="M1889.36,77.11v3.47L1853,111.81q-10.32,2.86-21.35,7.09l-5.2,2c-8.68-2.49-17.65-5-26.73-7.37l90.6-109.08L1891.48,3V0H1737.59V4.49h0V51.65h2.23V48.17l50.94-43.68h44l-82.46,99.29-4,4.76c25.65,2.89,53.48,10.52,78.8,17.75l5.2-2c22.16-8.58,42.53-12.81,59.26-13.69V77.11Z" transform="translate(-1677.9)"/>
</clipPath>
<clipPath id="clip2">
<path class="cls-1" fill="#c2a01e" d="M1932.74,126.17c-13.82-10.71-52.11-11.68-98.2,6.14l-5.19,2c-53.78-15.35-118.75-32.47-150.47-2.43a3.15,3.15,0,0,0-1,2.51v0a2.32,2.32,0,0,0,3.67,1.69c24.48-17.77,57.75-16.76,132.38,4.48l-1.75.75c-8.06,3.49-21,9.57-34.68,15.79-20.34-9.54-48.19-17.44-66.13-6.65-26.21,15.75-19.06,51.2,38.47,30.66,8.47-3,48.84-21.17,83-35,2.93.89,5.92,1.79,9,2.73,16.51,5.06,38.3,8.93,57.55,10.6C1945.4,163.47,1948.48,138.37,1932.74,126.17ZM1712,157.37c15.48-11.94,39.91-5.59,58.83,2.82-6.94,3.12-13.89,6.17-20.3,8.84C1699.64,190.21,1697.33,168.67,1712,157.37Zm149.51-14c-4.11-1.09-8.38-2.27-12.78-3.51,9.34-3.58,17.56-6.5,23.64-8.22,29.63-8.41,58.5-3.24,61,6.19C1936.54,149.74,1912.3,156.79,1861.48,143.37Z" transform="translate(-1677.9)"/>
</clipPath>
</defs>
<path class="cls-1" fill="#FFF" clip-path="url(#clip1)" transform="translate(-1677.9)"/>
<path class="cls-1" fill="#FFF" clip-path="url(#clip2)" transform="translate(-1677.9)"/>
</svg>
The general idea is this: you draw the path you clip it as you need and next you animate the stroke-dashoffset of the clipped path. You make sure that the animation for the next path begins after the previous one ends: begin="a.end + .5s".
However in this case you will need to rewrite the paths. For example in the case of the lace I would use 2 paths and 2 different clip-paths or even 3. Otherwise you get an unaesthetic bleeding effect where the path overlaps.
<svg viewBox="0 0 500 500">
<defs>
<clipPath id="theZ">
<path d="M401.374,215.788v6.586l-69.015,59.278c-13.06,3.619-26.567,8.105-40.525,13.457l-9.869,3.797
c-16.477-4.727-33.502-9.49-50.737-13.989L403.196,77.872l2.202-2.752v-5.694h-292.1v8.522l0,0v89.515h4.232v-6.605l96.69-82.91
h83.517L141.219,266.41l-7.592,9.035c48.687,5.486,101.511,19.969,149.57,33.691l9.871-3.796
c42.062-16.286,80.727-24.315,112.481-25.985v-63.567H401.374z"/>
</clipPath>
<clipPath id="theLace">
<path d="M483.714,308.909c-26.231-20.329-98.91-22.17-186.394,11.654l-9.852,3.796
c-102.081-29.135-225.4-61.631-285.608-4.611c-1.316,1.222-2.013,2.971-1.898,4.764l0,0c0.201,2.424,2.328,4.227,4.751,4.025
c0.799-0.065,1.565-0.348,2.215-0.817c46.466-33.729,109.616-31.812,251.271,8.503l-3.321,1.424
c-15.298,6.625-39.86,18.165-65.826,29.971c-38.607-18.107-91.47-33.103-125.522-12.621c-49.75,29.895-36.178,97.183,73.02,58.195
c16.077-5.694,92.704-40.184,157.544-66.434c5.561,1.689,11.236,3.397,17.082,5.182c31.338,9.604,72.698,16.95,109.236,20.12C507.744,379.709,513.591,332.066,483.714,308.909z M64.726,368.131c29.383-22.664,75.753-10.611,111.666,5.352
c-13.173,5.923-26.365,11.712-38.531,16.779C41.265,430.464,36.88,389.579,64.726,368.131z M348.512,341.557
c-7.801-2.068-15.906-4.309-24.258-6.662c17.729-6.795,33.331-12.338,44.871-15.603c56.241-15.963,111.04-6.149,115.785,11.749
c6.017,22.607-39.993,35.988-136.455,10.516H348.512z"/>
</clipPath>
</defs>
<path fill="none" stroke="#C2A01E" clip-path="url(#theLace)" stroke-width="25" stroke-dasharray="1206" stroke-dashoffset="1206" d="M-0.038,324.512c0,0,49.523-27.071,69.538-27.012 c23.35,0.069,74.84,1.785,121.646,11.637C242.583,319.965,288.5,338.5,288.5,338.5s134.99,34.916,169,27s36.999-16.612,35-33.425
s-44.115-67.954-226,12.425s-172,69-172,69s-52.867,8.077-52-16s7.277-37.219,43.205-46.984c38.84-10.557,110.17,30.986,110.17,30.986" >
<animate id="a"
attributeName="stroke-dashoffset"
attributeType="XML"
from="1206" to="0"
dur="1s"
fill="freeze"
repeatCount="1"/>
</path>
<path fill="none" stroke="#C2A01E" d="M259.424,309.137V64.778" clip-path="url(#theZ)" stroke-width="300" stroke-dasharray="244.36" stroke-dashoffset="244.36">
<animate
attributeName="stroke-dashoffset"
attributeType="XML"
begin="a.end + .5s"
from="244.36" to="0"
dur="1s"
fill="freeze"
repeatCount="1"
/>
</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 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>