CSS改变动画持续时间而不跳跃

kig*_*kig 9 html javascript css jquery animation

我有一个简单的车轮旋转动画.我试图使用滑块(输入范围)控制旋转轮的速度.我已设法做到这一点,但每次我更改动画时动画重新启动(它跳转).寻找一种解决方案,以创造一个平稳的速度增长.当用户增加滑块的值时,轮子以增加的速度旋转.

在下面的代码中,#loading是旋转轮.

$(document).on('input', '#slider', function() {
  var speed = $(this).val();
  $('#speed').html(speed);
  $("#loading").css("animation-duration", 50 / speed + "s");
});
Run Code Online (Sandbox Code Playgroud)
#loading {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  transform-origin: 50% 50%;
  animation: rotateRight infinite linear;
  animation-duration: 0;
}

@keyframes rotateRight {
  100% {
    transform: rotate(360deg);
  }
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<img id="loading" src="//placehold.it/100">
<input type="range" min="0" max="100" value="0" class="slider" id="slider">
<p>Speed: <span id="speed"></span></p>
Run Code Online (Sandbox Code Playgroud)

Aku*_*bik 7

经典问题
(有跳跃..现在还)

带有 jQ​​uery 的版本

var lasttime = 0,  lastduration = 0,  angle = 0;
$(document).on('input', '#slider', function(event) {
  var speed = $(this).val();
  $('#speed').html(speed);
  
  var el = $("#loading");
  var duration = (speed > 0) ? 50 / speed : 0;
  var currenttime = event.originalEvent.timeStamp / 1000;
  var difftime = currenttime - lasttime;
  el.removeClass("enable_rotate").show();
  
  if (!lastduration && duration)
      el.css("transform", "");
  else
      angle += (difftime % lastduration) / lastduration;
      
  if (duration){     
    el.css("animation-duration", duration + "s")
    .css("animation-delay", -duration * angle + "s")    
    .addClass("enable_rotate");
    }
  else
    el.css("transform", "rotate(" + 360 * angle + "deg)");
  
  angle -= angle | 0; //use fractional part only
  lasttime = currenttime;
  lastduration = duration;
});
Run Code Online (Sandbox Code Playgroud)
.anime_object {
  width:100px; height:100px; background-color:black;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

.enable_rotate {
  animation: rotateRight infinite linear;
}

@keyframes rotateRight {
  100% {
    transform: rotate(360deg);
  }
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<img id="loading" class="anime_object">
<input type="range" min="0" max="100" value="0" id="slider">
<p>Speed: <span id="speed"></span></p>
Run Code Online (Sandbox Code Playgroud)

工作草案

保存当前动画的变量
http://www.w3.org/TR/css-animations-1/#interface-animationevent-attributes

  1. 所以
  2. css-tricks.com


zer*_*298 0

我不完全确定如果没有不使用 CSS 动画的不同方法,这是否可行。问题是,每当您更改速度时,动画都不会正常化。它始终从动画的 0% 到动画的 100%。每次调整 时animation-duration,您都会使用动画中的当前位置重新插值。

换句话说,如果从 at 更改为animation-duration: 2550t=12动画完成一半(180 度);现在只完成了四分之一(90 度)。但你无法控制t,那是浏览器的。如果可以的话,您可能希望设置t为保持插值中的位置,在本例中为t=25,这样您就可以保持与原来相同的动画完成百分比,但可以延长剩余时间。

我对你的脚本做了一些修改,以尝试更好地展示我所描述的内容。它会在速度 0 到 5 之间每秒增加速度。0.25您可以看出问题是由浏览器控制的t

你可以重写它,以便t用 JavaScript 来控制自己,但我认为你必须放弃 CSS 动画。

要进一步讨论这个浏览器控制t变量的要点,请查看这篇关于 CSS 技巧的文章:神话破灭:CSS 动画与 JavaScript

有些浏览器允许您暂停/恢复 CSS 关键帧动画,但仅此而已。您无法寻找动画中的特定位置,也无法平滑地中途反转或更改时间刻度或在某些位置添加回调或将它们绑定到一组丰富的播放事件。JavaScript 提供了很好的控制,如下面的演示所示。

这就是您的问题,您希望能够更改动画的持续时间,但同时还要找到动画中的正确位置。

$(function() {
  var speed = parseInt($("#slider").val(), 10);
  $("#speed").html(speed);
  $("#loading").css("animation-duration", 50 / speed + "s");

  var forward = true;
  setInterval(function() {
    speed += (forward ? 0.25 : -0.25);
    if (speed >= 5) {
      forward = false;
    } else if (speed <= 0) {
      forward = true;
    }
    $("#loading").css("animation-duration", 50 / speed + "s");
    $("#slider").val(speed);
    $("#speed").html(speed);
  }, 1000);
});
Run Code Online (Sandbox Code Playgroud)
#loading {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  transform-origin: 50% 50%;
  animation: rotateRight infinite linear;
  animation-duration: 0;
}

@keyframes rotateRight {
  100% {
    transform: rotate(360deg);
  }
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<img id="loading" src="//placehold.it/100">
<input type="range" min="0" max="100" value="0" step=".25" class="slider" id="slider" value="0">
<p>Speed: <span id="speed"></span></p>
Run Code Online (Sandbox Code Playgroud)