【问题标题】:Keyframes Parameters with SASSSASS 的关键帧参数
【发布时间】:2018-08-02 21:09:14
【问题描述】:

我在 CSS 中创建了一个旋转轮播,我对此非常满意。它包含在 sn-p 中。原文在this CodePen

它基本上是旋转四个盒子的位置。总动画时间为 8 秒,我已将其设置为 20% 保持静态,然后将框移动 5%,然后再次等待(运行 sn-p;我认为我没有解释得很好)。

现在我想参数化它。 Sass 是我选择的武器,我可以轻松设置一些有用的变量。所以就在我的风格的顶部,我有这个:

$delays: 0s, -6s, -4s, -2s;
$fullanimtime: 8s;
$animationstops: 0%, 20%, 25%, 45%, 50%, 70%, 75%, 95%, 100%;

我使用$fullanimtime 作为我的animation-duration,并使用$delays 列表来配置我的pos-XXXX 样式的延迟:

.pos-1 {
  animation-delay: nth($delays, 1);
}
.pos-2 {
  animation-delay: nth($delays, 2);
}
.pos-3 {
  animation-delay: nth($delays, 3);
}
.pos-4 {
  animation-delay: nth($delays, 4);
}

这就像一个魅力,通过正确设置 $fullanimtime$delays,我可以将动画更改为在任何时间正确运行,无论是 8 秒还是 120 秒。

问题在于@keyframes 使用百分比。因此,如果我将其他变量设置为较长的​​动画时间,移动框的实际过渡会变得非常慢:8 秒,过渡运行 400 毫秒,但 120 秒,它们需要 6 秒,这比很酷。

所以$animationstops 变量应该让我配置合理的时间。但这不起作用。

由于我不明白的原因,我不能在关键帧声明中使用 Sass nth 函数,也不能使用 Sass 变量。

@keyframes rotate-board {
  nth($animationstops, 1) {
    // This gives an error:
    // Invalid CSS after "nth": expected keyframes selector, was "($animationstop..."
  }
  $somevariable {
    // This gives an error:
    // Invalid CSS after " $somevalue ": expected ":", was "{"
  }
}

有没有办法解决这个问题,还是我发现了 Sass 的限制?如果我想这样做,是否应该使用另一个预处理器?

body {
  margin: 0;
  padding: 0;
}
.frame {
  height: 580px;
  width: 100vw;
  background: lightgrey;
  position: relative;
  box-sizing: border-box;
}

.box {
  width: calc(50% - 30px);
  height: calc(50% - 30px);
  top: 20px;
  left: 20px;
  position: absolute;
  animation-name: rotate-board;
  animation-duration: 8s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}

.redbox {
  background: red;
}
.greenbox {
  background: green;
}
.bluebox {
  background: blue;
}
.orangebox {
  background: orange;
}

@keyframes rotate-board {
  0% {
    top: 20px;
    left: 20px;
    bottom: calc(50% + 10px);
    right: calc(50% + 10px);
  }
  20% {
    top: 20px;
    left: 20px;
    bottom: calc(50% + 10px);
    right: calc(50% + 10px);
  }
  25% {
    top: 20px;
    left: calc(50% + 10px);
    bottom: calc(50% + 10px);
    right: 20px;
  }
  45% {
    top: 20px;
    left: calc(50% + 10px);
    bottom: calc(50% + 10px);
    right: 20px;
  }
  50% {
    top: calc(50% + 10px);
    left: calc(50% + 10px);
    bottom: 20px;
    right: 20px;
  }
  70% {
    top: calc(50% + 10px);
    left: calc(50% + 10px);
    bottom: 20px;
    right: 20px;
  }
  75% {
    top: calc(50% + 10px);
    left: 20px;
    bottom: 20px;
    right: calc(50% + 10px);
  }
  95% {
    top: calc(50% + 10px);
    left: 20px;
    bottom: 20px;
    right: calc(50% + 10px);
  }
  100% {
    top: 20px;
    left: 20px;
    bottom: calc(50% + 10px);
    right: calc(50% + 10px);
  }
}

.pos-1 {
  animation-delay: 0s;
}
.pos-2 {
  animation-delay: -6s;
}
.pos-3 {
  animation-delay: -4s;
}
.pos-4 {
  animation-delay: -2s;
}
<div class="frame">
  <div class="box redbox pos-1"></div>
  <div class="box greenbox pos-2"></div>
  <div class="box bluebox pos-3"></div>
  <div class="box orangebox pos-4"></div>
</div>

【问题讨论】:

    标签: css sass css-animations


    【解决方案1】:

    你可以这样写你的变量:

    #{nth($animationstops, 1)} 
    

    我为你创建了一个 Sassmeister: https://www.sassmeister.com/gist/7c9b06c6b5a7cc580b14cbd1b312c566

    它在工作:https://codepen.io/anon/pen/PBeNLV

    PS:你的动画很漂亮!恭喜! :)

    【讨论】:

    • 太棒了!非常感谢。
    • 不客气! :) 而且...,好吧,这只是我的意见,但是... 和我们一起编写 Sass 代码,不要考虑更改预处理器,因为 SASS 太棒了! :P 干杯。 :)
    【解决方案2】:

    正如 ReSedano 所说,您可以使用语法 #{$var} 来解决您的问题。

    您还可以使用loops provided from Sass 来创建更易读且行数更少的代码。

    您可以使用 for 循环改进与 pos-* 相关的代码的最后部分,如下面的代码。

    $delays: 0s, -6s, -4s, -2s;
    @for $i from 1 through 4 {
      .pos-#{$i} {
        animation-delay: nth($delays, $i);
      }
    }
    

    您也可以尝试为您所要求的问题创建一个循环。例如,我发现有一个像 aaaabbbb 这样的模式,每边都有一个偏移量,可以映射您的案例以重现您想要的内容。有了这个逻辑,我创建了以下代码。

    $animationPerc: 0%, 20%, 25%, 45%, 50%, 70%, 75%, 95%, 100%;
    $animationPos: 20px, calc(50% + 10px);
    $animationOffset: 0, 2, 4, 6; // top, left, bottom, right
    @keyframes rotate-board {
      @for $i from 0 to 9 {
        #{nth($animationPerc, $i + 1)} {
          top: nth($animationPos, 1 + (floor((nth($animationOffset, 1) + $i)/4) % 2));
          left: nth($animationPos, 1 + (floor((nth($animationOffset, 2) + $i)/4) % 2));
          bottom: nth($animationPos, 1 + (floor((nth($animationOffset, 3) + $i)/4) % 2));
          right: nth($animationPos, 1 + (floor((nth($animationOffset, 4) + $i)/4) % 2));
        }
      }
    }
    

    【讨论】:

    • 绝妙的建议,谢谢。它实际上在我的雷达上,但我很快就被困住了。
    猜你喜欢
    • 2014-11-27
    • 2018-11-07
    • 2013-07-18
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 2013-12-27
    相关资源
    最近更新 更多