Reverse SVG line drawing animation - css

I'm trying to reverse how this SVG line animates. I need the line to draw from left to right but can only get it to work right to left. I tried changing the end point in illustrator but this only led to it drawing from both sides. How do I do this? You can see the animation here: http://mckeever02.github.io/voxbit/
This is the SVG:
<svg viewBox="0 0 759.7 234.2">
<path class="phone-line" stroke="#fff" stroke-width="4" stroke-dashoffset="20" fill="none" class="st0" d="M755.6,229.7H540.1c-31.9,0-57.6-27-57.6-58.9l0-5.8V61.6c0-31.9-26.1-58-58-58h-40.8h-7.9H335
M755.6,229.7H540.1c-31.9,0-57.6-27-57.6-58.9l0-5.8V61.6c0-31.9-26.1-58-58-58h-40.8h-7.9H335
c-31.9,0-58,26.1-58,58v103.3v6.8c0,31.9-26.1,58-58,58H11.55" />
</svg>
and the CSS to animate it:
.phone-line {
stroke-dasharray:1400;
-webkit-animation: draw 4s ease-in;
}
#-webkit-keyframes draw {
from {
stroke-dashoffset: 1400;
}
to {
stroke-dashoffset: 0;
}
}

As you would be aware, the stroke-dasharray property creates a dashed line pattern. When the value is assigned as 1400 it means that the length of the dash and the space between the dashes is 1400. That is for 0 to 1400 the line will be present and from 1400 to 2800 a dash would be present.
Now when you change the stroke-dashoffset from 1400 to 0 it brings the line into view from one direction. Initially the offset is at 1400 and thus only the dash is visible (no line). When the offset is animated to 0, the dash moves out towards the left and the line (that is present from 0 to 1400) slowly comes into view.
A simple method to do it from the other direction would be to animate it from 1400 to 2800. When this is done, the dash moves out towards the right as the line (that is present from 2800 to 4200) slowly comes into view.
.phone-line {
stroke-dasharray: 1400;
animation: draw 4s ease-in;
}
#keyframes draw {
from {
stroke-dashoffset: 1400;
}
to {
stroke-dashoffset: 2800;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<svg viewBox="0 0 759.7 234.2">
<path class="phone-line" stroke="#000" stroke-width="4" stroke-dashoffset="20" fill="none" class="st0" d="M755.6,229.7H540.1c-31.9,0-57.6-27-57.6-58.9l0-5.8V61.6c0-31.9-26.1-58-58-58h-40.8h-7.9H335
M755.6,229.7H540.1c-31.9,0-57.6-27-57.6-58.9l0-5.8V61.6c0-31.9-26.1-58-58-58h-40.8h-7.9H335
c-31.9,0-58,26.1-58,58v103.3v6.8c0,31.9-26.1,58-58,58H11.55" />
</svg>
Another approach (as mentioned by Paul LeBeau in comments) would be to animate it from -1400 to 0. This also produces the same output as the above snippet.
.phone-line {
stroke-dasharray: 1400;
animation: draw 4s ease-in;
}
#keyframes draw {
from {
stroke-dashoffset: -1400;
}
to {
stroke-dashoffset: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<svg viewBox="0 0 759.7 234.2">
<path class="phone-line" stroke="#000" stroke-width="4" stroke-dashoffset="20" fill="none" class="st0" d="M755.6,229.7H540.1c-31.9,0-57.6-27-57.6-58.9l0-5.8V61.6c0-31.9-26.1-58-58-58h-40.8h-7.9H335
M755.6,229.7H540.1c-31.9,0-57.6-27-57.6-58.9l0-5.8V61.6c0-31.9-26.1-58-58-58h-40.8h-7.9H335
c-31.9,0-58,26.1-58,58v103.3v6.8c0,31.9-26.1,58-58,58H11.55" />
</svg>
Note: Ideal approach in my view would be to change the direction of your path itself to start from the left and move to the right instead of go from right to left. This is only a simple workaround to reverse the direction without altering the path.

Related

SVG stroke dash array CSS animation reverses course?

I have a simple path, to which i'm applying a dash array and a dash offset with CSS. Then I'm animating this simple construct. The animation changes the dash array and offset to decrease and then increase size again.
The odd thing is, the movement appears to reverse halfway through. Can anyone help with this? I'm sure it's not actually reversing, but that the math is causing an unexpected visual effect.
.path {
stroke-dasharray: 10;
stroke-dashoffset: 10 30;
animation: dash 5s linear infinite;
}
#keyframes dash {
50%{
stroke-dashoffset: 35%;
stroke-dasharray: 0 87.5%;
}
}
<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="340px" height="333px" viewBox="0 0 340 333" enable-background="new 0 0 340 333" xml:space="preserve">
<path class="path" fill="#FFFFFF" stroke="#000000" stroke-width="4" stroke-miterlimit="10" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
C46.039,146.545,53.039,128.545,66.039,133.545z"/>
</svg>
For props the above is a very boiled down version of this beautiful work.
per MDN
If a keyframe rule doesn't specify the start or end states of the animation (that is, 0%/from and 100%/to), browsers will use the element's existing styles for the start/end states. This can be used to animate an element from its initial state and back.
You've got one keyframe at 50% so animation goes to that at half-time and then back to the initial state at full time.

How to clip border partially with CSS (or SVG)?

I want to clip border of div which have some border-radius to imitate how timer expires.
But can't find any way to do it except like with clip-path: polygon(...)
But building custom polygon seems like really hard way to control border length.
Is there some simpler/ more elegant way to do it with CSS (or maybe SVG)?
Here is image of desirable result with few states ⇩⇩
pure svg
The effect of drawing a line is achieved using the attribute of the line stroke-dashoffset, which is an indent from the beginning of the line.
The line is hidden when stroke-dashoffset has a maximum value and is fully visible whenstroke-dashoffset = "0"
Therefore, changing the value of stroke-dashoffset from max to zero, we get the effect of drawing the line.
<svg version="1.1" id="map_line_svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300" viewBox="0 0 300 300" >
<rect x="50" y="100" width="200" height="100" rx="50" fill="#E0E9F6" stroke-width="4" stroke="grey" stroke-dashoffset="600" stroke-dasharray="600">
<animate attributeName="stroke-dashoffset" begin="1s" from="600" to="0" dur="7s" repeatCount="indefinite" />
</rect>
</svg>
CSS+SVG
This example is exactly the same as the first example, but the styles of the display style are transferred to an external stylesheet. More information on the drawing technique can be found here - Chris Coyier - stroke-dashoffset
You correctly noticed that the length of the line can be calculated using the JS method - getTotalLength ()
Here is an example of a script that prints the length of the path for figures drawn with path:
<script>
function TotalLength(){
var path = document.querySelector('#check');
var len = Math.round(path.getTotalLength() );
alert("Path length - " + len);
};
</script>
Below is a complete example of animation:
#rect1 {
stroke-dasharray: 600;
stroke-dashoffset: 600;
animation: dash 5s linear alternate infinite;
}
#keyframes dash {
from {
stroke-dashoffset: 600;
}
to {
stroke-dashoffset: 0;
}
}
#rect1 {
fill:#E0E9F6;
stroke-width:4;
stroke:grey;
}
<svg version="1.1" id="map_line_svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300" viewBox="0 0 300 300" >
<rect id="rect1" x="50" y="100" width="200" height="100" rx="50" />
</svg>
If you need an animation of the movement of the line in one direction, replace the alternate with forwards
I think that you do not need to animate the offset in this case. In the case of passing through the zero point as well as if you want to start not from the zero point problems may arise.
I would use 2 parameters - the stroke length and the stroke space, like:
<animate attributeName="stroke-dasharray" from="0 600" to="600 0" />

Odd shape SVG Animation

I have this so far on codepen
https://codepen.io/phfilly/pen/gXbmmO?editors=1100
<div class="container">
<svg viewBox="-5 0 62.772 74.316" class="logo">
<path d="M43.034,33.66" class="logo-line"></path>
<path d="M9.607,33.012" class="logo-line-1"></path>
<path class="logo-line-two" d="M26.256,54.721c-9.245,0-16.766-7.59-16.766-16.92c0-4.496,1.729-8.73,4.867-11.921L33.171,6.882l5.514,5.561
l-6.921,6.99l6.344,6.4c0,0,0,0.001,0.001,0.001l0.002,0.002c3.168,3.196,4.911,7.445,4.911,11.964
C43.021,47.129,35.501,54.721,26.256,54.721z M26.253,24.995l-6.373,6.436c-1.67,1.698-2.595,3.965-2.595,6.37
c0,4.992,4.024,9.054,8.97,9.054c4.946-0.001,8.972-4.062,8.972-9.054c0-2.419-0.934-4.692-2.631-6.404L26.253,24.995z"></path>
<path class="logo-line-three" d="M26.387,64.316c-7.049,0-13.675-2.77-18.659-7.799C2.744,51.488-0.001,44.801,0,37.688
c0-7.076,2.722-13.739,7.663-18.763L26.394,0l5.515,5.56L13.186,24.476c-3.474,3.532-5.391,8.227-5.391,13.212
c0,5.012,1.933,9.725,5.444,13.268c3.511,3.543,8.181,5.494,13.147,5.494c10.252,0,18.591-8.416,18.591-18.762
c0-5.015-1.936-9.729-5.45-13.272h0.001l-9.11-9.192l5.512-5.564l9.114,9.199c4.984,5.028,7.729,11.715,7.729,18.83
C52.772,52.37,40.936,64.316,26.387,64.316z"></path>
</svg></div>
.logo path {
/* fill: #ff5825; */
/* transition: fill 0.5s; */
}
.container {
width: 100px;
display: block;
margin: auto;
padding: 50px 15px;
}
.logo-line-two, .logo-line-three {
fill: transparent;
stroke: #ff5825;
stroke-width: 1px;
stroke-dasharray: 320 320;
stroke-dashoffset: -300;
animation: dash 6s linear .5s infinite alternate;
}
#keyframes dash {
0% {
stroke-dashoffset: -300;
}
30% {
stroke-dashoffset: 0;
}
60% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -300;
}
}
but I’m lacking a bit of knowledge on the SVG animation side of things. I would like to animate the fill colour instead (which i commented out to show the animation i’m after) and not necessarily the stroke-dash.
From my findings and research it seems that this can only be achieved by using a clipPath or is there an easier way around it? I’m not sure what attributes to use as the clipPath if that is the way.
Any help or guidelines will be greatly appreciated.
Animating fills can be messy and complicated. Since your logo consists of line segments with constant width, it makes more sense to draw it as an animated path with a stroke that matches the width of these line segments.
This is a vague approximation of what you're after; you'll have to sort out the geometry yourself.
#logo {
stroke-dasharray: 1100;
stroke-dashoffset: 1100;
animation: draw 2s forwards;
}
#keyframes draw {
to {
stroke-dashoffset: 0;
}
}
<svg width="125" height="150" viewBox="0 0 250 300">
<g transform="translate(125,170)">
<path id="logo" stroke="#000" stroke-width="30"
fill="none" stroke-linecap="butt"
d="M10.6-152.0-70.7-70.7A100 100 0 1 0 70.7-70.7L28.7
-112.7-42-42A59.4 59.4 0 1 0 42-42L10.6-73.4"
/>
</svg>
Note: If you're not sure what's going on in the <path> element, you should perhaps read up on SVG's elliptical arc commands.
The three (?) parts of your logo all have consistent width, so just redraw your logo using three thick lines rather than three outlines.

Determine startpoint svg animation

I have exported an svg file from Illustrator.
Now I'm animating the line work. I know how to change the direction of animating but how (if) is it possible to determine the startpoint of the animation?
Here is an example:
#keyframes lines { 0% {fill: none;} 50% {fill: none; stroke-dashoffset: 0;} 100% {fill: none ;stroke-dashoffset: 0;} }
.nose_outer{ animation: lines 4s ease forwards; stroke-dasharray: 186.514; stroke-dashoffset: -186.514; }
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 768 768">
<title>svg</title>
<g><!-- NOSE OUTER -->
<path class="nose_outer" d="M396.667,406.31A17.016,17.016,0,0,0,381,416.686a17.008,17.008,0,1,0,0,13.266,17.011,17.011,0,1,0,15.667-23.642Z" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="5"/>
</g>
</svg>
By using negative and positive values on the stroke-dashoffset it's possible to change the direction.
Do I have to change something in Illustrator before exporting to svg?

How can I get an animated SVG to start "drawing itself" sooner?

I'm trying to create a loading animation with ONLY html & css that looks like an ekg readout. I have it working but I want it to start redrawing sooner (right now it completely disappears and I'd like it to start drawing the before it finishes "undrawing"
<head>
<style>
body {
background-color: #fff;
}
.path {
animation: draw 2.2s infinite ease-in-out;
-webkit-animation: draw 2.2s infinite ease-in-out;
}
#keyframes draw {
from {
stroke-dashoffset: 1100;
}
to { stroke-dashoffset: 50}
}
#-webkit-keyframes draw {
from {
stroke-dashoffset: 1100;
}
to { stroke-dashoffset: 50}
}
</style>
</head>
<div class="bg">
<svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236">
<path class="path" stroke="#ca6728" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="500" stroke-dashoffset="610" fill="none" d="M0,80.9h20.6c0.5,0,1.4-0.2,1.8-0.5L38,70.1
c0.5-0.3,1.2-0.3,1.6,0l12.7,9.4c0.4,0.3,1.3,0.6,1.8,0.6l13.3,0c0.6,0,1.2,0.4,1.5,0.9l6.2,11.3c0.3,0.5,0.5,0.4,0.5-0.1l4.4-90.8
c0-0.5,0.1-0.5,0.1,0l6.9,102.1c0,0.5,0.2,0.6,0.4,0l7-22.4c0.2-0.5,0.7-1,1.3-1l16.1,0c0.5,0,1.3-0.3,1.8-0.7L129,66.4
c0.4-0.4,1.1-0.3,1.5,0l13.3,13.1c0.4,0.4,1.2,0.7,1.7,0.7l20.1,0,"/>
</svg>
</div>
</html>
JS Fiddle here: https://jsfiddle.net/jzvenice/4sLw9ag9/
I think a similar effect can be achieved by playing with the stroke-dasharray values :
https://jsfiddle.net/4sLw9ag9/2/
...
stroke-dasharray="391 300" stroke-dashoffset="0"
....
#keyframes draw {
from {
stroke-dashoffset: 691;
}
to {
stroke-dashoffset: 0}
}
...
Only the first value is exact (length of the path is 391 pixels), it was detected with a line of JavaScript that is commented out and not needed for further functionality. The other value can be adjusted for what comes across best visually.
Edit - previously deleted the answer but it seems more relevant than a comment. So don't mind me undeleting with a minor update.

Resources