I have this SVG arrow that is consist of a path and a polygon. I want to animate the path and the polygon along the path.
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397" width="242.66" height="397">
<style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:4px;}</style>
<path class="cls-1" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85"/>
<polygon points="0 384.74 2.04 381.29 19 391.37 27.81 373.72 31.39 375.51 20.65 397 0 384.74"/>
</svg>
I have tried this css, and it animates the path.
path {
stroke: #000000;
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 4s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397" width="242.66" height="397">
<style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:4px;}</style>
<path class="cls-1" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85"/>
<polygon points="0 384.74 2.04 381.29 19 391.37 27.81 373.72 31.39 375.51 20.65 397 0 384.74"/>
</svg>
However, I can not figure how to move the polygon along the path with the same pace.
I have used this code that does not work.
polygon {
offset-distance: 0%;
offset-path: path('M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85');
animation: move 2.1s linear forwards infinite;
}
#keyframes move {
100% {
offset-distance: 100%;
}
}
How to animate the polygon along the same path?
The arrow will get rotated and positioned according to the offset-path.
css offset-path or svg SMIL <mpath> expect your animated element to point at the x/y origin of your svg like so:
Your arrow element is already placed on the path – the browser will add the current x/y values to the coordinates on your motion path.
In this case: your arrow disappears due to huge offsets. (see left example.)
.wrp {
padding: 1em;
//border: 1px solid #ccc;
display: inline-block;
}
svg {
display: inline-block;
width: 10em;
overflow: visible;
border: 1px solid #ccc;
}
.motionPath {
stroke: #000;
stroke-dasharray: 0 100;
animation: dash 2s linear forwards infinite;
}
.arrow {
offset-distance: 0%;
offset-path: path('M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85');
animation: move 2s linear forwards infinite;
}
polygon {
offset-distance: 0%;
offset-path: path('M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85');
animation: move 2s linear forwards infinite;
}
#keyframes dash {
to {
stroke-dasharray: 100 100;
}
}
#keyframes move {
100% {
offset-distance: 100%;
}
}
<div class="wrp">
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397">
<style>
.cls-1 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: bevel;
stroke-width: 4px;
}
</style>
<path class="cls-1 motionPath" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85" pathLength="100" />
<path class="arrow" stroke="red" fill="none" stroke-width="4" d="M-12.5 -12.5 l 12.5 12.5 l-12.5 12.5"></path>
</svg>
</div>
<div class="wrp">
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397">
<style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:4px;}</style>
<path class="cls-1 motionPath" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85" pathLength="100"/>
<polygon fill="red" style="transform:translate(-25px, -300px)" points="0 384.74 2.04 381.29 19 391.37 27.81 373.72 31.39 375.51 20.65 397 0 384.74"/>
</svg>
</div>
I have replaced your arrow with another <path> element but you can reposition your original arrow polygon in an editor like inkscape to get the right coordinates and rotation.
You will also need to set a pathLength or calculate the exact pathLength with js like path.getTotalLength()
Otherwise you can't synchronize your stroke animation with the arrow movement.
Related
I'm trying to get a svg object to follow a path.
When I use the following code, it works fine:
<svg x="0px" y="0px" viewBox="0 0 600 800">
<style>
svg {
fill: none;
stroke: black;
}
#arrow {
transform-origin: center;
transform-box: fill-box;
animation: followPath 5s infinite;
offset-path: path("M-54.918,380.7l285.5,0.5l0.5,354.5l173.1-0.1V480.1h181.5");
}
#keyframes followPath {
0% {offset-distance: 100%;}
100% {offset-distance: 0%;}
}
</style>
<polygon id="arrow" points="574.857,479.816 585.682,473.566 596.507,467.316 596.507,479.816 596.507,492.316 585.682,486.066" />
</svg>
But when I try to use a path through a url, I get nothing:
<svg x="0px" y="0px" viewBox="0 0 600 800">
<style>
svg {
fill: none;
stroke: black;
}
#arrow {
transform-origin: center;
transform-box: fill-box;
animation: followPath 5s infinite;
offset-path: url(#guide);
}
#keyframes followPath {
0% {offset-distance: 100%;}
100% {offset-distance: 0%;}
}
</style>
<path id="guide" d="M-54.918,380.7l285.5,0.5l0.5,354.5l173.1-0.1V480.1h181.5" />
<polygon id="arrow" points="574.857,479.816 585.682,473.566 596.507,467.316 596.507,479.816 596.507,492.316 585.682,486.066" />
</svg>
Having to put the paths directly on the element is no good for me, i need to reference existing paths, any help is greatly appreciated, thanks.
I have this codepen animation: Codepen SVG Testing
.anim {
width:500px;
height:281.25px;
margin: 0;
padding: 0;
}
svg {
width: 100%;
height:100%;
stroke-width:10px;
stroke: #ff0000;
stroke-dasharray: 10000;
stroke-dashoffset: 10000;
animation: dash 3s ease-in-out forwards infinite;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
and my HTML:
<div class="anim">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1920 1080" enable-background="new 0 0 1920 1080" xml:space="preserve">
<path fill="none" d="M0,392.306V1080h1920V647.331c0,0-165.5,91.836-384.623,105.011
c-215.715,12.97-302.606-198.286-324.033-252.025c-20.759-52.064-258.025-465.046-591.059-24.002c0,0-150.015,249.024-396.04-24.002
C224.246,452.312,150.792,368.303,0,392.306z"/>
</svg>
</div>
The animation starts on the top left corner to bottom (forwards).
I want it to start on the same top left, but moving to the right direction, where the waves are, then move to right bottom, then left bottom, then top left and finish.
I've tried animation-direction: reverse; but it just do the same thing but backwards.
I need to do this only with css.
What am I missing?
i found a solution. Just change the value on
stroke-dashoffset: 10000;
to
stroke-dashoffset: -10000;
I am new to learning SVG and css animations. I am simply trying to draw the letter "T". My issue is that the path begins animating in two different spots. I want it to draw the horizontal line first before drawing the vertical line. What am I not understanding? Below is what i have thus far. Thanks.
.letter_loader {
fill: none;
stroke: #000;
stroke-width: 8px;
stroke-dasharray: 200px;
stroke-dashoffset: 200px;
animation: move 5s linear forwards;
}
#keyframes move {
100% {
stroke-dashoffset: 0;
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" width="355.1" height="411.22">
<path class="letter_loader"
d="M175.2 250.76 L275.2 250.76 M225.2 250.76 L225.2 350.76" />
</svg>
The way I would approach this wouldn't be the best way...
First, setup a box/line that blends in with the background. It should be compiled before the <path>. It should be as wide as the line and be as tall as the horizontal line's width. Then, start the vertical line at the top of the box/line that is supposed to blend in with the background. What is supposed to happen is although the animations start a the same time, the vertical line won't be seen by the viewer until the horizontal line finishes. This may be a bit more difficult if your background is a linear gradient.
Here is what I am thinking:
.letter_loader {
fill: none;
stroke: #000;
stroke-width: 8px;
stroke-dasharray: 200px;
stroke-dashoffset: 200px;
animation: move 5s linear forwards;
}
#keyframes move {
100% {
stroke-dashoffset: 0;
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" style='background-color: #f1f1f1;'>
<path class="letter_loader"
d="M150 150 L250 150 M200 50 L200 250" />
<path style="stroke: #f1f1f1; stroke-width: 8px;" d="M200 50 L 200 146"/>
</svg>
You are drawing a single svg path with a single class, so, the entire path will be drawn with the same animation that starts with stroke-dashoffset:200px and after 5 seconds become 0px.
One option that I think (I'm not an expert with svg or animations, if someone is and I'm saying bullshit, please tell me) you can use, is to separate the path in two, one for top of T other for the base. So in the T base you add another class with another animation, that starts a little later than the top part.
See below code to understand it better.
/* class and animation for T Top*/
.letter_loader {
fill: none;
stroke: #000;
stroke-width: 8px;
stroke-dasharray: 200px;
stroke-dashoffset: 200px;
animation: move 5s ease forwards;
}
#keyframes move {
100% {
stroke-dashoffset: 0;
}
}
/* class and animation for T Base*/
.letter_loader_later {
fill: none;
stroke: #000;
stroke-width: 8px;
stroke-dasharray: 200px;
stroke-dashoffset: 200px;
animation: move_later 5s ease forwards;
}
#keyframes move_later {
/* until 25% it stills with 200px to have a "later start*/
25% {
stroke-dashoffset: 200px;
}
100% {
stroke-dashoffset: 0;
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="129.204 94.714 359.102 415.224" width="355.1" height="411.22">
<path class="letter_loader" d="M175.2 250.76 L275.2 250.76" /> <!-- T TOP -->
<path class="letter_loader_later" d="M225.2 250.76 L225.2 350.76"/> <!-- T BASE -->
</svg>
svg stroke animate start from right, but i want to stroke that animate form left to right. After animating stroke remain stands. can add any animate css class like fadeIn during the animation
.cls-1 {
fill: none;
stroke: #00a139;
stroke-miterlimit: 10;
}
svg {
width: 100%;
height: 100vh;
margin-left: auto;
margin-right: auto;
display: block;
background: #1e1e1e;
}
#Path_70 {
stroke-dasharray: 1800;
stroke-dashoffset: 1800;
animation: dash 5s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg id="ex6" xmlns="http://www.w3.org/2000/svg" viewBox="2080.831 303.745 1673.195 406.547">
<defs>
</defs>
<g id="Group_191" data-name="Group 191" transform="translate(2393 93)">
<path id="Path_70" data-name="Path 70" class="cls-1" d="M1700.935,169.155s-227.809,11.434-421.654,140.759c-174.322,116.314-275.519,110.6-373.713,41.794C786.235,268.022,551.495-57.262,63.3,9.47" transform="translate(-361.422 210.687)"/>
</g>
</svg>
You can make the stroke-dashoffset a negative value:
.cls-1 {
fill: none;
stroke: #00a139;
stroke-miterlimit: 10;
}
svg {
width: 100%;
height: 100vh;
margin-left: auto;
margin-right: auto;
display: block;
background: #1e1e1e;
}
#Path_70 {
stroke-dasharray: 1800;
stroke-dashoffset: -1800;
animation: dash 5s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg id="ex6" xmlns="http://www.w3.org/2000/svg" viewBox="2080.831 303.745 1673.195 406.547">
<defs>
</defs>
<g id="Group_191" data-name="Group 191" transform="translate(2393 93)">
<path id="Path_70" data-name="Path 70" class="cls-1" d="M1700.935,169.155s-227.809,11.434-421.654,140.759c-174.322,116.314-275.519,110.6-373.713,41.794C786.235,268.022,551.495-57.262,63.3,9.47" transform="translate(-361.422 210.687)"/>
</g>
</svg>
What I want is in green And what I already have Is in red in the image. And I want it to be done in CSS animation. The edge of the triangle (start and end of stroke) should be angled like in picture.
My so far code is :
.path {
stroke-dasharray: 504;
animation: dash 2.5s linear infinite;
-webkit-animation: dash 2.5s linear infinite;
-moz-animation: dash 2.5s linear infinite;
-ms-animation: dash 2.5s linear infinite -o-animation: dash 2.5s linear infinite;
}
#keyframes dash {
0% {
stroke-dashoffset: 0;
stroke-width: 30;
}
50% {
stroke-dashoffset: 500;
stroke-width: 30;
}
100% {
stroke-dashoffset: 1000;
stroke-width: 30;
}
}
div svg {
width: 20%;
}
<div>
<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" viewBox="0 0 252.7 251.9" style="enable-background:new 0 0 252.7 251.9;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: #fff;
}
</style>
<g>
<path stroke="#C5C5C5" stroke-width="20" stroke-linejoin="square" stroke-linecap="butt" class="path" d="M151 45 L79 200 L213 200 L152.324 50 L156 45" fill="url(#fagl)" />
</g>
</svg>
</div>
The issue you are facing is the way the stoke end is rendered. I am not aware of a way to make it end exaclty at the angle you need. None of the stoke-linecap values would fit.
You should also note that the path element in your SVG doesn't have the same start and end points.
Workaround:
A way would be to make the path go further than you need it and hide the overflow with clipPath. This way, the sroke will end at the desired angle:
.path {
stroke-dasharray: 23;
animation: dash 2.5s linear infinite;
}
#keyframes dash {
to { stroke-dashoffset: -46; }
}
svg { width: 20%; }
<svg viewBox="0 0 10 10">
<clipPath id="clip">
<path d="M5 1 L8 9 H2z" />
</clipPath>
<path stroke="#C5C5C5" stroke-width="2" class="path" d="M5 1 L8 9 H2 L5 1" fill="url(#fagl)" clip-path="url(#clip)" />
</svg>
Note that I also simplified your SVG and CSS
If you change the 45 values to 60 (the degrees) in your path it will give you the output you desired AFAICT
Snippet
.path {
stroke-dasharray: 504;
animation: dash 2.5s linear infinite;
-webkit-animation: dash 2.5s linear infinite;
-moz-animation: dash 2.5s linear infinite;
-ms-animation: dash 2.5s linear infinite -o-animation: dash 2.5s linear infinite;
}
#keyframes dash {
0% {
stroke-dashoffset: 0;
stroke-width: 30;
}
50% {
stroke-dashoffset: 500;
stroke-width: 30;
}
100% {
stroke-dashoffset: 1000;
stroke-width: 30;
}
}
div svg {
width: 20%;
}
<div>
<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" viewBox="0 0 252.7 251.9" style="enable-background:new 0 0 252.7 251.9;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: #fff;
}
</style>
<g>
<path stroke="#C5C5C5" stroke-width="20" stroke-linejoin="square" stroke-linecap="butt" class="path" d="M151 60 L79 200 L213 200 L152.324 50 L156 60" fill="url(#fagl)" />
</g>
</svg>
</div>