mask SVG path by another path - animation
I have SVG path (solid) which I want to mask by other path (dashed). I have this CSS
.dashed{
stroke-dasharray: 5;
}
.path {
stroke-dasharray: 852;
stroke-dashoffset: 852;
animation: dash 4s 1s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
and the SVG like this
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="612px" height="792px" viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
<g transform="scale(1.7)">
<path class="path" fill="none" stroke="#e31f1a" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.0" d="m 34.161514,227.15068 c 0,0 5.335031,41.13009 -10.338686,53.31427 -13.8827124,10.79193 -26.8802222,-16.84233 0.681739,-19.39738 52.917804,-4.90561 69.13065,91.87642 69.13065,91.87642"/>
</g>
<g transform="scale(1.71)">
<path class="dashed" fill="none" stroke="black" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.5" d="m 34.161514,227.15068 c 0,0 5.335031,41.13009 -10.338686,53.31427 -13.8827124,10.79193 -26.8802222,-16.84233 0.681739,-19.39738 52.917804,-4.90561 69.13065,91.87642 69.13065,91.87642"/>
</g>
</svg>
The paths are the same. The reason why I don't use just dashed one is the animation (see CSS part) where I want to do effect which will draw the dashed line.
Using mask image (with the dashed line inside)
mask-image: url(mask.svg);
did not work for me. Would you know the way?
You don't need to use mask-image. That is for when you want to mask an HTML element with a mask.
You should just use an SVG <mask> element. And animate the path in that.
.dashed {
stroke-dasharray: 5;
}
.path {
stroke-dasharray: 226;
stroke-dashoffset: 226;
animation: dash 4s 1s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" width="612px" height="792px" viewBox="0 0 612 792">
<defs>
<mask id="mymask">
<path class="path" fill="none" stroke="#fff" stroke-width="2"
d="m 34.161514,227.15068 c 0,0 5.335031,41.13009 -10.338686,53.31427 -13.8827124,10.79193 -26.8802222,-16.84233 0.681739,-19.39738 52.917804,-4.90561 69.13065,91.87642 69.13065,91.87642"/>
</mask>
</defs>
<g transform="scale(1.71)">
<path class="dashed" fill="none" stroke="black" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="1.5"
mask="url(#mymask)"
d="m 34.161514,227.15068 c 0,0 5.335031,41.13009 -10.338686,53.31427 -13.8827124,10.79193 -26.8802222,-16.84233 0.681739,-19.39738 52.917804,-4.90561 69.13065,91.87642 69.13065,91.87642"/>
</g>
</svg>
Related
Hard svg animation
I need your help with the implementation of svg animation. https://youtu.be/lrWjkARl8Zg (sorry for the poor video quality) And I have such a structure of svg I need the arrow (class = "arrow") itself to move along long lines and draw it. <svg class="vector" width="1193" height="329" viewBox="0 0 1193 329" fill="none" xmlns="http://www.w3.org/2000/svg"> <path class="long_line" d="M1436 327.98L84.7148 327.98C73.8082 328.219 62.9639 326.275 52.818 322.262C42.6722 318.249 33.4293 312.249 25.6315 304.613C17.8337 296.977 11.6384 287.858 7.40866 277.793C3.17891 267.728 0.999997 256.919 0.999996 246C0.999996 235.081 3.17891 224.272 7.40866 214.207C11.6384 204.142 17.8337 195.023 25.6315 187.387C33.4292 179.751 42.6722 173.75 52.818 169.738C62.9638 165.725 73.8082 163.781 84.7147 164.02L589.173 164.02" stroke="black" stroke-width="2" stroke-miterlimit="10"/> <path class="arrow" d="M544 204L589 164L548 124" stroke="black" stroke-width="2"/> <path class="arrow" d="M504 1L459 41L500 81" stroke="black" stroke-width="2"/> <path class="short_line" d="M1308 41L459 41" stroke="black" stroke-width="2" stroke-miterlimit="10"/> </svg> Advise which library I can use
You could do this using svg smil animations: A Guide to SVG Animations (SMIL) Your arrow animations could be achieved by <animateMotion> for moving the arrow element and animating the stroke-dashoffset property. Animated example svg { border: 1px solid #ccc; width: 33%; overflow: visible; display: block; } path { stroke-width: 10; stroke: #000; } <p>Click on animation for replay</p> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 500"> <defs> <path id="arrow" fill="none" d="M-45,40L0,0l-41-40" /> </defs> <use id="arrow1" href="#arrow" /> <use id="arrow2" href="#arrow" /> <g id="graphics"> <rect id="graphics" fill="#fff" fill-opacity="0" x="0" y="0" width="100%" height="100%" /> <path id="mpath-long" fill="none" pathLength="100" stroke-width="2" stroke-miterlimit="10" stroke-dashoffset="100" stroke-dasharray="100" d="M1571,413H219.7 c-10.9,0.2-21.8-1.7-31.9-5.7c-10.1-4-19.4-10-27.2-17.6c-7.8-7.6-14-16.8-18.2-26.8S136,341.9,136,331s2.2-21.7,6.4-31.8 s10.4-19.2,18.2-26.8c7.8-7.6,17-13.6,27.2-17.6c10.1-4,21-6,31.9-5.7h504.5" /> <path id="mpath-short" fill="none" pathLength="100" stroke-width="2" stroke-miterlimit="10" stroke-dashoffset="100" stroke-dasharray="100" d="M1443,126H594" /> </g> <animateMotion href="#arrow1" dur="2" rotate="auto" repeatCount="1" begin="0;graphics.click" fill="freeze"> <mpath href="#mpath-long" /> </animateMotion> <animate attributeType="XML" href="#mpath-long" id="strokeAni" attributeName="stroke-dashoffset" from="100" to="0" dur="2s" repeatCount="1" begin="0;graphics.click" fill="freeze" /> <animateMotion href="#arrow2" dur="2s" rotate="auto" repeatCount="1" begin="0;graphics.click" fill="freeze"> <mpath href="#mpath-short" /> </animateMotion> <animate attributeType="XML" href="#mpath-short" attributeName="stroke-dashoffset" from="100" to="0" dur="2s" repeatCount="1" fill="freeze" begin="0;graphics.click" /> </svg> Quite likely, you will have to tweak your svg viewBox to get the desired result. A common trick is to position element that's supposed to move along the motion path to x/y = 0. Static example <style> svg{ border: 1px solid #ccc; width: 33%; overflow:visible; display:block; } path{ stroke-width:10; stroke: #000; } </style> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 500"> <defs> <path id="arrow" fill="none" d="M-45,40L0,0l-41-40" /> </defs> <use id="arrow1" href="#arrow" /> <use id="arrow2" href="#arrow" /> <g id="graphics"> <rect id="graphics" fill="#fff" fill-opacity="0" x="0" y="0" width="100%" height="100%" /> <path id="mpath-long" fill="none" pathLength="100" stroke-width="2" stroke-miterlimit="10" stroke-dashoffset="0" stroke-dasharray="100" d="M1571,413H219.7 c-10.9,0.2-21.8-1.7-31.9-5.7c-10.1-4-19.4-10-27.2-17.6c-7.8-7.6-14-16.8-18.2-26.8S136,341.9,136,331s2.2-21.7,6.4-31.8 s10.4-19.2,18.2-26.8c7.8-7.6,17-13.6,27.2-17.6c10.1-4,21-6,31.9-5.7h504.5" /> <path id="mpath-short" fill="none" pathLength="100" stroke-width="2" stroke-miterlimit="10" stroke-dashoffset="0" stroke-dasharray="100" d="M1443,126H594" /> </g> </svg>
SVG animate gradient along path
I have the following svg that i would like to animate. I would like the red part moves along the path up to the end (so from the top right side to the left bottom side) : The problem is : obviously is quite impossible to have a gradient following a path. Here is my code so far : <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; } </style> <linearGradient id="light" x1="100%" y1="100%"> <stop offset="70%" stop-color="#3E3E3E"> <!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="0.5s" fill="freeze" /> --> </stop> <stop offset="100%" stop-color="#CF4B59"> <!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="0.5s" fill="freeze" /> --> </stop> </linearGradient> </defs> <g id="Calque_2" data-name="Calque 2"> <g id="Calque_1-2" data-name="Calque 1"> <g class="cls-2"> <path class="cls-3" id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" transform="translate(-52.32 -8.93)" stroke="url(#light)"/> </g> </g> </g> </svg> I tried to use "animate" to make it move along the path, but it's a vertical gradient which is applied and goes from the top to the bottom and not a gradient which follows the path. I had other ideas to overcome this : Maybe by using a second path which would be the same shape than the first one but with inverted gradient so I could make it slide along the initial path maybe Or, I could use opacity to make the final path appear but i'm not sure i will be able to make the red part move in this way... If you have some ideas to make the red part move from the top right to the bottom left it would help me a lot!
Question I would like the red part moves along the path up to the end (so from the top right side to the left bottom side) : Consider using fill-line animation with stroke-dashoffset. For clarity, I placed exactly the same curve below which will show the route of filling the line with color If this indication of the motion path is not necessary, simply remove the path id = "trace" <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; stroke:#E7E7E7; } #base { fill: none; stroke:crimson; stroke-width:3px; stroke-dashoffset:1732; stroke-dasharray:1732; animation: fillStroke 10s linear forwards; } #keyframes fillStroke { to {stroke-dashoffset:0;} } </style> </defs> <g transform="translate(-352.32 -8.93)"> <path id="trace" class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" /> <g class="cls-2"> <path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" > </path> </g> </g> </svg> Gradient animation option Instead of filling with color as the length of the curve increases, a gradient will perform this function <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; stroke:#E7E7E7; } #base { fill: none; stroke:url(#light); stroke-width:3px; stroke-dashoffset:1732; stroke-dasharray:1732; animation: fillStroke 10s linear forwards; } #keyframes fillStroke { to {stroke-dashoffset:0;} } </style> <linearGradient id="light" x1="100%" y1="100%"> <stop offset="50%" stop-color="#CF4B59"> <!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="10s" fill="freeze" /> --> </stop> <stop offset="100%" stop-color="#3E3E3E"> <!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="10s" fill="freeze" /> --> </stop> </linearGradient> </defs> <g transform="translate(-352.32 -8.93)"> <path class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" /> <g class="cls-2"> <path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" > </path> </g> </g> </svg>
How to make an object rotate around the exact center of the screen using animateTransform?
Consider the following SVG code for moving a circle around the center of the screen, with hard-coded dimensions: <svg xmlns="http://www.w3.org/2000/svg"> <g> <ellipse id="circ" style="fill:#000000" cx="60%" cy="50%" rx="10" ry="10" /> <!--Assuming window size is 1000x1000--> <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,500,500" to="360,500,500" repeatCount="indefinite"/> </g> </svg> If I try to provide the center of rotation in percent, the animation doesn't work at all: <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,50%,50%" to="360,50%,50%" repeatCount="indefinite"/> How do I fix this?
Set a viewBox on your SVG, then whatever size you make it, the ellipse will rotate around the centre of it. viewBox="0 0 1000 1000" The value of 1000 for width and height here is chosen because it would make 500 be the centre. svg:nth-child(1) { width: 200px; } svg:nth-child(2) { width: 500px; } svg { border: solid 1px green; } <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> <g> <ellipse id="circ" style="fill:#000000" cx="60%" cy="50%" rx="10" ry="10" /> <!--Assuming window size is 1000x1000--> <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,500,500" to="360,500,500" repeatCount="indefinite"/> </g> </svg> <!-- An exact duplicate of th first one --> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> <g> <ellipse id="circ" style="fill:#000000" cx="60%" cy="50%" rx="10" ry="10" /> <!--Assuming window size is 1000x1000--> <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,500,500" to="360,500,500" repeatCount="indefinite"/> </g> </svg>
d3 Select and modify g elements within svg elements
I'm having trouble selecting and manipulating (i want to add click behavior to) a path in inline svg code I produced in Inkscape and then pasted into my html file. <svg version="1.1" id="layer" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="905.1372px" height="1100px" viewBox="0 300 721.464 889.561" enable-background="new 0 0 721.464 889.561" xml:space="preserve"> <g id="section3"> <path id="section" d="m 433.125,729.14792 -0.17857,32.67857 32.32143,0.44643 15.89286,-0.44643 11.78571,-3.03572 -11.33928,-35.26785 -19.82143,5.625 z"/> </g> I've tried all sorts of way.. getelementbyid, d3.select("#id").. can anyone help?
Selecting by ID: d3.select("#section3") Check this demo, clicking on your path (you'll have to scroll down to find it): d3.select("#section3").on("click", function(){ console.log("hello"); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <svg version="1.1" id="layer" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="905.1372px" height="1100px" viewBox="0 300 721.464 889.561" enable-background="new 0 0 721.464 889.561" xml:space="preserve"> <g id="section3"> <path id="section" d="m 433.125,729.14792 -0.17857,32.67857 32.32143,0.44643 15.89286,-0.44643 11.78571,-3.03572 -11.33928,-35.26785 -19.82143,5.625 z"/> </g>
Why don't the circles show up?
I built some SVG with d3.js but nothing is displayed. Why? Here is part of code: <svg width="863" height="863" id="svgId"> <g transform="translate(431.5,431.5)"> <g class="asdf" r="421.5"> <circle transform="translate(0,0)" style="fill: rgb(255, 0, 0);"></circle> </g> <g class="asdf" r="127.6354829132969"> <circle transform="translate(-118.50486492278469,167.13470131539657)" style="fill: rgb(255, 0, 0);"></circle> </g> </g>
You've set the radius (r attribute) on the <g> element where it does nothing and not on the <circle> element where it's required. What you need is this... <svg width="863" height="863" id="svgId"> <g transform="translate(431.5,431.5)"> <g class="asdf"> <circle r="421.5" transform="translate(0,0)" style="fill: rgb(255, 0, 0);"></circle> </g> <g class="asdf"> <circle r="127.6354829132969" transform="translate(-118.50486492278469,167.13470131539657)" style="fill: rgb(255, 0, 0);"></circle> </g> </g> </svg>