How can I make the last part of the spinner lighter (ie. fading):
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 5px solid transparent;
border-top-color: #aaa;
border-right-color: #aaa;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="loader-wrapper">
<div id="loader"></div>
</div>
I tried using gradient but it converts it to a square
You can apply the gradient to a pseudo-element like so:
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 5px solid transparent;
border-top-color: #aaa;
border-right-color: #aaa;
animation: spin 2s linear infinite;
}
#loader::after {
content: '';
width: 85%;
height: 85%;
background: linear-gradient(45deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 40%, rgba(255, 255, 255, 0.7) 60%, rgba(255, 255, 255, 0) 100%);
position: absolute;
top: 0;
left: 0;
transform: translate(-5%, -5%);
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="loader-wrapper">
<div id="loader"></div>
</div>
Here is another idea with less code and without using pseudo element.
.loader {
--border-width: 5px;
height: 150px;
width: 150px;
border-radius: 50%;
/* 0.5px's are needed to avoid hard-stopping */
--mask: radial-gradient(
farthest-side,
transparent calc(100% - var(--border-width) - 0.5px),
#000 calc(100% - var(--border-width) + 0.5px)
);
-webkit-mask: var(--mask);
mask: var(--mask);
background: linear-gradient(#aaa 30%, transparent 80%) 0 0/50% 100% no-repeat; /* this is our border image */
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="loader"></div>
And this is the comparison of my answer with #Ricky's answer by setting background to body:
#Ricky's way:
body {
background: pink; /* just added this */
}
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 5px solid transparent;
border-top-color: #aaa;
border-right-color: #aaa;
animation: spin 2s linear infinite;
}
#loader::after {
content: '';
width: 85%;
height: 85%;
background: linear-gradient(45deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 40%, rgba(255, 255, 255, 0.7) 60%, rgba(255, 255, 255, 0) 100%);
position: absolute;
top: 0;
left: 0;
transform: translate(-5%, -5%);
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="loader-wrapper">
<div id="loader"></div>
</div>
My way:
body {
background: pink; /* just added this */
}
.loader {
--border-width: 5px;
height: 150px;
width: 150px;
border-radius: 50%;
/* 0.5px's are needed to avoid hard-stopping */
--mask: radial-gradient(
farthest-side,
transparent calc(100% - var(--border-width) - 0.5px),
#000 calc(100% - var(--border-width) + 0.5px)
);
-webkit-mask: var(--mask);
mask: var(--mask);
background: linear-gradient(#aaa 30%, transparent 80%) 0 0/50% 100% no-repeat; /* this is our border image */
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="loader"></div>
Related
I want to animate the waves to go up when i click on the div i cant get the wave to animate when i change the heigt on the animation it self.
.tsx
<div className={styles.circle}>
<div className={styles.wave}></div>
</div>
.css
.circle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-190%, -50%);
width: 25%;
height: 60%;
background: #ccc;
box-shadow: 0 0 0 5px #fff;
border-radius: 50%;
overflow: hidden;
}
.wave {
position: relative;
width: 100%;
height: 100%;
background: #4973ff;
border-radius: 50%;
box-shadow: inset 0 0 50px rgba(0, 0, 0, 0.5);
}
.wave:before,
.wave:after {
content: "";
position: absolute;
width: 200%;
height: 200%;
top: 0;
left: 50%;
transform: translate(-50%, -75%);
background: #000;
}
.wave:before {
border-radius: 45%;
background: rgb(255, 255, 255);
animation: animate 5s linear infinite;
}
.wave:after {
border-radius: 40%;
background: rgb(255, 255, 255, 0.5);
animation: animate 10s linear infinite;
}
#keyframes animate {
0% {
transform: translate(-50%, var(--water)) rotate(0deg);
}
100% {
transform: translate(-50%, var(--water)) rotate(360deg);
}
}
I tried putting translate: transform 2s linear but that didnt work for me eighter do you guys have any idea beaces when i change the
:root {
--water: -90%
}
to
:root {
--water: -80%
}
it will just snap and not animate
How would I be able to apply a gradient color to the triangle?
https://jsfiddle.net/otz9ewm8/
.spinner::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 27px solid #B76BF0;
transform: translateX(4px);
z-index: 0;
}
How would this be done in the code?
.spinner {
-webkit-appearance: none;
appearance: none;
border: none;
padding: 0;
display: block;
cursor: pointer;
/*background: rgba(255, 255, 255, 0.1);*/
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
box-sizing: border-box;
background-clip: padding-box;
/* -webkit-mask: linear-gradient(rgba(0, 0, 0, 0.1), #000000 90%);*/
width: 90px;
height: 90px;
border-radius: 50%;
transform-origin: 50% 55%;
transform: perspective(90px) rotateX(30deg);
animation: spinner-wiggle 5.2s infinite;
}
.spinner::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 27px solid #B76BF0;
transform: translateX(4px);
z-index: 0;
}
#keyframes spinner-wiggle {
30% {
transform: perspective(90px) rotateX(10deg);
}
40% {
transform: perspective(90px) rotateX(7deg);
}
50% {
transform: perspective(90px) rotateX(10deg);
}
60% {
transform: perspective(90px) rotateX(8deg);
}
}
.color-circle {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 90px;
height: 90px;
transform-origin: 50% 50%;
background: -webkit-gradient(linear,
left top,
left bottom,
color-stop(50%, #25d8fb),
color-stop(100%, #4f66bb));
border-radius: 50%;
z-index: 0;
box-shadow: inset 0 24px 18px -10px rgba(0, 0, 140, 0.3),
inset 0 0 22px -2px rgba(0, 0, 0, 0.4);
cursor: pointer;
background: linear-gradient(100deg, #24A4EA, #379DEB 25%, #B76BF0);
-webkit-mask-image: radial-gradient(circle, transparent 0 36px, black 36px);
mask-image: radial-gradient(circle, transparent 0 50px, black 20px);
}
.spinner:hover .color-circle {
background: -webkit-gradient(linear,
left top,
left bottom,
color-stop(50%, rgba(34, 204, 0, 0.9)),
color-stop(100%, #55ff00));
}
.color-circle:before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 72px;
height: 72px;
border-radius: 50%;
background-color: #353198;
z-index: 0;
}
.spinner:hover .color-circle {
animation: spin 1.7s infinite linear;
}
#-webkit-keyframes spin {
0% {
transform: rotateZ(0deg);
}
100% {
transform: rotateZ(360deg);
}
}
<div class=" spinner">
<span class="color-circle"></span>
</div>
You can use clip-path instead of borders
background-image: linear-gradient(100deg, #24A4EA, #379DEB 25%, #B76BF0);
clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
I'm implementing waves animation similar to this:
I want to make the 2px border for each transparent wave circle - what is the best way to achieve this (preferably without width/height animation)?
Currently I'm animating box-shadow property and seems I'm unable(?) to use several shadows to imitate the border as long as I need them to be half-transparent. Also I'm unable to use scale as border-width will be scaled as well. The only way I see here is to animate the actual width/height of each <i> element but I don't think this animation will be smooth on all devices(?)
:root {
--size: 6px;
--duration: 1000ms;
}
body {
background: #333;
}
.blinker {
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
z-index: 3;
background: #fdfdf9;
width: var(--size);
height: var(--size);
border-radius: 50%;
}
.blinker i {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
content: "";
width: 6px;
height: 6px;
border-radius: 50%;
opacity: 1;
}
.blinker i:nth-child(1) {
animation: blinkBoxShadow var(--duration) ease-out infinite;
display: block;
border: 1px solid white;
}
#keyframes blinkBoxShadow {
from {
box-shadow: 0 0 0 30px trasparent;
background: transparent;
opacity: 1;
}
to {
box-shadow: 0 0 0 30px rgba(255, 255, 255, 0.7);
background: rgba(255, 255, 255, 0.7);
opacity: 0;
}
}
.blinker i:nth-child(2) {
transform: translateX(-50%) translateY(-50%);
width: 61px;
height: 61px;
animation: blinkBoxShadow2 var(--duration) ease-out infinite;
animation-delay: calc(var(--duration) - 200ms);
}
#keyframes blinkBoxShadow2 {
from {
box-shadow: 0 0 0 0px rgba(255, 179, 117, 0.7);
opacity: 0;
}
50% {
opacity: 0.5;
}
to {
box-shadow: 0 0 0 50px rgba(255, 179, 117, 0);
opacity: 0;
}
}
.blinker i:nth-child(3) {
background: white;
}
<div class="blinker">
<i></i>
<i></i>
<i></i>
</div>
If I'm understanding correctly - You can't use box-shadow property, because of it's non-transparent?
If yes, you can set the color of the shadow by using rgba() function, where the last parameter is alpha (transparency) channel value. You can see how it's done on CodePen projects when you type in search bar - 'pulse'.
If no, if you would use JS to animate width/height I think it wouldn't be a efficiency problem on most mobile devices.
I think border should work. Remove box-shadow and animate it on width and height.
See the Snippet below:
:root {
--size: 6px;
--duration: 1000ms;
}
body {
background: #333;
}
.blinker {
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
z-index: 3;
background: #fdfdf9;
width: var(--size);
height: var(--size);
border-radius: 50%;
}
.blinker i {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
content: "";
width: 6px;
height: 6px;
border-radius: 50%;
opacity: 1;
}
.blinker i:nth-child(1) {
animation: blinkBoxShadow var(--duration) ease-out infinite;
display: block;
border: 2px solid rgba(255, 255, 255, 0.5);
}
#keyframes blinkBoxShadow {
from {
/*box-shadow: 0 0 0 30px trasparent;*/
background: transparent;
opacity: 1;
width:0px;
height:0px;
}
to {
/*box-shadow: 0 0 0 30px rgba(255, 255, 255, 0.7);*/
background: rgba(255, 255, 255, 0.7);
opacity: 0;
width:61px;
height:61px;
}
}
.blinker i:nth-child(2) {
transform: translateX(-50%) translateY(-50%);
width: 61px;
height: 61px;
animation: blinkBoxShadow2 var(--duration) ease-out infinite;
animation-delay: calc(var(--duration) - 500ms);
}
#keyframes blinkBoxShadow2 {
from {
/*box-shadow: 0 0 0 0px rgba(255, 179, 117, 0.7);*/
background:transparent;
opacity: 0;
border:2px solid rgba(255, 179, 117, 0);
width: 61px;
height: 61px;
}
50% {
opacity: 0.5;
}
to {
/*box-shadow: 0 0 0 50px rgba(255, 179, 117, 0);*/
background:rgba(255, 179, 117, 0.2);
opacity: 0;
width:140px;
height:140px;
border:2px solid rgba(255, 179, 117, 0.2);
}
}
.blinker i:nth-child(3) {
background: white;
}
<div class="blinker">
<i></i>
<i></i>
<i></i>
</div>
I've created a simple pie-chart (2 slices) and set the background color of the small slice by creating a layer with the help of CSS clip-path.
My problem is - clip path isn't working in Microsoft Edge.
Is there any better way to do it?
Codepen: https://codepen.io/anon/pen/QMPPOQ?editors=1100
body {
background: #e74c3c;
margin-top: 45px;
}
.chart {
width: 400px;
max-width: 90vw;
height: 400px;
margin: 0 auto;
border-radius: 50%;
border: 3px solid white;
position: relative;
background: rgba(255, 255, 255, .3);
overflow: hidden;
}
.chart-inner {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-1.5px);
}
.chart .line {
width: 50%;
height: 3px;
background: white;
position: absolute;
top: 50%;
transform-origin: 100%;
transform: rotate(90deg);
}
.chart .line-spl {
transform: rotate(60deg); /* 1/12 */
}
.layer {
z-index: -10;
position: relative;
background: rgba(255, 255, 255, .6);
-webkit-clip-path: polygon(49% 55%, 25% 13%, 49% 8%);
-ms-clip-path: polygon(40% 50%, 18% 12%, 40% 5%);
-moz-clip-path: polygon(40% 50%, 18% 12%, 40% 5%);
clip-path: polygon(49% 55%, 25% 13%, 49% 8%);
height: 450px;
width: 465px;
left: -29px;
top: -52px;
}
<div class="chart">
<div class="chart-inner">
<div class="line"></div>
<div class="line line-spl"></div>
<div class="layer"></div>
</div>
</div>
I have this pen which tries to emulate an object revolving around something. This works, but it isn't smooth. While revolving it pauses around the left and right edges.
I thought it had something to do with animation-timing-function but can't get the desired result with any of the in-built functions like ease-in-out or linear or a custom cubic-bezier function.
How can I make the animation feel smooth? If there are better ways something like this can be done, feel free to let me know.
.overlay {
background-image: -webkit-repeating-linear-gradient(0deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
background-image: repeating-linear-gradient(90deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
height: 200px;
position: relative;
width: 40%;
margin: auto;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: #888;
position: absolute;
z-index: -1;
left: 0;
display: inline-block;
}
.move {
-webkit-animation: moveAndGlow 2s infinite ease-in-out;
animation: moveAndGlow 2s infinite ease-in-out;
}
#-webkit-keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
}
}
#keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
}
}
<div class="overlay">
<span class="circle move"></span>
</div>
If you want to move you element in a 3d environement, you can use the perspective property and actual 3d rotation.
Right now you are animating on straight lines between positions so simulating a rotation is almost imposible. I built the following example, you will need to tweak the size to fit it into your project but you should get the idea.
Also note that I put the gradient background in a pseudo element so it appear in front of the moving object :
.overlay {
height: 200px;
position: relative;
width: 40%;
margin: auto;
perspective:500px;
margin-top:50px;
}
.overlay:after{
content:'';
position:absolute;
top:-100px; left:-10%;
width:120%; height:100%;
background-image: repeating-linear-gradient(90deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: #888;
position: absolute;
z-index: -1;
left: 50%;
margin-left:-50px;
transform: rotateY(0deg) translateX(-100px) rotateY(0deg);
display: inline-block;
}
.move {
animation: moveAndGlow 2s infinite linear;
}
#keyframes moveAndGlow {
to{ transform:rotateY(360deg) translateX(-100px) rotateY(-360deg); }
}
<div class="overlay">
<span class="circle move"></span>
</div>
I found this made it smoother
.move {
-webkit-animation: moveAndGlow 2s infinite linear;
animation: moveAndGlow 2s infinite linear;
}
#-webkit-keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
-webkit-animation-timing-function:ease-in;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
-webkit-animation-timing-function:ease-out;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
-webkit-animation-timing-function:ease-in;
}
}