I have created this CodePen for a rotating border around a button and although the principle seems to be good, it is not working as it should - the rendering seems extremely slow and staggering (I have the M1 MacBook Pro).
.button {
width: 206px;
height: 70px;
line-height: 70px;
text-align: center;
position: relative;
}
.button::after {
content: "";
border-radius: 35px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
clip-path: url(#mask);
border: 3px solid black;
}
.curve-1 {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ 20s infinite linear;
transform-origin: 35px center;
//animation-play-state: paused;
//transform: rotate(-315deg)
}
.curve-2 {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ 20s infinite linear;
transform-origin: 35px center;
translate: 136px 0;
}
.line {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʕ•̫͡•ʔ 20s infinite linear;
}
svg {
display: block;
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ {
0% {
transform: rotate(45deg);
}
22% {
transform: rotate(-135deg);
}
27% {
transform: rotate(-180deg);
}
88% {
transform: rotate(-180deg);
}
89% {
transform: rotate(-225deg);
}
100% {
transform: rotate(-315deg);
}
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ {
0% {
transform: rotate(0deg);
}
38% {
transform: rotate(0deg)
}
39% {
transform: rotate(-45deg);
}
50% {
transform: rotate(-135deg);
}
72% {
transform: rotate(-360deg);
}
100% {
transform: rotate(-360deg);
}
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʕ•̫͡•ʔ {
0%, 100% {
width: 0;
x: 35px;
y: 35px;
}
11% {
width: 0;
x: 35px;
y: 35px;
}
22% {
width: 55px;
x: 35px;
y: 35px;
}
39% {
width: 55px;
x: 116px;
y: 35px;
}
50% {
width: 0;
x: 171px;
y: 35px;
}
61% {
width: 0;
x: 171px;
y: 0;
}
72% {
width: 55px;
x: 116px;
y: 0;
}
89% {
width: 55px;
x: 35px;
y: 0;
}
100% {
width: 0;
x: 35px;
y: 0;
}
}
<div class="button">button text</div>
<svg view-box="0 0 206 70" width="206" height="70">
<defs>
<clipPath id="mask">
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-1"/>
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-2"/>
<rect fill="#000" height="35" class="line">
</clipPath>
</defs>
</svg>
<svg view-box="0 0 206 70" width="206" height="70">
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-1"/>
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-2"/>
<rect fill="#000" height="35" class="line">
</svg>
Does anybody know anything about CSS rendering and why could this be happening?
I also created this CodePen where I just wanted to demonstrate that animating a clip-path is possible and it seems to work just fine here...
.masked {
width: 500px;
clip-path: url(#mask)
}
.mask {
width: 500px;
}
.circle {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ 2s infinite;
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ {
0% {
translate: 0;
}
50% {
translate: 40px;
}
100% {
translate: 100px;
}
}
<img src="https://images.unsplash.com/photo-1542273917363-3b1817f69a2d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Nnx8dHJlZXxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=900&q=60" class="masked"/>
<svg viewport="0 0 100 60">
<circle cx="50" cy="30" r="20" class="circle">
</svg>
<svg width="0" height="0">
<defs>
<clipPath id="mask">
<circle cx="100" cy="100" r="40" class="circle" />
</clipPath>
</defs>
</svg>
I have no idea why this's happening, if anyone knows the answer, I would be glad.
Thanks
Why so complicated? The same animation can be achieved with the stroke-dasharray technique.
For me, the animation appears smooth. Whether it is the same for you depends probably on hardware, but I am far down from your computing power.
.button {
width: 206px;
height: 70px;
line-height: 70px;
text-align: center;
position: relative;
border: 3px solid transparent;
}
.button .line {
position: absolute;
overflow: visible;
top: 0;
left: 0;
width: 100%;
height: 100%;
fill: none;
stroke: black;
stroke-width: 3px;
stroke-dasharray: 10px 90px;
animation: around 20s linear infinite;
}
#keyframes around {
0% {
stroke-dashoffset: 100px;
}
100% {
stroke-dashoffset: 0px;
}
}
<div class="button">button text<svg class="line" view-box="0 0 206 70">
<path d="M35,-1.5 A 36.5 36.5 0 0 0 35,71.5 H 171 A 36.5 36.5 0 0 0 171,-1.5 Z" pathLength="100" />
</svg>
I'm working on an animated loading animation. I have 3 shapes that I want to follow a path and scale in size as they move along the path. The 3 shapes will follow a similar path but from different starting points. I created the shapes and paths in Illustrator and exported SVGs. Here's an example of the largest shape and its path.
My issue is without spending all day with trial and error changing the path points order, is there an easier way to set the starting point? My shape starts at the wrong point as you can see in this image.
.loading-wrap {
width:200px;
height:200px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.cir-3 {
width:50px;
height:50px;
border-radius: 50%;
background:cornflowerblue;
position: absolute;
top: 30%;
left: 30%;
offset-path: path("M147.33,108.45A49.76,49.76,0,0,0,97.57,58.69c-22.33,0-45.32,20.86-47.52,35-1.46,4.68-2.23,19.13,61,21.5-.79,14.37-43.76,9.63-61.5,6.39a49.77,49.77,0,0,0,97.78-13.09Z");
animation: move 3s ease-in-out infinite reverse;
}
#keyframes move {
100% {
offset-distance: 100%;
}
}
<div class="loading-wrap">
<div class="cir-1"></div>
<div class="cir-2"></div>
<div class="cir-3"></div>
</div>
EDIT: created a codepen https://codepen.io/CodeFreeze/pen/JjGNLRN
My solution is using 3 different animations for every div. Every div has a different initial offset-distance and the offset-distance is animated to a different value.
.loading-wrap {
width:100px;
height:100px;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
border:1px solid silver;
position:absolute;
}
test{position:relative;}
.test div{
position:absolute;
offset-path: path("M97.78,49.76a49.76,49.76,0,0,0,-49.76,-49.76c-22.33,0,-45.32,20.86,-47.52,35c-1.46,4.68,-2.23,19.13,61,21.5c-0.79,14.37,-43.76,9.63,-61.5,6.39a49.77,49.77,0,0,0,97.78,-13.09z");
}
.cir-1 {
width:20px;
height:20px;
border-radius: 50%;
background:rgb(119, 30, 30);
animation: move 3s ease-in-out infinite;
}
.cir-2 {
width:30px;
height:30px;
border-radius: 50%;
background-color: blueviolet;
offset-distance: 10%;
animation: move2 3s ease-in-out infinite;
}
.cir-3 {
width:50px;
height:50px;
border-radius: 50%;
background:cornflowerblue;
offset-distance: 20%;
animation: move3 3s ease-in-out infinite;
}
#keyframes move {
100% {
offset-distance: 100%;
}
}
#keyframes move2 {
100% {
offset-distance: 110%;
}
}
#keyframes move3 {
100% {
offset-distance: 120%;
}
}
svg{position:absolute;}
<div class="loading-wrap">
<svg viewBox="0 0 100 100">
<path d="M97.78,49.76a49.76,49.76,0,0,0,-49.76,-49.76c-22.33,0,-45.32,20.86,-47.52,35c-1.46,4.68,-2.23,19.13,61,21.5c-0.79,14.37,-43.76,9.63,-61.5,6.39a49.77,49.77,0,0,0,97.78,-13.09z" fill="none" stroke="black"/>
</svg>
<div class="test">
<div class="cir-1"></div>
<div class="cir-2"></div>
<div class="cir-3"></div>
</div>
</div>
UPDATE
If you need the animation to run the other way round you have 2 solution:
You reverse the svg path, meaning that yoy are using this path M97.78,49.76L97.78,49.8A49.77,49.77 0 0 10,62.89C17.74,66.13 60.71,70.87 61.5,56.5C-1.73,54.123 -0.96,39.68 0.5,35C2.7,20.86 25.69,0 48.02,0A49.76,49.76 0 0 197.78,49.76z instead.
.loading-wrap {
width:100px;
height:100px;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
position:absolute;
border:1px solid silver;
}
test{position:relative;}
.test div{
position:absolute;
offset-path: path("M97.78,49.76L97.78,49.8A49.77,49.77 0 0 10,62.89C17.74,66.13 60.71,70.87 61.5,56.5C-1.73,54.123 -0.96,39.68 0.5,35C2.7,20.86 25.69,0 48.02,0A49.76,49.76 0 0 197.78,49.76z");
}
.cir-1 {
width:20px;
height:20px;
border-radius: 50%;
background:rgb(119, 30, 30);
animation: move 3s ease-in-out infinite;
}
.cir-2 {
width:30px;
height:30px;
border-radius: 50%;
background-color: blueviolet;
offset-distance: 10%;
animation: move2 3s ease-in-out infinite;
}
.cir-3 {
width:50px;
height:50px;
border-radius: 50%;
background:cornflowerblue;
offset-distance: 20%;
animation: move3 3s ease-in-out infinite;
}
#keyframes move {
100% {
offset-distance: 100%;
}
}
#keyframes move2 {
100% {
offset-distance: 110%;
}
}
#keyframes move3 {
100% {
offset-distance: 120%;
}
}
svg{position:absolute;}
<div class="loading-wrap">
<svg viewBox="0 0 100 100">
<path d="M97.78,49.76L97.78,49.8A49.77,49.77 0 0 10,62.89C17.74,66.13 60.71,70.87 61.5,56.5C-1.73,54.123 -0.96,39.68 0.5,35C2.7,20.86 25.69,0 48.02,0A49.76,49.76 0 0 197.78,49.76z" fill="none" stroke="black"/>
</svg>
<div class="test">
<div class="cir-1"></div>
<div class="cir-2"></div>
<div class="cir-3"></div>
</div>
</div>
You can use the same path but you animate the divs to negative offset distances.
.loading-wrap {
width:100px;
height:100px;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
border:1px solid silver;
position:absolute;
}
test{position:relative;}
.test div{
position:absolute;
offset-path: path("M97.78,49.76a49.76,49.76,0,0,0,-49.76,-49.76c-22.33,0,-45.32,20.86,-47.52,35c-1.46,4.68,-2.23,19.13,61,21.5c-0.79,14.37,-43.76,9.63,-61.5,6.39a49.77,49.77,0,0,0,97.78,-13.09z");
}
.cir-1 {
width:20px;
height:20px;
border-radius: 50%;
background:rgb(119, 30, 30);
animation: move 3s ease-in-out infinite;
}
.cir-2 {
width:30px;
height:30px;
border-radius: 50%;
background-color: blueviolet;
offset-distance: -10%;
animation: move2 3s ease-in-out infinite;
}
.cir-3 {
width:50px;
height:50px;
border-radius: 50%;
background:cornflowerblue;
offset-distance: -20%;
animation: move3 3s ease-in-out infinite;
}
#keyframes move {
100% {
offset-distance: -100%;
}
}
#keyframes move2 {
100% {
offset-distance: -110%;
}
}
#keyframes move3 {
100% {
offset-distance: -120%;
}
}
svg{position:absolute;}
<div class="loading-wrap">
<svg viewBox="0 0 100 100">
<path d="M97.78,49.76a49.76,49.76,0,0,0,-49.76,-49.76c-22.33,0,-45.32,20.86,-47.52,35c-1.46,4.68,-2.23,19.13,61,21.5c-0.79,14.37,-43.76,9.63,-61.5,6.39a49.77,49.77,0,0,0,97.78,-13.09z" fill="none" stroke="black"/>
</svg>
<div class="test">
<div class="cir-1"></div>
<div class="cir-2"></div>
<div class="cir-3"></div>
</div>
</div>
I want it to repeat the animation from where the hover has been 'released. So this is what my code looks like:
<section class="container">
<figure class="chart" data-percent="100">
<figcaption>HTML</figcaption>
<svg width="200" height="200">
<circle class="outer" cx="95" cy="95" r="85" transform="rotate(-90, 95, 95)"/>
</svg>
</figure>
</section>
This is the HTML I have got.
.outer {
fill: transparent;
stroke: #333;
stroke-width: 10;
stroke-dasharray: 534;
/* firefox bug fix - won't rotate at 90deg angles */
-moz-transform: rotate(-89deg) translateX(-190px);
}
.chart[data-percent='100'] {
stroke-dashoffset: 0;
-webkit-animation: show100 2s;
animation-name: show100;
animation-duration: 2s;
}
.chart:hover .outer {
stroke-dashoffset: 534;
-webkit-animation: show0 2s;
animation-name: show0;
animation-duration: 2s;
}
#-webkit-keyframes show100 {
from {
stroke-dashoffset: 534;
}
to {
stroke-dashoffset: 0;
}
}
#keyframes show100 {
from {
stroke-dashoffset: 534;
}
to {
stroke-dashoffset: 0;
}
}
#-webkit-keyframes show0 {
from {
stroke-dashoffset: 0;
}
to {
stroke-dashoffset: 534;
}
}
#keyframes show0 {
from {
stroke-dashoffset: 0;
}
to {
stroke-dashoffset: 534;
}
}
I am not sure if 'release' is the right word but I can't think of anything better right now.
So if you hover it, that animation will be reversed. But what I want to accomplish is that when you release the hover at 50%, the animation will play from 50% and when you release the hover at 20% that the animation will play from 20%. I haven't got really, I got stuck after the hover-reverse.
this is a live example of my working code:
https://jsfiddle.net/172dLc93/
Thanks
Use animation for the initial setup, but then use transitions so that it continues from where it left.
#import url(https://fonts.googleapis.com/css?family=Lato:300,400,700);
body {
font-family: 'Lato';
}
.container {
position:absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.chart {
position: relative;
display: inline-block;
color: #999;
font-size: 20px;
text-align: center;
}
.chart figcaption {
padding: 50px 25px;
width: 100px;
height: 50px;
border: 20px solid #f0f0f0;
border-radius: 100px;
line-height: 50px;
}
.chart svg {
position: absolute;
top: 0;
left: 0;
}
.outer {
fill: transparent;
stroke: #333;
stroke-width: 10;
stroke-dasharray: 534;
transition:stroke-dashoffset 2s;
/* firefox bug fix - won't rotate at 90deg angles */
-moz-transform: rotate(-89deg) translateX(-190px);
}
.chart[data-percent='100'] {
stroke-dashoffset: 0
-webkit-animation: show100 2s;
animation-name: show100;
animation-duration: 2s;
}
.chart:hover .outer {
stroke-dashoffset: 534;
}
#-webkit-keyframes show100 {
from {
stroke-dashoffset: 534;
}
to {
stroke-dashoffset: 0;
}
}
#keyframes show100 {
from {
stroke-dashoffset: 534;
}
to {
stroke-dashoffset: 0;
}
}
<section class="container">
<figure class="chart" data-percent="100">
<figcaption>HTML</figcaption>
<svg width="200" height="200">
<circle class="outer" cx="95" cy="95" r="85" transform="rotate(-90, 95, 95)"/>
</svg>
</figure>
</section>
Updated fiddle: https://jsfiddle.net/gaby/172dLc93/4/
I have animation (#svg_tag, .st0). After animation complete, then fades-in the image (.logo_svg). I want that animation begins after page is fully loaded (both animation and image).
.logo_svg {
max-width: 80%;
width: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
opacity: 0;
animation-name: show;
animation-delay: 11s;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-iteration-count: 1;
animation-timing-function: linear;
}
body{
background-color: grey;
}
#svg_tag {
max-width: 80%;
width: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
.st0 {
fill-opacity: 0;
stroke: #fff;
stroke-width: 1;
stroke-dasharray: 1350;
stroke-dashoffset: 1350;
animation: draw 15s linear;
animation-delay: 5s;
}
#keyframes draw {
to {
stroke-dashoffset: 0;
}
}
#keyframes show {
to {
opacity: 1;
}
}
<body>
<svg version="1.1" id="svg_tag" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 708.7 437.3" style="enable-background:new 0 0 708.7 437.3;" xml:space="preserve">
<path id="XMLID_13_" class="st0" d="M708.7,285c-18.6,18.6-47.7,21.9-70,7.9v102.3l70,42V285z"/>
<path id="XMLID_12_" class="st0" d="M595.6,113.1l-113.1,67.9v7.5H509V245c0,16.6,13.4,30,30,30s30-13.4,30-30v-56.5h26.5v113.1
h-26.5v-8.6c-9,5.6-19.4,8.6-30,8.6c-31.2,0-56.5-25.3-56.5-56.5v56.5l129.6,77.8V188.5h26.5v8.6c22.3-14,51.4-10.7,70,7.9v-24.1
L595.6,113.1z"/>
<circle id="XMLID_11_" class="st0" cx="669" cy="245" r="30"/>
<path id="XMLID_10_" class="st0" d="M242.7,188.5h-9.9V245c0,25.7-20.9,46.6-46.6,46.6s-46.6-20.9-46.6-46.6v-56.5h-9.9V245
c0,31.2,25.3,56.5,56.5,56.5c18.6,0,36.1-9.2,46.6-24.5v24.5h9.9V188.5z"/>
<polyline id="XMLID_9_" class="st0" points="279.2,188.5 259.3,188.5 259.3,198.4 269.2,198.4 269.2,301.6 279.2,301.6 279.2,188.5
"/>
<path id="XMLID_8_" class="st0" d="M259.3,123c0-5.5,4.4-9.9,9.9-9.9s9.9,4.4,9.9,9.9s-4.4,9.9-9.9,9.9S259.3,128.5,259.3,123
L259.3,123z"/>
<rect id="XMLID_7_" x="295.7" y="113.1" class="st0" width="9.9" height="188.5"/>
<path id="XMLID_16_" class="st0" d="M425.4,0v213c-17.7-25.7-52.9-32.3-78.6-14.6c-25.7,17.7-32.3,52.9-14.6,78.6
c17.7,25.7,52.9,32.3,78.6,14.6c5.7-3.9,10.7-8.9,14.6-14.6v24.5h9.9V0H425.4z M378.8,291.6c-25.7,0-46.6-20.9-46.6-46.6
s20.9-46.6,46.6-46.6s46.6,20.9,46.6,46.6S404.5,291.6,378.8,291.6z"/>
<path id="XMLID_15_" class="st0" d="M103.1,213c-17.7-25.7-52.9-32.3-78.6-14.6c-5.7,3.9-10.7,8.9-14.6,14.6V0H0v301.6h9.9V277
c17.7,25.7,52.9,32.3,78.6,14.6C114.3,273.9,120.8,238.7,103.1,213z M56.5,291.6c-25.7,0-46.6-20.9-46.6-46.6s20.9-46.6,46.6-46.6
s46.6,20.9,46.6,46.6S82.3,291.6,56.5,291.6z"/>
</svg>
<img src="logo.png" class="logo_svg" alt="" />
</body>
Thanks for uploading the HTML.
Correct me if I'm wrong, but I think you want to animate the logo, to draw itself, when the page loads. And then you want to animate another logo, that fades in.
If the logotypes are the same - then you can animate the first SVG logo itself, with one animation. No need for two :)
Here's a little codepen that does exactly that.
Here's the essential animation:
svg{
max-width: 80%;
width: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
.st0 {
fill-opacity: 0;
stroke: #fff;
stroke-width: 1;
stroke-dasharray: 1350;
stroke-dashoffset: 1350;
animation: draw 5s linear forwards;
}
#keyframes draw {
95% {
stroke-dashoffset: 0;
fill-opacity:0;
stroke-width:1;
}
100%{
fill-opacity:1;
stroke-width:0;
}
}
Does this solve your problem?