Animate SVG fill from left to right - css
I have this SVG that I want to smoothly fill from left to right. How can I do that using CSS?
I don't want the line to be moving, i want it filling smoothly from left to right while staying in the same place, that's why i'm using svg.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="324" height="25" viewBox="0 0 324 25">
<g id="btn_underline">
<path id="V" d="M88.029,0.613 C58.722,-0.156 29.992,3.400 1.839,11.183 C-1.140,12.047 0.205,16.660 3.184,15.795 C28.262,8.781 54.014,5.321 80.438,5.321 C83.801,5.321 86.203,5.321 87.836,5.417 C96.196,5.610 105.324,6.282 115.413,7.339 C125.503,8.396 133.958,9.453 140.588,10.510 C147.218,11.471 156.346,12.912 167.781,14.834 C182.098,17.236 194.397,19.158 204.582,20.599 C223.511,23.194 240.519,24.443 255.412,24.443 C259.256,24.443 262.138,24.443 264.060,24.347 C274.726,23.962 284.623,23.001 293.655,21.368 C303.936,19.542 313.449,17.044 322.385,13.873 C323.634,13.489 324.307,12.047 323.826,10.798 C323.250,9.357 322.193,8.877 320.751,9.357 C311.815,12.624 302.495,15.026 292.790,16.660 C283.758,18.197 274.149,19.158 263.868,19.542 C246.668,20.023 227.066,18.774 205.159,15.795 C195.742,14.546 183.539,12.624 168.549,10.126 C156.635,8.108 147.506,6.667 141.069,5.706 C134.631,4.745 126.271,3.688 115.990,2.631 C105.709,1.478 96.388,0.805 88.029,0.613 z" fill="#00363B" />
</g>
</svg>
http://codepen.io/anon/pen/GrQPvK
You can indeed do this in CSS with the stroke property.
I'm sorry by advance, I can't use your SVG because it's a shape and in order to make your effect you only need a path without fill. So I take this SVG for the example (from this article : https://jakearchibald.com/2013/animated-line-drawing-svg/):
<svg xmlns="http://www.w3.org/2000/svg" height="98" width="581" viewBox="0 0 581 98">
<path
class="path"
d="M62.9 14.9c-25-7.74-56.6 4.8-60.4 24.3-3.73 19.6 21.6 35 39.6 37.6 42.8 6.2 72.9-53.4 116-58.9 65-18.2 191 101 215 28.8 5-16.7-7-49.1-34-44-34 11.5-31 46.5-14 69.3 9.38 12.6 24.2 20.6 39.8 22.9 91.4 9.05 102-98.9 176-86.7 18.8 3.81 33 17.3 36.7 34.6 2.01 10.2.124 21.1-5.18 30.1"
stroke="#000"
stroke-width="4.3"
fill="none">
</path>
</svg>
Notice the stroke and stroke-width properties. It's the beginning of the trick ;). Then you need to add some CSS :
.path {
//we divide the line in multiple dashes (some full and other empty)
//these dashes have 1000px in length
//so there are one dash full of 1000px of length and then one dash empty of 1000px of length and so on and so forth
stroke-dasharray: 1000;
//we change the position of the dashes
stroke-dashoffset: 1000;
//now we animate the dashoffset
//we reduce the offset of each dash so we have the impression that the dashes are moving
animation: dash 5s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
And that's it !
For more information, you can read this article too : https://css-tricks.com/svg-line-animation-works/
You could work from this.
svg {
left: -400px;
position:absolute;
}
#keyframes example {
from {left: -400px;}
to {left: 200px;}
}
#-webkit-keyframes example {
from {left: -400px;}
to {left: 200px;}
}
svg {
animation-name: example;
animation-duration: 4s;
animation-delay: 2s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
ccodepen: http://codepen.io/anon/pen/egVbMV
Try this
.fadeIn {
animation-name: fade-in-left;
animation-duration: 1s;
}
#keyframes fade-in-left {
0% {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
100% {
opacity: 1;
transform: none;
}
}
Live demo - http://codepen.io/anon/pen/MJQLgG
Related
Dripping SVG clip-path on animation
In the following example, I apply a clip-path and animate a block in that path to simulate pouring. The issue is, while it looks like it's rendering well in Safari, we can see the box boundaries of the animated path in Chrome. Any idea why, and how to get rid of them? .fill { animation-name: fillAction; animation-iteration-count: 1; animation-timing-function: cubic-bezier(.2, .6, .8, .4); animation-duration: 4s; animation-fill-mode: forwards; } #waveShape { animation-name: waveAction; animation-iteration-count: infinite; animation-timing-function: linear; animation-duration: 2s; fill: #300f0f; } #keyframes fillAction { 0% { transform: translate(0, 700px); } 100% { transform: translate(0, 250px); } } #keyframes waveAction { 0% { transform: translate(380px, 0); } 100% { transform: translate(-235px, 0); } } <svg class="h-full w-full" viewBox="0 0 1500 1500"> <defs> <clipPath id="drop"> <path d="M 537.5,714.5 C 744.168,714.167 950.834,714.5 1157.5,715.5C 1170.62,825.317 1137.29,918.15 1057.5,994C 970.54,1067.47 871.54,1090.14 760.5,1062C 667.845,1033.01 601.012,974.512 560,886.5C 536.431,831.281 528.931,773.948 537.5,714.5 Z" /> </clipPath> </defs> <g clip-path="url(#drop)"> <g class="fill"> <path id="waveShape" d="M 265.5,488.5 C 265.897,487.475 266.563,487.308 267.5,488C 266.906,488.464 266.239,488.631 265.5,488.5 Z M 888.5,488.5 C 888.897,487.475 889.563,487.308 890.5,488C 889.906,488.464 889.239,488.631 888.5,488.5 Z M 248.5,490.5 C 258.172,490.334 267.839,490.5 277.5,491C 292.931,492.686 308.264,495.019 323.5,498C 340.141,499.478 356.808,499.811 373.5,499C 407.587,492.498 441.92,490.831 476.5,494C 502.019,497.965 527.686,500.132 553.5,500.5C 564.855,500.46 576.188,499.96 587.5,499C 618.82,494.292 650.32,492.126 682,492.5C 705.194,492.581 728.36,493.414 751.5,495C 769.224,497.858 787.058,499.692 805,500.5C 827.502,499.666 849.668,496.5 871.5,491C 884.529,490.231 897.529,490.564 910.5,492C 922.5,494 934.5,496 946.5,498C 963.141,499.478 979.808,499.811 996.5,499C 1030.59,492.498 1064.92,490.831 1099.5,494C 1125.02,497.965 1150.69,500.132 1176.5,500.5C 1187.86,500.46 1199.19,499.96 1210.5,499C 1259.65,492.451 1308.99,490.784 1358.5,494C 1371.26,494.455 1383.93,495.788 1396.5,498C 1395.48,498.519 1394.82,499.353 1394.5,500.5C 1395.5,753.146 1395.83,1005.81 1395.5,1258.5C 978.833,1258.5 562.167,1258.5 145.5,1258.5C 145.5,1004.83 145.5,751.167 145.5,497.5C 180.445,502.459 214.778,500.126 248.5,490.5 Z" /> </g> </g> </svg>
As a possible solution you can use a mask instead: .fill { animation-name: fillAction; animation-iteration-count: 1; animation-timing-function: cubic-bezier(.2, .6, .8, .4); animation-duration: 4s; animation-fill-mode: forwards; } #waveShape { animation-name: waveAction; animation-iteration-count: infinite; animation-timing-function: linear; animation-duration: 2s; fill: #300f0f; } #keyframes fillAction { 0% { transform: translate(0, 700px); } 100% { transform: translate(0, 250px); } } #keyframes waveAction { 0% { transform: translate(380px, 0); } 100% { transform: translate(-235px, 0); } } <svg class="h-full w-full" viewBox="0 500 1500 1000"> <defs> <mask id="drop"> <rect y="500" width="1500" height="1000" /> <path d="M 537.5,714.5 C 744.168,714.167 950.834,714.5 1157.5,715.5C 1170.62,825.317 1137.29,918.15 1057.5,994C 970.54,1067.47 871.54,1090.14 760.5,1062C 667.845,1033.01 601.012,974.512 560,886.5C 536.431,831.281 528.931,773.948 537.5,714.5 Z" fill="white" /> </mask> </defs> <g mask="url(#drop)"> <g class="fill"> <path id="waveShape" d="M 265.5,488.5 C 265.897,487.475 266.563,487.308 267.5,488C 266.906,488.464 266.239,488.631 265.5,488.5 Z M 888.5,488.5 C 888.897,487.475 889.563,487.308 890.5,488C 889.906,488.464 889.239,488.631 888.5,488.5 Z M 248.5,490.5 C 258.172,490.334 267.839,490.5 277.5,491C 292.931,492.686 308.264,495.019 323.5,498C 340.141,499.478 356.808,499.811 373.5,499C 407.587,492.498 441.92,490.831 476.5,494C 502.019,497.965 527.686,500.132 553.5,500.5C 564.855,500.46 576.188,499.96 587.5,499C 618.82,494.292 650.32,492.126 682,492.5C 705.194,492.581 728.36,493.414 751.5,495C 769.224,497.858 787.058,499.692 805,500.5C 827.502,499.666 849.668,496.5 871.5,491C 884.529,490.231 897.529,490.564 910.5,492C 922.5,494 934.5,496 946.5,498C 963.141,499.478 979.808,499.811 996.5,499C 1030.59,492.498 1064.92,490.831 1099.5,494C 1125.02,497.965 1150.69,500.132 1176.5,500.5C 1187.86,500.46 1199.19,499.96 1210.5,499C 1259.65,492.451 1308.99,490.784 1358.5,494C 1371.26,494.455 1383.93,495.788 1396.5,498C 1395.48,498.519 1394.82,499.353 1394.5,500.5C 1395.5,753.146 1395.83,1005.81 1395.5,1258.5C 978.833,1258.5 562.167,1258.5 145.5,1258.5C 145.5,1004.83 145.5,751.167 145.5,497.5C 180.445,502.459 214.778,500.126 248.5,490.5 Z" /> </g> </g> </svg> I've changed the viewBox of the svg element because I wanted the animation in the view but you can change it back to what you want.
How to animate handwriting text on the web page using SVG?
I am trying to animate a text that I created and saved as SVG. So far, I've only been able to animate the stroke, but that's not what I am trying to achieve. How can I implement animation like the two examples, below? http://codepen.io/se7ensky/pen/waoMyx https://codepen.io/munkholm/pen/EaZJQE Here is what I have so far: .test { width: 300px /* margin:0 auto; */ } .l1 { animation: dash 15s 1; stroke-linecap: round; stroke-miterlimit: 10; stroke-dasharray: 300; stroke-dashoffset: 300; animation-fill-mode: forwards; /*fill: none;*/ } .l2 { stroke-dasharray: 300; stroke-dashoffset: 300; animation: dash 20s linear forwards; -webkit-animation-delay: 1s; /* Chrome, Safari, Opera */ animation-delay: 1s; } .l3 { stroke-dasharray: 300; stroke-dashoffset: 300; animation: dash 25s linear forwards; -webkit-animation-delay: 2.5s; /* Chrome, Safari, Opera */ animation-delay: 2.5s; } .l4 { stroke-dasharray: 300; stroke-dashoffset: 300; animation: dash 25s linear forwards; -webkit-animation-delay: 4.5s; /* Chrome, Safari, Opera */ animation-delay: 4.5s; } #keyframes dash { to { stroke-dashoffset: 0; } } <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg class="test" 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" viewBox="0 0 30.1 21.8" style="enable-background:new 0 0 30.1 21.8;" xml:space="preserve"> <g> <path class="text l1" d="M16.5,9.2c-0.2-0.2-0.2-1,0.1-1.5c0.1-0.1,0.2-0.3,0.3-0.4c-1.6,0-3.2-0.3-4.7-0.1C10.8,7.3,9.5,8,9.3,8.9 c-0.1,0.6,0.5,0.8,0.7,1c0.1,0.1,0,0.2-0.1,0.1C9.5,10,8.7,9.4,9,8.7c0,0,0-0.1,0-0.2c0.3-1.2,1.7-1.8,3.3-1.9 c1.8-0.1,3.9,0.4,4.8,0.4c0.2-0.2,0.4-0.4,0.5-0.4c0.3-0.1,0.6,0.1,0.3,0.4c-0.1,0.1-0.4,0.3-0.6,0.5c-0.4,0.4-0.8,1-0.5,1.5 C16.8,9.2,16.7,9.3,16.5,9.2z M12.1,12.8c0.1,0.1-0.1,0.3-0.1,0.3c-0.2,0.3-0.5,0.8-0.8,0.8c-0.1,0-0.5-0.1-0.5-0.1 c-0.1-0.8,1.5-3.5,1.9-4.2c0.2-0.3,0.1-0.4,0.1-0.5c0.1-0.4,0.9-1.4,1.5-1.4c0.2,0,0.8,0.2,0.7,0.5c0,0-0.1-0.1-0.2-0.1 c-1.1,0-2.9,3.6-3.4,4.7c-0.3,0.7,0.1,0.6,0.4,0.3C11.8,13,12,12.8,12.1,12.8z" fill="red" stroke="#000" stroke-miterlimit="10" stroke-width="0.5" /> <path class="text l2" d="M14.4,12.3c-0.2,0-0.3-0.2-0.1-0.2c0.4,0,1.1-0.4,1.5-0.8c0.2-0.2,0.6-0.5,0.5-0.8c0-0.3-0.4-0.2-0.6-0.1 c-0.7,0.3-1.7,1.3-2,2.2c-0.3,1,0.6,1,1.4,0.7c0.9-0.4,1.7-1,2.1-1.7c0-0.1,0.1-0.1,0.1,0c0.1,0,0.1,0.1,0,0.1 c-0.5,0.8-1.2,1.5-2.1,1.8c-1.2,0.5-2.8,0-2.1-1.5c0.4-0.8,2.2-2.4,3.1-2.1c0.5,0.2,0.4,0.8,0.2,1.1C16.1,11.8,15,12.2,14.4,12.3z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5" /> <path class="text l3" d="M17.3,13.6c-0.2,0.2-0.1,0.5,0.4,0.4c0.6-0.2,1.5-0.9,1.5-1.6c0-0.3-0.7-0.6-0.9-0.7c-0.2-0.1-0.3-0.3-0.4-0.4 c-0.1,0.2-0.3,0.5-0.5,0.8c-0.1,0.1-0.3,0-0.2-0.1c0.3-0.5,0.6-0.9,0.6-1.1c0.1-0.9,1.7-1.7,2.6-1.7c0.5,0,1,0.3,0.7,0.8 c-0.1,0.2-0.2,0.3-0.4,0.4c-0.1,0-0.2,0-0.1-0.2c0.2-0.2,0.3-0.6,0-0.6c-0.4,0-1,0.2-1.3,0.4c-0.4,0.2-0.7,0.4-1,0.9 c-0.3,0.3-0.2,0.6,0.1,0.8c0.8,0.5,1.8,0.8,0.9,1.8c-0.4,0.5-1.1,0.7-1.7,0.9c-0.2,0-0.7,0.1-0.9-0.1c-0.1-0.1,0-0.3,0.2-0.5 c0.1-0.1,0.3-0.3,0.6-0.3c0.1,0,0.1,0.1,0,0.1C17.5,13.4,17.3,13.5,17.3,13.6z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"/> <path class="text l4" d="M23.6,10.2c-0.2,0.1-0.8,0.1-1.4,0.2c-0.2,0.3-0.3,0.5-0.3,0.6c-0.4,0.7-0.7,1.4-0.7,1.7c-0.1,0.5,0.2,0.8,0.6,0.6 c0.4-0.2,1.3-1,1.8-1.7c0.1-0.1,0.2,0,0.1,0.1c-0.2,0.4-1,1.2-1.6,1.6c-0.4,0.3-1.3,0.6-1.5-0.1c-0.1-0.3,0.1-0.9,0.4-1.5 c-0.1,0.1-0.2,0.3-0.5,0.6c-0.1,0.1-0.2,0-0.1-0.2c0.4-0.5,0.7-1,0.9-1.2c0,0,0.1-0.2,0.3-0.5c-0.1,0-0.2,0-0.3,0 c-0.1,0-0.2-0.1-0.2-0.3c0.1-0.2,0.4-0.2,0.6-0.2c0,0,0,0,0,0l0.6-1.1c0.3-0.5,0.3-0.6,0.5-0.7c0.2,0,0.4,0,0.5,0.1 c0.1,0.1,0,0.4-0.1,0.5C23.2,9,23.1,9,23,9.1l-0.6,1l0.2,0c0.4,0,0.7-0.1,1.1-0.1C23.9,10,24.1,10.1,23.6,10.2z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"/> </g> <g></g> <g></g> <g></g> <g></g> <g></g> <g></g> </svg> View on CodePen
How the Se7ensky animation works is that it uses the standard dash animation technique, but clips the animated stroke with an outline representing the hand-drawn look of the logo. So the standard dash animation technique works as follows. You take a standard line: <svg> <path d="M 10,75 L 290,75" stroke="red" stroke-width="50"/> </svg> Then you add a dash pattern to it and animate it's position (stroke-dashoffset). .pen { stroke-dasharray: 280 280; stroke-dashoffset: 280; animation-duration: 2s; animation-name: draw; animation-iteration-count: infinite; animation-direction: alternate; animation-timing-function: linear; } #keyframes draw { from { stroke-dashoffset: 280; } to { stroke-dashoffset: 0; } } <svg> <path class="pen" d="M 10,75 L 290,75" stroke="red" stroke-width="50"/> </svg> Finally to get the fancy variable stroke width of the Se7ensky example, you clip that line with the outline of your logo. So let's pretend this simple path below represents your logo: <svg> <path stroke="black" stroke-width="1" fill="lightgrey" d="M 40,50 C 110,55 195,60, 265,55 C 290,55 290,85 265,85 C 195,85 110,85 40,100 C 0,100 0,50 40,50 Z"/> </svg> We turn that into a clipPath element and use it to trim our animated stroke to the shape of our logo: .pen { stroke-dasharray: 280 280; stroke-dashoffset: 280; animation-duration: 2s; animation-name: draw; animation-iteration-count: infinite; animation-direction: alternate; animation-timing-function: linear; } #keyframes draw { from { stroke-dashoffset: 280; } to { stroke-dashoffset: 0; } } <svg> <clipPath id="logo"> <path d="M 40,50 C 110,55 195,60, 265,55 C 290,55 290,85 265,85 C 195,85 110,85 40,100 C 0,100 0,50 40,50 Z"/> </clipPath> <path class="pen" d="M 10,75 L 290,75" stroke="red" stroke-width="50" clip-path="url(#logo)"/> </svg> So to replicate their example, you'll need to add a continuous path (or paths if you want) to your SVG that represents the path that a pen would take if it were writing the letters in your logo. Then animate that path using the dashoffset technique while clipping it with your original logo. Update Here's a final demo with a more realistic letter shape: // Simple code to enable and disable the clipping path var chk = document.getElementById("chk"); var penpath = document.getElementById("penpath"); chk.addEventListener("input", function(evt) { if (evt.target.checked) { penpath.classList.add("clipped"); } else { penpath.classList.remove("clipped"); } }); .pen { fill: none; stroke: red; stroke-width: 18; stroke-linecap: round; stroke-dasharray: 206 206; stroke-dashoffset: 206; animation-duration: 2s; animation-name: draw; animation-iteration-count: infinite; animation-direction: alternate; animation-timing-function: linear; } .clipped { clip-path: url(#logo); } #keyframes draw { from { stroke-dashoffset: 206; } to { stroke-dashoffset: 0; } } <svg> <defs> <clipPath id="logo"> <path d="m85.77 49.77c-10.59 8.017-27.38 21.95-41.58 21.95-6.396 0-12.99-2.481-12.39-9.735l0.3998-4.199c38.38-12.03 48.17-26.15 48.17-35.5 0-7.635-7.995-9.162-14.39-9.162-25.98-0.1909-54.97 25.39-54.17 50.39 0.3998 12.6 7.196 25.01 21.79 25.01 19.79 0 41.78-17.94 53.97-31.5zm-52.37-1.336c5.397-12.6 16.99-21.76 26.98-24.24 1.399-0.3818 2.399 0.7635 2.399 2.1 0.1999 3.245-11.79 16.42-29.38 22.14z"/> </clipPath> </defs> <path id="penpath" d="m39.02 51.1c5.361-1.771 10.04-4.182 15.98-7.857 6.019-3.933 9.841-7.728 12.77-10.71 1.403-1.369 12.03-15.97-7.857-13.93-9.824 1.01-19.62 8.3-26.16 14.91-6.538 6.61-10.42 14.51-11.96 22.23-2.559 12.76 1.807 26.19 21.07 23.48 13.96-1.965 32.59-14.55 43.66-25.54" class="pen clipped"/> </svg> <p> <input id="chk" type="checkbox" checked="true"/> <label for="chk">Enable clipping path</label> </p>
The example looks like a combination of svg paths and delayed animations. This blog post by CSS-Tricks explains it pretty well (Note that the svg must have strokes for this to work): https://css-tricks.com/svg-line-animation-works/ Here's a guide on stroke-dashoffset (used on the example) that might be useful: https://css-tricks.com/almanac/properties/s/stroke-dashoffset/
SVG handwriting animation without using stroke properties
I'm trying to work on a SVG handwriting animation. I've already researched some tutorials but all them are using SVG stroke properties and it's not quite working for me, because in my situation the animation should be on the fill, not the stroke. I've found things like that: svg path { fill: none; stroke: #000; stroke-width: 1; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1700; stroke-dashoffset: 1700; -webkit-animation: dash 5s linear forwards; animation: dash 5s linear forwards; } #-webkit-keyframes dash { to { stroke-dashoffset: 0; } } #keyframes dash { to { stroke-dashoffset: 0; } } Here's the SVG I'm working on: http://codepen.io/boyporreta/pen/BNewgG Is there a way to create this animation using fill instead of stroke? Thanks in advance.
I thought I'd have a go at Erik's suggested method. Combining the stroke animating technique from here with his suggestion to clip I came up with this .pentip { stroke-linecap:round; stroke-linejoin:round; fill:none; stroke:#e21b1b; stroke-width:15; stroke-dasharray: 1454; stroke-dashoffset: 1454; animation: dash 5s linear forwards; } #keyframes dash { to { stroke-dashoffset: 0; } } <link href="https://fonts.googleapis.com/css?family=Pacifico" rel="stylesheet"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 341.61432 138.25008"> <defs> <clipPath id="svgTextPath"> <text x="10" y="94" font-family='Pacifico' font-size="95">Monkey</text> </clipPath> </defs> <g clip-path="url(#svgTextPath)"> <path class="pentip" d="M7.6 39.8l17.5-22 5.6 5.7-3.4 52-3 17.2L46.5 30s9.2-13.3 15-11c10.2 4.2-1.3 74-1.3 74S82 16 93.6 19.6c20.2 6-6 64 6.3 67.4 12.2 3.4 21-15 21-15l6.4-16.2 15.2-1s-19.4 5.7-19.4 6.7l-1 21.5 10.7 6.3L144 73l-8-20.4L164.5 69l2-17.7L163 90l22-36.3-.2 33.5 20.2-8.4 3-42.7 14.3-28.5 8.5 4.5s-13 46.4-14.2 47.2c-1 .7-12 28-12 28l15.2-19.6s13.6-18 17.8-12.6c4.2 5.2-11.8 28.3-11.8 28.3s-1 5.8 8 5.5c8.8-.3 19.3-14.4 25.3-16.3 6-1.8 17.6-11.2 11.5-16.7-6-5.6-21.2-1-21 8 .3 9.3 0 24.7 11.3 24.7s21.3-3 23.6-10.7c2.4-8 9.5-28.3 7-25.7-2.3 2.7-11.7 15-8.8 24.7 3 9.7 9 16.6 16 10.3 7-6.3 17.3-35.4 14.7-33.6-2.6 1.8-12 61.6-12 61.6l-12.8 15.8-12-2.7s2-4 7.2-12.2c5.3-8 32-24 36-27.3 4-3 14.6-17.3 14.6-17.3"/> </g> </svg> You'd obviously be a bit more careful with your stroke creation!
The svg engine doesn't know that the path fill in your example is handwriting, and there's no defined direction for the handwriting motion. Calligraphy makes it a little harder to accomplish since there's no built-in support for variable stroke widths in svg. However, it might be passable to do a clip-path animation, using the animation code you quoted, but on a "crude copy" of the original path which has been converted to just a thick stroke, without fill. That clip-path can then be applied to the original path in your example to give an impression of the calligraphic stroke being drawn. Another option is to not use a path, but to draw the whole thing with lots of small rectangles along the path. This implies using javascript instead of css animation.
Floating ghost CSS animation
I have created an SVG ghost for my website's logo. I have made a CSS animation so when a user hovers the logo, the ghost starts floating. Everything works okay except that when it is unhovered, the ghost just drops back to it's original position. Is it possible to have it also animated when it returns to translateY(0)? I have tried a solution myself, but it doesn't work. Here is the example: #keyframes float { 100% { transform: translateY(-8px); } } #keyframes bob { 0% { transform: translateY(-8px); } 100% { transform: translateY(0); } } #keyframes sink { 100% { transform: translateY(0); } } #logo svg { margin: 20px; overflow: visible; } #logo #ghost { animation-name: sink; animation-duration: 0.3s; animation-timing-function: ease-out; animation-delay: 0s; animation-direction: normal; animation-iteration-count: 1; animation-fill-mode: forwards; } #logo:hover #ghost { animation-name: float, bob; animation-duration: 0.3s, 0.7s; animation-timing-function: ease-out, ease-in-out; animation-delay: 0s, 0.3s; animation-direction: normal, alternate; animation-iteration-count: 1, infinite; animation-fill-mode: forwards; } <div id="logo"> <svg width="100" height="100"> <g id="ghost"> <rect fill="red" width="100" height="100" /> </g> </svg> </div>
It isn't all that difficult with JQuery. Here's a function that can be called regularly with a setInterval() timer: var haunt=function(){ var dy; ghost_ticks++; ghost_clock++; if (ghost_clock>30) ghost_clock=30; dy = Math.sin(Math.abs(ghost_clock) * Math.PI/60); /* sine wave */ dy *= -40 + 6*Math.cos(ghost_ticks/5); /* ramp */ $("#ghost").css("transform","translate(0,"+dy+"px)"); if (ghost_clock==0) { clearInterval(ghost_timer); ghost_timer=ghost_ticks=0; } } This calculates the ghost's position as the sum of two components — a sine-wave hovering motion, and a vertical offset that ramps up and down at the start and end of the animation and also controls the amplitude of the hovering. This is done with two counter variables: ghost_ticks simply increments at every tick and is used to calculate the hovering position, while ghost_clock controls the ramp by counting up to 30 and then stopping. At the end of the animation, its value is made negative, so it counts back to zero, at which point the animation stops. You can still use a CSS transition to change the ghost's colour. var ghost_ticks=0, ghost_clock=0, ghost_timer=0; var haunt=function(){ var dy; ghost_ticks++; ghost_clock++; if (ghost_clock>30) ghost_clock=30; dy = Math.sin(Math.abs(ghost_clock) * Math.PI/60); dy *= -40 + 6*Math.cos(ghost_ticks/5); $("#ghost").css("transform","translate(0,"+dy+"px)"); if (ghost_clock==0) { clearInterval(ghost_timer); ghost_timer=ghost_ticks=0; } } var start_haunting=function(){ if (ghost_clock < 0) ghost_clock = -ghost_clock; if (!ghost_clock) ghost_timer=setInterval(haunt,25); }; var stop_haunting=function(){ if (ghost_clock > 0) ghost_clock = -ghost_clock; }; $(document).ready(function(){ $("#logo").hover(start_haunting,stop_haunting); }); #logo { background-color:#000; width: 200px; height: 200px; } #logo #ghost { fill:#333; transition: fill 1s; } #logo:hover #ghost { fill:#999; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="logo"> <svg width="200" height="200" viewBox="0 0 200 200"> <g id="ghost" stroke="none"> <path d="M60 160V100A40 40 0 0 1 140 100V160l-10-10l-10 10l -10-10l-10 10l-10-10l-10 10l-10-10ZM73 100a10 10 0 0 0 20 0 10 10 0 0 0 -20 0M107 100a10 10 0 0 0 20 0 10 10 0 0 0 -20 0z" /> </g> </svg> </div>
Change direction of SVG animation
I saw this SVG animation and I'm wondering how to alter the direction that the line is erased in; currently the line retracts from the last point it is drawn, however I want the reverse; for the line to erase itself from the point where it first started to draw (so that it looks more like a loading animation). I see that the animation property on .path has a value of infinite, but I'm not sure how the direction is specified. The HTML is <div class="bg"> <svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236"> <path class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="300" stroke-dashoffset="300" fill="none" d="M343.6 75.9v20.3l23.1 21.8-23.1 21.8v20.3l44.6-42.1zM326.4 139.8l-23.1-21.8 23.1-21.8v-20.3l-44.6 42.1 44.6 42.1z"/> <path class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="500" stroke-dashoffset="500" fill="none" d="M335 38.9c-43.7 0-79.1 35.4-79.1 79.1s35.4 79.1 79.1 79.1 79.1-35.4 79.1-79.1-35.4-79.1-79.1-79.1zM335 182.9c-35.8 0-64.9-29.1-64.9-64.9s29.1-64.9 64.9-64.9 64.9 29.1 64.9 64.9-29.1 64.9-64.9 64.9z"/> </svg> </div> And the CSS is body { background-color: #fff; } .bg { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .path { animation: draw 3.5s infinite; } #keyframes draw { 50% { stroke-dashoffset: 0; } }
I like your idea of making this an loading animation: CODEPEN Now what i did: changed the animation start stop point #keyframes draw { 100% { stroke-dashoffset: -500; } } Why -500? Because this is the value of the dash-array. This is defined in the <svg>: dasharray="500" Changed this value in the inner most path. It was only 300 I added a linear animation animation: draw 5s infinite linear; The default is ease. I found the animation has better consistency with a linear animation. NOTE dashoffset=500 <- makes the animation start without the dash/stroke
I used the negative value for stroke-dashoffset that Persijn recommended. This worked great in Chrome and FF, but it didn't work properly in Safari. I've found that if you open the SVG in Illustrator, you can reverse the direction of the path, by opening the Attributes panel (you might have to click the "show more" in the top right) and literally clicking the "reverse path" button.
stroke-dasharray can be a list of white space separated dashes and gaps, so you could do something like this: var svgPath = document.getElementById('svgPath'); var pathLength = svgPath.getTotalLength(); var offset = 0; function offsetPath() { requestAnimationFrame(offsetPath); offset += 0.1; var dasharray = 0 + ' ' + offset + ' ' + (pathLength - offset); svgPath.setAttribute('stroke-dasharray', dasharray); } requestAnimationFrame(offsetPath); <svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236"> <path id="svgPath" class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="100 100 100" fill="none" d="M343.6 75.9v20.3l23.1 21.8-23.1 21.8v20.3l44.6-42.1zM326.4 139.8l-23.1-21.8 23.1-21.8v-20.3l-44.6 42.1 44.6 42.1z" /> </svg>
Changing SVG Line Animation Direction Add KeyFrames and Classes for Both Directions: .dash { stroke-dasharray : 10 5; animation : dash 4s linear infinite; } .dash_reverse { stroke-dasharray : 10 5; animation : dash_reverse 4s linear infinite; } #keyframes dash { to { stroke-dashoffset: 100; } } #keyframes dash_reverse { to { stroke-dashoffset: -100; } } Use JavaScript to Toggle Animation: function animate_line_forward(id) { $("#" + id).removeClass("dash_reverse"); $("#" + id).addClass("dash"); } function animate_line_reverse(id) { $("#" + id).removeClass("dash"); $("#" + id).addClass("dash_reverse"); } Call functions as needed (pass the SVG line id into the above functions: Calling animate_line_forward: Calling animate_line_reverse: