【问题标题】:Animating a box-shadow/text-shadow on a circular path?在圆形路径上为框阴影/文本阴影设置动画?
【发布时间】:2020-10-05 06:41:59
【问题描述】:

我正在尝试使用 CSS 动画来创建光源指向对象、投射阴影并围绕它做圆周运动的效果。我在下面创建了一个 sn-p 来显示我到目前为止的位置。

有点接近,但目前(因为我只有 4 个关键帧)就像光源沿着方形路径移动。我希望它看起来像沿着圆形路径移动。

我能想到的唯一解决方案是添加更多关键帧并创建(为简单起见)十二边形路径,但有更简单的解决方案吗?有没有一种计时功能可以让我缓和它进入更平滑的路径?或者我可以使用某种 Sass 函数来自动计算中间关键帧吗?

我应该注意到,一旦我开始使用 box-shadows,我还想将相同的方法应用于 text-shadows。

.container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
}

.circle {
  width: 200px;
  height: 200px;
  border-radius: 100%;
  background-color: teal;
  box-shadow: 50px 50px 5px darkgrey;
  animation: orbit-shadow 5s linear infinite;
}

@keyframes orbit-shadow {
  0% {
    box-shadow: 50px 50px 5px darkgrey;
  }
  25% {
    box-shadow: -50px 50px 5px darkgrey;
  }
  50% {
    box-shadow: -50px -50px 5px darkgrey;
  }
  75% {
    box-shadow: 50px -50px 5px darkgrey;
  }
  1000% {
    box-shadow: 50px 50px 5px darkgrey;
  }
}
<div class="container">
  <div class="circle"></div>
</div>

【问题讨论】:

    标签: css css-animations


    【解决方案1】:

    您必须为此考虑轮换。使用伪元素避免旋转主元素:

    .container {
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      position:relative;
      z-index:0;
    }
    
    .circle {
      width: 200px;
      height: 200px;
      margin:50px;
      border-radius: 100%;
      background-color: teal;
      position:relative;
    }
    .circle::before {
      content:"";
      position:absolute;
      z-index:-1;
      top:0;
      left:0;
      right:0;
      bottom:0;
      border-radius:inherit;
      box-shadow: 50px 50px 5px darkgrey;
      animation: orbit-shadow 5s linear infinite;
    }
    
    @keyframes orbit-shadow {
      100% {
        transform:rotate(360deg);
      }
    }
    
    body{
     margin:0;
    }
    <div class="container">
      <div class="circle"></div>
    </div>

    或者如果你没有任何内容,你只需旋转元素:

    .container {
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
    }
    
    .circle {
      width: 200px;
      height: 200px;
      border-radius: 100%;
      background-color: teal;
      box-shadow: 50px 50px 5px darkgrey;
      animation: orbit-shadow 5s linear infinite;
    }
    
    @keyframes orbit-shadow {
      100% {
        transform:rotate(360deg);
      }
    }
    
    body{
     margin:0;
    }
    <div class="container">
      <div class="circle"></div>
    </div>

    另一个想法:

    .container {
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      position:relative;
      z-index:0;
    }
    
    .circle {
      width: 200px;
      height: 200px;
      margin:50px;
      border-radius: 100%;
      background-color: teal;
      position:relative;
    }
    .circle::before {
      content:"";
      position:absolute;
      z-index:-1;
      top:0;
      left:0;
      right:0;
      bottom:0;
      border-radius:inherit;
      background:darkgrey;
      filter:blur(5px);
      animation: orbit-shadow 5s linear infinite;
    }
    
    @keyframes orbit-shadow {
      0% {
        transform:rotate(0deg)   translate(50px);
      }
      100% {
        transform:rotate(360deg) translate(50px);
      }
    }
    
    body{
     margin:0;
    }
    <div class="container">
      <div class="circle"></div>
    </div>

    您也可以对text-shadow 执行相同操作,但动画稍有不同,以免旋转文本:

    .container {
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
    }
    
    .circle {
      position:relative;
      font-size:40px;
      font-weight:bold;
    }
    .circle::before,
    .circle::after{
      content:attr(data-text);
      position:relative;
      z-index:1;
    }
    
    .circle::before {
      position:absolute;
      top:0;
      left:0;
      right:0;
      bottom:0;
      color:transparent;
      text-shadow:0 0 5px darkgrey;
      animation: orbit-shadow 5s linear infinite;
    }
    /* the 50px is your offset */
    @keyframes orbit-shadow {
      0% {
        transform:rotate(0deg)   translate(50px) rotate(0deg);
      }
      100% {
        transform:rotate(360deg) translate(50px) rotate(-360deg);
      }
    }
    body{
     margin:0;
    }
    <div class="container">
      <div class="circle" data-text="some text"></div>
    </div>

    【讨论】:

    • 是的,这似乎是一个更简单的解决方案。我在最初的问题中没有提到它,但这源于想要将相同的动画应用于文本阴影,所以我想我只是把它卡在了我的头上,我也 使用 box-shadow 以便于翻译。但我想我也可以将您的方法应用于文本 - 只需将文本的副本放在伪元素中并以相同的方式对其进行动画处理。谢谢!
    • @itsViney 我正在使用文本阴影解决方案进行更新
    • 所有这些例子都弄乱了滚动条,但我不知道是否有解决方案。但是,我怀疑这将在以前没有滚动条的地方使用。但是,它可能会导致内容上下移动,使其相当烦人。但是,我不知道是否有解决方案...:/但看起来很酷!
    • @IsmaelMiguel 您可以增加主要元素的边距以确保旋转的元素将在该区域旋转,并且您将避免内容的任何移动。
    • @IsmaelMiguel 我不这么认为,因为这与盒子大小无关。边距更合适,因为在所有情况下,除非您将填充应用于父元素,否则旋转将使元素向外移动
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多