CSS旋转笑脸加载器

标签 css css-animations css-shapes

我想用纯 CSS 复制下面的 gif 动画,是否可行,如何实现?我也愿意接受其他合适的方法。

下面的片段是我目前所拥有的,它只是一张静态面孔。

body {
  background: #fff;
  margin: 50px;
}

.loader {
  position: relative;
  border-radius: 50%;
  box-sizing: border-box;
  width: 80px;
  height: 80px;
  background: linear-gradient(to bottom, #fff 50%, #51cf66 50%);
}

.loader:before {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  top: 10px;
  bottom: 10px;
  border-radius: 50%;
  background: #fff;
}

.dot {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #51cf66;
}

.dot:first-child {
  left: 10px;
  top: 10px;
}

.dot:last-child {
  right: 10px;
  top: 10px;
}
<div class="loader">
  <div class="dot"></div>
  <div class="dot"></div>
</div>

Rotating smiley face animation

最佳答案

2020 年更新

一个新的优化版本,代码更少,我将使微笑的边缘更逼真:

.smile {
  margin: 30px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background:
    radial-gradient(circle closest-side,#42bd56 99%,transparent) 
       -35px 42px/calc(100% - 15px) 15px repeat-x,
    linear-gradient(#fff,#fff) top/100% 50px no-repeat,
    radial-gradient(farthest-side,transparent calc(99% - 15px),#42bd56 calc(100% - 15px));
  position: relative;
}

.smile:before,
.smile:after{
    content: "";
    position: absolute;
    width:100%;
    top: calc(50% - 7px);
    height: 15px;
    background:radial-gradient(circle closest-side,#42bd56 99%,transparent) -7.5px 0/200% 100%;
    transform:rotate(calc(var(--o,0deg) - 50deg));
    
}
.smile:after {
  --o:-80deg;
}

.smile:hover {
  animation: rotateS 1.2s linear;
}
.smile:hover:before,
.smile:hover:after{
  animation: inherit;
  animation-name:rotateE;
}

@keyframes rotateS {
  50% {
    transform: rotate(360deg);
    background-size: calc(90% - 15px) 15px,100% 30px,auto;
    background-position:-25px 22px,top,0 0;
  }
  100% {
    transform: rotate(720deg);
  }
}


@keyframes rotateE {
  30%,70% {
    transform:rotate(calc(var(--o,0deg) - 180deg));
  }
}
Hover to animate
<div class="smile">
</div>

A Codepen使用代码演示


旧答案

这是解决方案,下面是一步一步的解释

.smile {
  margin: 30px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background:
    radial-gradient(circle ,#42bd56 10%,transparent 11%)  43px 0px,
    radial-gradient(circle ,#42bd56 10%,transparent 11%) -43px 0px,
    radial-gradient(circle , #fff 35px, transparent 35px), 
    linear-gradient(to bottom, #fff 50%, transparent 50%), 
    #42bd56;
  background-repeat:no-repeat;
  position: relative;
}

.smile:before,.smile:after{
    content: "";
    position: absolute;
    width: 100%;
    top: 50%;
    margin-top: -7px;
    height: 15px;
    background: 
      radial-gradient(circle,#42bd56 15%,transparent 16%) 43px 0px;
    transform:rotate(-50deg);
    
}
.smile:after {
  background:
    radial-gradient(circle at center,#42bd56 15%,transparent 16%) -43px 0px;
  transform:rotate(50deg);
}


.smile:hover {
  animation: rotateS 1.5s linear;
}

.smile:hover::before {
  animation: rotateL 1.5s linear;
}
.smile:hover::after {
  animation: rotateR 1.5s linear;
}

@keyframes rotateS {
  0% {
    transform: rotate(0deg);
    background-size: auto,auto,auto ,100% 100%, auto;
  }
  50% {
    transform: rotate(360deg);
    background-size: auto,auto,auto, 100% 50%, auto;
  }
  100% {
    transform: rotate(720deg);
    background-size: auto,auto,auto, 100% 100%, auto;
  }
}

@keyframes rotateR {
  0% {
    transform:rotate(50deg);
  }
  30%,70% {
    transform:rotate(-40deg);
  }
  100% {
    transform:rotate(50deg);
  }
}

@keyframes rotateL {
  0% {
    transform:rotate(-50deg);
  }
  30%,70% {
    transform:rotate(-180deg);
  }

  100% {
    transform:rotate(-50deg);
  }
}
Hover to animate
<div class="smile">
</div>


在此解决方案中,我将仅使用一个 元素。我将依赖具有线性渐变和径向渐变的多个背景,并使用伪元素。

微笑

我将使用线性渐变和带背景颜色的径向渐变来创建主要形状,然后我将为圆 Angular 添加 2 个小的径向渐变:

.smile {
  margin: 50px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background:
   radial-gradient(circle,#42bd56 10%,transparent 11%)  43px 0px,
   radial-gradient(circle,#42bd56 10%,transparent 11%) -43px 0px,
   radial-gradient(circle, #fff 35px, transparent 35px), 
   linear-gradient(to bottom, #fff 50%, transparent 50%), 
  #42bd56;
  background-repeat:no-repeat;
  position: relative;
}
<div class="smile">
</div>

现在要旋转微笑,我将使用旋转并更改线性渐变的大小。正如您在 GIF 中看到的那样,在旋转过程中曲线会增加,因此通过改变线性渐变的大小我会增加它。

enter image description here

正如你所注意到的,用于圆 Angular 的小径向渐变在增加后隐藏了,所以我们也可以考虑同时移动它们,但我不会这样做,以免代码变得复杂.

这是动画(悬停激活):

.smile {
  margin: 50px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background:
   radial-gradient(circle at center,#42bd56 10%,transparent 11%)  43px 0px,
   radial-gradient(circle at center,#42bd56 10%,transparent 11%) -43px 0px,
   radial-gradient(circle at center, #fff 35px, transparent 35px), 
   linear-gradient(to bottom, #fff 50%, transparent 50%), 
   #42bd56;
  background-repeat:no-repeat;
  position: relative;
}

.smile:hover {
  animation: rotateS 1.5s linear;
}

@keyframes rotateS {
  0% {
    transform: rotate(0deg);
    background-size: auto,auto,auto ,100% 100%, auto;
  }
  50% {
    transform: rotate(360deg);
    background-size: auto,auto,auto, 100% 50%, auto;
  }
  100% {
    transform: rotate(720deg);
    background-size: auto,auto,auto, 100% 100%, auto;
  }
}
<div class="smile">
</div>

眼睛

对于眼睛,我将使用伪元素和径向渐变来创建圆圈。我不会简单地创建一个带有 border-radius 的圆,因为我还需要在与微笑相同的轴上旋转它们。

所以我的想法是让它们全宽,并使用径向渐变使圆圈位于最右/最左端。通过这样做,我可以轻松地通过旋转控制它们的位置,并确保它们保持在需要的位置,无论旋转程度如何。

enter image description here

.smile {
  margin: 50px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background:
   radial-gradient(circle at center,#42bd56 10%,transparent 11%)  43px 0px,
   radial-gradient(circle at center,#42bd56 10%,transparent 11%) -43px 0px,
   radial-gradient(circle at center, #fff 35px, transparent 35px) , 
   linear-gradient(to bottom, #fff 50%, transparent 50%), 
   #42bd56;
  position: relative;
}

.smile:before,.smile:after{
    content: "";
    position: absolute;
    width: 100%;
    top: 50%;
    margin-top: -7px;
    height: 15px;
    background: radial-gradient(circle,#42bd56 15%,transparent 16%) 43px 0px;
    transform:rotate(-50deg);
    
}
.smile:after {
  background:radial-gradient(circle,#42bd56 15%,transparent 16%) -43px 0px;
  transform:rotate(50deg);
}
<div class="smile">
</div>

现在对于动画,我将保留第一个也会旋转眼睛的旋转,但我会为眼睛添加一些动画,使它们向相反的方向移动,并创造出微笑在它们上方的错觉。 所以我将简单地为眼睛添加负旋转,使它们看起来移动得更慢,从而超越微笑并产生所需的效果:

这里是再次完整的动画:)

.smile {
  margin: 50px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background:
   radial-gradient(circle at center,#42bd56 10%,transparent 11%)  43px 0px,
   radial-gradient(circle at center,#42bd56 10%,transparent 11%) -43px 0px,
   radial-gradient(circle at center, #fff 35px, transparent 35px) , 
   linear-gradient(to bottom, #fff 50%, transparent 50%), 
   #42bd56;
  background-repeat:no-repeat;
  position: relative;
}

.smile:before,.smile:after{
    content: "";
    position: absolute;
    width: 100%;
    top: 50%;
    margin-top: -7px;
    height: 15px;
    background: radial-gradient(circle,#42bd56 15%,transparent 16%) 43px 0px;
    transform:rotate(-50deg);
    
}
.smile:after {
  background:radial-gradient(circle,#42bd56 15%,transparent 16%)  -43px 0px;
  transform:rotate(50deg);
}


.smile:hover {
  animation: rotateS 1.5s linear;
}

.smile:hover::before {
  animation: rotateL 1.5s linear;
}
.smile:hover::after {
  animation: rotateR 1.5s linear;
}

@keyframes rotateS {
  0% {
    transform: rotate(0deg);
    background-size: auto,auto,auto ,100% 100%, auto;
  }
  50% {
    transform: rotate(360deg);
    background-size: auto,auto,auto, 100% 50%, auto;
  }
  100% {
    transform: rotate(720deg);
    background-size: auto,auto,auto, 100% 100%, auto;
  }
}

@keyframes rotateR {
  0% {
    transform:rotate(50deg);
  }
  30%,70% {
    transform:rotate(-40deg);
  }
  100% {
    transform:rotate(50deg);
  }
}

@keyframes rotateL {
  0% {
    transform:rotate(-50deg);
  }
  30%,70% {
    transform:rotate(-180deg);
  }

  100% {
    transform:rotate(-50deg);
  }
}
<div class="smile">
</div>

在这个解决方案中,为简单起见,我使用了线性过渡,但它可以更改为任何 ease function具有与 GIF 类似的过渡

关于CSS旋转笑脸加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48232891/

相关文章:

css - 使用 matrix3D 创建立方体,作为多个变换的替代方法?

html - 创建一个 'New' 带有 24 点或以上点爆发的尖峰标签

javascript - JQuery - 动态创建的元素 css 不起作用

html - 固定背景图像不断移动

html - 多个文本更改动画不起作用

html - CSS 动画 : make div float out of document

css - CSS 或 SVG 中的波浪

css - 具有百分比宽度的响应式 CSS 三 Angular 形

ios - 如何修复 iOS 视口(viewport)错误?

css - 矛盾的CSS规则 `.myClass:hover { display:none; }`没有效果