CSS中的关键帧动画有什么替代方案?

5
我需要创建一个加载动画,目前我正在使用以下代码。
我想知道是否可以使用替代语法(比如过渡)重写它,而不是使用 keyframes
不幸的是,我正在使用构建工具来重写 keyframes 属性,这会导致添加错误,并且由此生成的CSS无法生效,因此我想绕过这个问题。
也可以使用JS解决方案,在CSS中添加样式。

.loadingSpinner {
    width: 50px;
    height: 50px;
    border: 5px solid #3498db;
    border-top-color: rgba(0, 0, 0, 0);
    border-left-color: rgba(0, 0, 0, 0);
    border-radius: 50%;
    -moz-animation: loadingSpinner 0.7s infinite linear;
    -o-animation: loadingSpinner 0.7s infinite linear;
    -webkit-animation: loadingSpinner 0.7s infinite linear;
    animation: loadingSpinner 0.7s infinite linear;
}

@-moz-keyframes loadingSpinner {
  0%   {
      -moz-transform: rotate(0deg);

  }
  100% {
      -moz-transform: rotate(360deg);
  }
}

@-o-keyframes loadingSpinner {
  0%   {
      -o-transform: rotate(0deg);

  }
  100% {
      -o-transform: rotate(360deg);
  }
}

@-webkit-keyframes loadingSpinner {
  0%   {
      -webkit-transform: rotate(0deg);

  }
  100% {
      -webkit-transform: rotate(360deg);
  }
}

@keyframes loadingSpinner {
  0%   {
      transform: rotate(0deg);

  }
  100% {
      transform: rotate(360deg);
  }
}
<div class="loadingSpinner"></div>


与CSS内联选项相关:https://dev59.com/x2Yq5IYBdhLWcg3whRDV - GibboK
3个回答

3
您可以使用一个非常长的过渡效果,并使用快速的JS代码行触发它。例如,添加一个.start类来触发60秒的过渡效果,将旋转器旋转数次(例如36000度)。
.loadingSpinner {
    width: 50px;
    height: 50px;
    border: 5px solid #3498db;
    border-top-color: rgba(0, 0, 0, 0);
    border-left-color: rgba(0, 0, 0, 0);
    border-radius: 50%;
    transform: rotate(0deg);
    transition: transform 60s;
}

.loadingSpinner.start {
    transform: rotate(36000deg);
}

示例:https://jsfiddle.net/6tkf1f95/1/

1
谢谢,这是个有趣的想法。你知道除了使用rotate(36000deg)之外,还有什么其他方法可以让它看起来像无限旋转吗? - GibboK
使用JavaScript间隔旋转360度 - ezakto

0

只使用CSS解决方案怎么样?

@keyframes spinner {
    to {transform: rotate(360deg);}
}
 
@-webkit-keyframes spinner {
    to {-webkit-transform: rotate(360deg);}
}
 
.spinner {
    min-width: 30px;
    min-height: 30px;
}
 
.spinner:before {
    content: 'Loading…';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 50px;
    height: 50px;
    margin-top: -13px;
    margin-left: -13px;
}
 
.spinner:not(:required):before {
    content: '';
    border-radius: 50%;
    border: 5px solid #ccc;
    border-top-color: #03ade0;
    animation: spinner .7s linear infinite;
    -webkit-animation: spinner .7s linear infinite;
}
<div class="spinner"></div>


谢谢您的发布,但实际上我需要一个不使用@keyframes的版本...您能否请修订一下? - GibboK
1
当然,给我几分钟 =) - MKAD
我有个不好的消息 = 我尝试了几种方法,发现你必须使用Js或关键帧来旋转Spinner。如果没有关键帧或js,浏览器不知道何时应该开始动画。我认为@ezakto的解决方案是你的最佳选择。 - MKAD

0
你可以使用单个CSS自定义属性创建一个无限CSStransition,每当JavaScript transitionend事件触发时,您可以更新其值。
在CSS样式表中,我们可以从以下transformtransition开始:
  transform: var(--rotation);
  transition: transform 0.7s linear;

我们需要初始化--rotation,因此我们可以在样式表的顶部进行初始化:

:root {
  --rotation: rotate(0deg);
}

目前为止还不错。现在我们需要一个JS函数,每次转换完成时将旋转值增加360度

const rotateSpinner = () => {

  let loadingSpinnerStyles = window.getComputedStyle(loadingSpinner);
  let rotation = loadingSpinnerStyles.getPropertyValue('--rotation');
  rotation = parseInt(rotation.replace('rotate(', '').replace('deg)', '')) + 360;
  rotation = 'rotate(' + rotation + 'deg)';
  loadingSpinner.style.setProperty('--rotation', rotation);
}

当我们把所有东西放在一起,就会得到下面的工作示例。


工作示例:

const loadingSpinner = document.querySelector('.loadingSpinner');

const rotateSpinner = () => {

  let loadingSpinnerStyles = window.getComputedStyle(loadingSpinner);
  let rotation = loadingSpinnerStyles.getPropertyValue('--rotation');
  rotation = parseInt(rotation.replace('rotate(', '').replace('deg)', '')) + 360;
  rotation = 'rotate(' + rotation + 'deg)';
  loadingSpinner.style.setProperty('--rotation', rotation);
}

loadingSpinner.addEventListener('transitionend', rotateSpinner);
window.addEventListener('load', rotateSpinner);
:root {
  --rotation: rotate(0deg);
}

.loadingSpinner {
  width: 50px;
  height: 50px;
  border: 5px solid #3498db;
  border-top-color: rgba(0, 0, 0, 0);
  border-left-color: rgba(0, 0, 0, 0);
  border-radius: 50%;
  transform: var(--rotation);
  transition: transform 0.7s linear;
}
<div class="loadingSpinner"></div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接