svg path transform origin issue [duplicate] - css

This question already has answers here:
Why does order of transforms matter? rotate/scale doesn't give the same result as scale/rotate
(2 answers)
Closed 1 year ago.
I am trying to move a path along x axis on :hover, and rotate it. What value of transform-origin should I use?
a {
display: inline-block;
}
svg, path {
transition: all ease .3s;
transform-origin: 50% 50%;
transform-box: fill-box;
}
.circle {
transform: rotate(-45deg) translateX(20px);
opacity: 0;
}
a:hover .circle{
transform: rotate(45deg) translateX(-20px);
opacity: 1;
}
<a href="" class="play">
<svg width="252" height="188" viewBox="0 0 252 188" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M118.765 118.031a2.945 2.945 0 01-2.942-2.942V72.912a2.944 2.944 0 014.827-2.261l25.306 21.089a2.943 2.943 0 010 4.52L120.65 117.35a2.945 2.945 0 01-1.885.682zm2.944-38.837v29.612L139.476 94l-17.767-14.806z" fill="#000"/>
<path class="circle" d="M125.913 144a49.728 49.728 0 01-24.437-6.386 2.942 2.942 0 112.887-5.128c17.169 9.664 38.901 6.676 52.847-7.276 17.21-17.209 17.21-45.21 0-62.419-17.209-17.212-45.212-17.21-62.42 0-17.21 17.21-17.21 45.21 0 62.419a2.944 2.944 0 01-4.162 4.163c-19.503-19.505-19.503-51.24 0-70.744 19.505-19.503 51.238-19.504 70.745 0 19.504 19.505 19.504 51.239 0 70.744-9.608 9.608-22.476 14.627-35.46 14.627z" fill="#FDB500"/></svg>
</a>

Looks like you just need to swap the order of the translateX and rotate parameters. Matrix multiplication is not commutative.
a {
display: inline-block;
}
svg, path {
transition: all ease .3s;
transform-origin: 50% 50%;
transform-box: fill-box;
}
.circle {
transform: translateX(20px) rotate(-45deg);
opacity: 0;
}
a:hover .circle{
transform: translateX(-20px) rotate(45deg);
opacity: 1;
}
<a href="" class="play">
<svg width="252" height="188" viewBox="0 0 252 188" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M118.765 118.031a2.945 2.945 0 01-2.942-2.942V72.912a2.944 2.944 0 014.827-2.261l25.306 21.089a2.943 2.943 0 010 4.52L120.65 117.35a2.945 2.945 0 01-1.885.682zm2.944-38.837v29.612L139.476 94l-17.767-14.806z" fill="#000"/>
<path class="circle" d="M125.913 144a49.728 49.728 0 01-24.437-6.386 2.942 2.942 0 112.887-5.128c17.169 9.664 38.901 6.676 52.847-7.276 17.21-17.209 17.21-45.21 0-62.419-17.209-17.212-45.212-17.21-62.42 0-17.21 17.21-17.21 45.21 0 62.419a2.944 2.944 0 01-4.162 4.163c-19.503-19.505-19.503-51.24 0-70.744 19.505-19.503 51.238-19.504 70.745 0 19.504 19.505 19.504 51.239 0 70.744-9.608 9.608-22.476 14.627-35.46 14.627z" fill="#FDB500"/></svg>
</a>

Related

CSS transform rotate animation not working as a spinning wheel

.carbody { fill:#000; animation: carbody 4s infinite ; }
#keyframes carbody {
0 { transform: rotate(0deg); }
25% { transform: rotate(1deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-1deg); }
100% { transform: rotate(0deg); }
}
.tireone{
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
display: block; animation:tireone 4s linear infinite;
}
#keyframes tireone { 100% { transform:rotate(360deg); } }
.tiretwo{fill:#a00;}
.wifidot{fill:#c00;}
.wifibarone{fill:#b00;}
.wifibartwo{fill:#d00;}
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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 1000 826.5" style="enable-background:new 0 0 1000 826.5;" xml:space="preserve">
<path class="carbody" d="M190,717.3c-0.8-3.5-3.9-7.2-6.9-9.5c-71.8-53.1-76.7-150.9-10.1-210c22.3-19.8,48.9-30.5,78.6-31.3
c33.8-0.9,67.6,0,101.4-0.4c4.6-0.1,10.1-1.8,13.5-4.8c47.5-40.8,94.6-81.9,142-122.7c3.2-2.7,8.5-4.2,12.8-4.2
c90.4,0.2,180.8,0.6,271.2,1.3c4.4,0,9.6,2.7,12.9,5.7c49.9,45.6,99.5,91.4,149.3,137.2c1.6,1.4,3.6,2.3,5.4,3.5
c21.1,13.1,23.8,16.1,27.3,47.8c-0.3,19.8-0.9,39.7-1,59.5c-0.2,38.7-12.8,72.5-39.4,100.8c-5.5,5.9-12.1,10.8-19.6,17.5
c-2.1-61.2-26.4-108.8-74.9-142.9c-35.1-24.6-74.6-33.5-117.1-28.7c-82.2,9.2-162.8,86.7-148.7,197.2c-16.1-0.1-32-0.1-49-0.2
c0.2-3.1,0.2-5.8,0.6-8.5C553.6,600.5,433,502.2,314.5,542.3c-76.8,26-121,98.6-116.2,172.6"/>
<path class="wifibar" d="M337.3,45.5c3.8,6.8,6.4,13.9,5.4,22c-1.6,13.5-12.5,24.9-26,26.3c-6,0.6-12.1,0.4-18.2,0.5c-69.5,0.6-127.6,26.9-173.3,79
C88.1,215.6,69.9,265.6,69.5,322c-0.1,8.4,0.2,16.9,0,25.3c-0.4,14.5-8.6,25.3-22.1,29.3c-11.8,3.5-25.5-1.2-32.7-11.2
c-3.9-5.3-5.7-11.3-5.9-17.8c-0.9-36.4,1.4-72.5,12.1-107.6c11.4-37.5,29.4-71.5,54.6-101.7c39.2-46.9,88.2-78.6,147.2-94.8
c29.5-8.1,59.6-11.2,90.1-9.8c6.2,0.3,12.2,3.6,18.4,5.5C333.1,41.3,335.2,43.4,337.3,45.5z"/>
<path class="wifibar" d="M172.4,195.4c22-22.1,48-37.2,78.1-45.3c22.4-6,45.2-7.6,68.2-5.4c15.5,1.4,27.8,16.3,27.9,32.3c0.1,16.3-12.3,31-28.1,32.6
c-8.8,0.9-17.7,0.7-26.6,1.1c-31.6,1.4-57.7,14.2-78.1,38.2c-17.2,20.1-25.1,43.9-25.1,70.3c0,8,0.2,16,0,24
c-0.7,26.6-27.5,42.1-50.3,28.9c-10.4-6-15.9-15.5-16.2-27.4c-0.7-25.2-0.8-50.3,6.4-74.8C137.1,241.4,151.6,216.6,172.4,195.4z"/>
<path class="wifibartwo" d="M334,286.7c20.7,20.7,20.7,54.6,0,75.1c-20.8,20.7-54.6,20.6-75.2,0c-20.7-20.8-20.7-54.5,0-75.1
C279.6,266,313.3,266,334,286.7z"/>
<path class="tiretwo" d="M855.2,650c-31.3-54.9-100.3-74.5-154.3-43.9c-55.6,31.5-75.3,101.2-44,155.9c31.3,54.6,101.3,73.8,155.6,42.7
C866.9,773.6,886,704.2,855.2,650z M797.2,676.6c-13.5,0-24.5-11-24.5-24.5s11-24.5,24.5-24.5s24.5,11,24.5,24.5
S810.7,676.6,797.2,676.6z"/>
<path class="tireone" d="M467.4,647.1c-32.2-54.7-101.3-73.2-155.7-41.6c-54.3,31.5-73,101.1-41.8,154.8c32,54.9,101.2,73.9,155.5,42.5
C479.9,771.4,498.9,700.7,467.4,647.1z M416.3,782.4c-13.5,0-24.5-11-24.5-24.5s11-24.5,24.5-24.5s24.5,11,24.5,24.5
S429.8,782.4,416.3,782.4z"/>
</svg>
[![CSS transform rotate animation not working as a spinning wheel, When I apply transform rotate it dose not stay on its position. its just start rotating all over the screen. it should stay on its position and spin as a wheel ][1]][1]
you shouldn't need all that position absolute, top, bottom css on the tireone, the path itself is placing it where it needs to be. what you're looking for is transform-origin. right now defaults to the top left or something for you, so when it rotates around something it's rotating around that spot as the origin. you can set percentages to move where that spot is. (you can also use px but since you're using svg i would avoid that) in fiddling with the percentages i found that transform-origin: 37% 82%; got pretty close to what you probably want, but i'll let you dial it in from there
shout out to this SO post that got me on the right track
.carbody { fill:#000; animation: carbody 4s infinite ; }
#keyframes carbody {
0 { transform: rotate(0deg); }
25% { transform: rotate(1deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-1deg); }
100% { transform: rotate(0deg); }
}
.tireone{
animation:tireone 4s linear infinite;
transform-origin: 37% 82%;
}
#keyframes tireone { 100% { transform:rotate(360deg); } }
.tiretwo{fill:#a00;}
.wifidot{fill:#c00;}
.wifibarone{fill:#b00;}
.wifibartwo{fill:#d00;}
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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 1000 826.5" style="enable-background:new 0 0 1000 826.5;" xml:space="preserve">
<path class="carbody" d="M190,717.3c-0.8-3.5-3.9-7.2-6.9-9.5c-71.8-53.1-76.7-150.9-10.1-210c22.3-19.8,48.9-30.5,78.6-31.3
c33.8-0.9,67.6,0,101.4-0.4c4.6-0.1,10.1-1.8,13.5-4.8c47.5-40.8,94.6-81.9,142-122.7c3.2-2.7,8.5-4.2,12.8-4.2
c90.4,0.2,180.8,0.6,271.2,1.3c4.4,0,9.6,2.7,12.9,5.7c49.9,45.6,99.5,91.4,149.3,137.2c1.6,1.4,3.6,2.3,5.4,3.5
c21.1,13.1,23.8,16.1,27.3,47.8c-0.3,19.8-0.9,39.7-1,59.5c-0.2,38.7-12.8,72.5-39.4,100.8c-5.5,5.9-12.1,10.8-19.6,17.5
c-2.1-61.2-26.4-108.8-74.9-142.9c-35.1-24.6-74.6-33.5-117.1-28.7c-82.2,9.2-162.8,86.7-148.7,197.2c-16.1-0.1-32-0.1-49-0.2
c0.2-3.1,0.2-5.8,0.6-8.5C553.6,600.5,433,502.2,314.5,542.3c-76.8,26-121,98.6-116.2,172.6"/>
<path class="wifibar" d="M337.3,45.5c3.8,6.8,6.4,13.9,5.4,22c-1.6,13.5-12.5,24.9-26,26.3c-6,0.6-12.1,0.4-18.2,0.5c-69.5,0.6-127.6,26.9-173.3,79
C88.1,215.6,69.9,265.6,69.5,322c-0.1,8.4,0.2,16.9,0,25.3c-0.4,14.5-8.6,25.3-22.1,29.3c-11.8,3.5-25.5-1.2-32.7-11.2
c-3.9-5.3-5.7-11.3-5.9-17.8c-0.9-36.4,1.4-72.5,12.1-107.6c11.4-37.5,29.4-71.5,54.6-101.7c39.2-46.9,88.2-78.6,147.2-94.8
c29.5-8.1,59.6-11.2,90.1-9.8c6.2,0.3,12.2,3.6,18.4,5.5C333.1,41.3,335.2,43.4,337.3,45.5z"/>
<path class="wifibar" d="M172.4,195.4c22-22.1,48-37.2,78.1-45.3c22.4-6,45.2-7.6,68.2-5.4c15.5,1.4,27.8,16.3,27.9,32.3c0.1,16.3-12.3,31-28.1,32.6
c-8.8,0.9-17.7,0.7-26.6,1.1c-31.6,1.4-57.7,14.2-78.1,38.2c-17.2,20.1-25.1,43.9-25.1,70.3c0,8,0.2,16,0,24
c-0.7,26.6-27.5,42.1-50.3,28.9c-10.4-6-15.9-15.5-16.2-27.4c-0.7-25.2-0.8-50.3,6.4-74.8C137.1,241.4,151.6,216.6,172.4,195.4z"/>
<path class="wifibartwo" d="M334,286.7c20.7,20.7,20.7,54.6,0,75.1c-20.8,20.7-54.6,20.6-75.2,0c-20.7-20.8-20.7-54.5,0-75.1
C279.6,266,313.3,266,334,286.7z"/>
<path class="tiretwo" d="M855.2,650c-31.3-54.9-100.3-74.5-154.3-43.9c-55.6,31.5-75.3,101.2-44,155.9c31.3,54.6,101.3,73.8,155.6,42.7
C866.9,773.6,886,704.2,855.2,650z M797.2,676.6c-13.5,0-24.5-11-24.5-24.5s11-24.5,24.5-24.5s24.5,11,24.5,24.5
S810.7,676.6,797.2,676.6z"/>
<path class="tireone" d="M467.4,647.1c-32.2-54.7-101.3-73.2-155.7-41.6c-54.3,31.5-73,101.1-41.8,154.8c32,54.9,101.2,73.9,155.5,42.5
C479.9,771.4,498.9,700.7,467.4,647.1z M416.3,782.4c-13.5,0-24.5-11-24.5-24.5s11-24.5,24.5-24.5s24.5,11,24.5,24.5
S429.8,782.4,416.3,782.4z"/>
</svg>

How to rotate an icon at the end of animation?

I found the following example https://codepen.io/lonekorean/pen/vYLNpoY to make the basic animation. But how can I rotate the icon used in the #keyframes duck animation at the end of #keyframes move animation.
.duck svg {
height: 100px;
}
.duck {
animation: duck .2s linear infinite alternate;
}
.move {
animation: move 10s linear infinite alternate;
}
#keyframes duck {
from {
transform: translateY(-7px);
}
to {
transform: translateY(0px);
}
}
#keyframes move {
from {
transform: translateX(0) ;
}
to {
transform: translateX(400px) ;
}
}
<div class="box move">
<div class="duck">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001" xml:space="preserve"><path d="M492.977 219.06c-11.854-6.513-25.73-6.081-37.119 1.151-32.916 20.896-79.957 30.239-136.975 27.373 12.867-20.341 19.778-43.956 19.778-68.435 0-70.739-57.551-128.291-128.29-128.291-67.26.002-122.524 51.371-127.858 117.721-10.914 10.909-37.836 34.276-71.473 38.288a12.521 12.521 0 0 0-7.725 20.921c1.592 1.727 37.457 39.74 105.634 39.738 2.705 0 5.468-.068 8.276-.192.526.556 1.044 1.121 1.58 1.667-19.416 20.845-30.445 48.099-30.664 76.66-.224 30.788 11.594 59.774 33.278 81.615 21.682 21.84 50.568 33.867 81.338 33.867h155.517c50.332 0 91.082-19.931 117.84-57.636C499.591 370.425 512 324.207 512 269.846v-18.648a36.671 36.671 0 0 0-19.023-32.138zM41.04 225.209c17.138-6.245 31.695-15.589 42.887-24.412a128.208 128.208 0 0 0 14.704 41.344c-25.533-1.704-44.748-9.525-57.591-16.932zm445.914 44.638c0 49.136-10.812 90.342-31.265 119.164-22.173 31.244-54.948 47.086-97.414 47.086H202.757c-24.045 0-46.62-9.399-63.563-26.467-16.946-17.07-26.182-39.723-26.006-63.781.199-25.927 11.87-50.51 32.015-67.442a12.528 12.528 0 0 0 4.465-9.678 12.516 12.516 0 0 0-4.605-9.612 103.705 103.705 0 0 1-13.091-12.79l-.005-.006c-16.028-18.66-24.854-42.515-24.854-67.17 0-1.628.035-3.11.113-4.625 2.423-55.299 47.73-98.618 103.148-98.618 56.928 0 103.243 46.315 103.243 103.244 0 26.306-9.92 51.373-27.934 70.583a12.521 12.521 0 0 0 7.868 21.026c72.976 7.425 133.734-2.74 175.735-29.401 5.133-3.261 9.843-1.328 11.629-.346 1.816.998 6.039 3.989 6.039 10.187v18.646z"/><path d="M302.82 374.732h-10.432c-6.915 0-12.523 5.607-12.523 12.524s5.607 12.524 12.523 12.524h10.432c6.916 0 12.524-5.607 12.524-12.524s-5.609-12.524-12.524-12.524zM425.577 324.05c-5.768-3.817-13.538-2.238-17.355 3.53-13.842 20.912-34.649 36.216-58.586 43.091-6.649 1.91-10.488 8.847-8.58 15.494 1.576 5.494 6.585 9.07 12.029 9.07 1.145 0 2.309-.158 3.464-.49 29.662-8.52 55.429-27.463 72.559-53.34 3.816-5.767 2.236-13.538-3.531-17.355zM179.087 126.365c-6.916 0-12.524 5.607-12.524 12.524v31.434c0 6.917 5.608 12.524 12.524 12.524s12.524-5.607 12.524-12.524v-31.434c0-6.917-5.608-12.524-12.524-12.524z"/></svg>
</div>
</div>
Maybe this is what you're looking for?
.duck {
width: 100px;
height: 100px;
animation: duck .2s linear infinite alternate;
}
.duck svg {
width: 100px;
height: 100px;
}
.duck-rotation {
width: 100px;
height: 100px;
animation: duck-rotation 20s linear infinite;
transform-origin: center;
}
.move {
width: 100px;
height: 100px;
animation: move 10s linear infinite alternate;
}
#keyframes duck {
from {
transform: translateY(-7px);
}
to {
transform: translateY(0px);
}
}
#keyframes duck-rotation {
0% {
transform: rotateY(180deg);
}
49% {
transform: rotateY(180deg);
}
50% {
transform: rotateY(0deg);
}
99% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(180deg);
}
}
#keyframes move {
from {
transform: translateX(0) ;
}
to {
transform: translateX(400px) ;
}
}
<div class="box move">
<div class="duck-rotation">
<div class="duck">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001" xml:space="preserve"><path d="M492.977 219.06c-11.854-6.513-25.73-6.081-37.119 1.151-32.916 20.896-79.957 30.239-136.975 27.373 12.867-20.341 19.778-43.956 19.778-68.435 0-70.739-57.551-128.291-128.29-128.291-67.26.002-122.524 51.371-127.858 117.721-10.914 10.909-37.836 34.276-71.473 38.288a12.521 12.521 0 0 0-7.725 20.921c1.592 1.727 37.457 39.74 105.634 39.738 2.705 0 5.468-.068 8.276-.192.526.556 1.044 1.121 1.58 1.667-19.416 20.845-30.445 48.099-30.664 76.66-.224 30.788 11.594 59.774 33.278 81.615 21.682 21.84 50.568 33.867 81.338 33.867h155.517c50.332 0 91.082-19.931 117.84-57.636C499.591 370.425 512 324.207 512 269.846v-18.648a36.671 36.671 0 0 0-19.023-32.138zM41.04 225.209c17.138-6.245 31.695-15.589 42.887-24.412a128.208 128.208 0 0 0 14.704 41.344c-25.533-1.704-44.748-9.525-57.591-16.932zm445.914 44.638c0 49.136-10.812 90.342-31.265 119.164-22.173 31.244-54.948 47.086-97.414 47.086H202.757c-24.045 0-46.62-9.399-63.563-26.467-16.946-17.07-26.182-39.723-26.006-63.781.199-25.927 11.87-50.51 32.015-67.442a12.528 12.528 0 0 0 4.465-9.678 12.516 12.516 0 0 0-4.605-9.612 103.705 103.705 0 0 1-13.091-12.79l-.005-.006c-16.028-18.66-24.854-42.515-24.854-67.17 0-1.628.035-3.11.113-4.625 2.423-55.299 47.73-98.618 103.148-98.618 56.928 0 103.243 46.315 103.243 103.244 0 26.306-9.92 51.373-27.934 70.583a12.521 12.521 0 0 0 7.868 21.026c72.976 7.425 133.734-2.74 175.735-29.401 5.133-3.261 9.843-1.328 11.629-.346 1.816.998 6.039 3.989 6.039 10.187v18.646z"/><path d="M302.82 374.732h-10.432c-6.915 0-12.523 5.607-12.523 12.524s5.607 12.524 12.523 12.524h10.432c6.916 0 12.524-5.607 12.524-12.524s-5.609-12.524-12.524-12.524zM425.577 324.05c-5.768-3.817-13.538-2.238-17.355 3.53-13.842 20.912-34.649 36.216-58.586 43.091-6.649 1.91-10.488 8.847-8.58 15.494 1.576 5.494 6.585 9.07 12.029 9.07 1.145 0 2.309-.158 3.464-.49 29.662-8.52 55.429-27.463 72.559-53.34 3.816-5.767 2.236-13.538-3.531-17.355zM179.087 126.365c-6.916 0-12.524 5.607-12.524 12.524v31.434c0 6.917 5.608 12.524 12.524 12.524s12.524-5.607 12.524-12.524v-31.434c0-6.917-5.608-12.524-12.524-12.524z"/></svg>
</div>
</div>
</div>
In general, you can combine multiple properties for transform: by simply adding them separated by a space, for example:
transform: translateX(400px) rotate(20deg);
But to be honest, I'm not sure what the result you want to achieve should look like.

SVG Line Animation Reversed in Safari?

I've built pretty simple spinning animations for a site, and they look great in Chrome/Firefox, but for some reason, they're animating in reverse in Safari. I've played around with changing values of the offsets, but nothing seems to be working. Is there a workaround for this at all?
.sq {
width: 50vw;
height: auto;
padding: 2.2vw;
}
.path {
stroke-dasharray: 250;
stroke-dashoffset: 250;
animation: line 3s ease forwards;
}
#keyframes line {
from {
stroke-dashoffset: -250;
}
to {
stroke-dashoffset: 0;
}
}
<div class="sq">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 81.32 81.32">
<defs>
<style>
.cls-1{fill:#202020;opacity:0.1;}
.path{fill:none;stroke:#ef3f44;stroke-miterlimit:10;stroke-width:5px;}
</style>
</defs>
<g id="94" data-name="94">
<g id="Objects">
<circle cx="40.66" cy="40.66" r="27.17" class="cls-1"/>
<path d="M40.66 79.15a38.49 38.49 0 1 1 38.49-38.49 38.53 38.53 0 0 1-38.49 38.49zm0-76.07a37.58 37.58 0 1 0 37.58 37.58A37.63 37.63 0 0 0 40.66 3.08z" class="cls-1"/>
<path d="M26.83 5.1a38.16 38.16 0 1 0 13.83-2.6" class="path"/>
</g>
</g>
</svg>
</div>
Also feel free to check this out on Codepen as well:
https://codepen.io/noahbrennan/pen/RLNWXj
In order not to use negative values of stroke-dashoffset, you can use double the positive value of stroke-dashoffset: 500;
Instead of negative values
#keyframes line {
from {
stroke-dashoffset: -250;
}
to {
stroke-dashoffset: 0;
}
}
Use double positive values:
#keyframes line {
from {
stroke-dashoffset: 250;
}
to {
stroke-dashoffset: 500;
}
}
.sq {
width: 50vw;
height: auto;
padding: 2.2vw;
}
.path {
stroke-dasharray: 250;
stroke-dashoffset: 250;
animation: line 3s ease forwards;
}
#keyframes line {
from {
stroke-dashoffset: 250;
}
to {
stroke-dashoffset: 500;
}
}
<div class="sq">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 81.32 81.32">
<defs>
<style>
.cls-1{fill:#202020;opacity:0.1;}
.path{fill:none;stroke:#ef3f44;stroke-miterlimit:10;stroke-width:5px;}
</style>
</defs>
<g id="94" data-name="94">
<g id="Objects">
<circle cx="40.66" cy="40.66" r="27.17" class="cls-1"/>
<path d="M40.66 79.15a38.49 38.49 0 1 1 38.49-38.49 38.53 38.53 0 0 1-38.49 38.49zm0-76.07a37.58 37.58 0 1 0 37.58 37.58A37.63 37.63 0 0 0 40.66 3.08z" class="cls-1"/>
<path d="M26.83 5.1a38.16 38.16 0 1 0 13.83-2.6" class="path"/>
</g>
</g>
</svg>
</div>
Safari doesn't support negative dashoffsets. You'll need to work around that by reversing your path and having the dashoffset animate the other way.
Had the same issue for an svg circle. I wanted the animation to progress counter clockwise. Ended up solving it by horizontally flipping the circle and using a positive dash offset.
I used a transform to flip the circle.
scale(-1 1)
See codepen for an example.
https://codepen.io/rikki404/pen/YzydPJq

Animate SVG fill from left to right

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

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>

Resources