requestAnimationFrame 没有触发提供给它的函数
requestAnimationFrame is not triggering the function supplied to it
我使用 setInterval 实现了无限循环动画。我现在想将实现更改为 requestAnimationFrame(),这样我就能获得我想要的性能。由于某些原因,requestAnimationFrame() 不会调用提供给它的函数。
我的代码是这样的;
var index = 0;
var $btn = $('.btn');
function btnBlinkRun() {
if (index < 2) {
index = index + 1;
} else {
index = 0;
}
$('#ani--scaleinout').removeAttr('id');
$($btn[index]).attr('id', 'ani--scaleinout');
window.requestAnimationFrame(btnBlinkRun);
}
btnBlinkRun();
.btn{
width: 30px;
height: 30px;
background: blue;
border-radius: 100%;
margin-bottom: 10px;
}
#ani--scaleinout {
animation: zoominout 1s ease-in;
}
@keyframes zoominout {
50% {
transform: scale(1.4);
}
100% {
transform: scale(1);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="btn" id="ani--scaleinout"></div>
<div class="btn"></div>
<div class="btn"></div>
</div>
看起来你每秒发射 requestAnimationFrame
多次。您的 css 动画持续时间为 1s
。但是您每 x 毫秒删除一次属性。
它正在触发,它发生得如此之快以至于你看不到它。为了演示更改对 window.requestAnimationFrame
的调用以使用 setTimeout,您会注意到动画:
setTimeout(function() {
window.requestAnimationFrame(btnBlinkRun);
}, 1000);
不是说这是首选解决方案,而是解释为什么会这样。
它执行得很好。但我想它不会做你想做的事。
动画帧在每个渲染帧(例如 60fps)上触发,而不是在 CSS 个动画关键帧上触发。
animationend
活动是你的朋友。
var index = 0;
var buttons = document.querySelectorAll('.btn');
function btnBlinkRun() {
if (index < 2) {
index = index + 1;
} else {
index = 0;
}
const element = document.querySelector('#ani--scaleinout');
element.id = null;
buttons[index].id = 'ani--scaleinout';
buttons[index].addEventListener("animationend", btnBlinkRun, { once: true });
}
btnBlinkRun();
.btn{
width: 30px;
height: 30px;
background: blue;
border-radius: 100%;
margin-bottom: 10px;
}
#ani--scaleinout {
animation: zoominout 1s ease-in;
}
@keyframes zoominout {
50% {
transform: scale(1.4);
}
100% {
transform: scale(1);
}
}
<div>
<div class="btn" id="ani--scaleinout"></div>
<div class="btn"></div>
<div class="btn"></div>
</div>
我使用 setInterval 实现了无限循环动画。我现在想将实现更改为 requestAnimationFrame(),这样我就能获得我想要的性能。由于某些原因,requestAnimationFrame() 不会调用提供给它的函数。
我的代码是这样的;
var index = 0;
var $btn = $('.btn');
function btnBlinkRun() {
if (index < 2) {
index = index + 1;
} else {
index = 0;
}
$('#ani--scaleinout').removeAttr('id');
$($btn[index]).attr('id', 'ani--scaleinout');
window.requestAnimationFrame(btnBlinkRun);
}
btnBlinkRun();
.btn{
width: 30px;
height: 30px;
background: blue;
border-radius: 100%;
margin-bottom: 10px;
}
#ani--scaleinout {
animation: zoominout 1s ease-in;
}
@keyframes zoominout {
50% {
transform: scale(1.4);
}
100% {
transform: scale(1);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="btn" id="ani--scaleinout"></div>
<div class="btn"></div>
<div class="btn"></div>
</div>
看起来你每秒发射 requestAnimationFrame
多次。您的 css 动画持续时间为 1s
。但是您每 x 毫秒删除一次属性。
它正在触发,它发生得如此之快以至于你看不到它。为了演示更改对 window.requestAnimationFrame
的调用以使用 setTimeout,您会注意到动画:
setTimeout(function() {
window.requestAnimationFrame(btnBlinkRun);
}, 1000);
不是说这是首选解决方案,而是解释为什么会这样。
它执行得很好。但我想它不会做你想做的事。 动画帧在每个渲染帧(例如 60fps)上触发,而不是在 CSS 个动画关键帧上触发。
animationend
活动是你的朋友。
var index = 0;
var buttons = document.querySelectorAll('.btn');
function btnBlinkRun() {
if (index < 2) {
index = index + 1;
} else {
index = 0;
}
const element = document.querySelector('#ani--scaleinout');
element.id = null;
buttons[index].id = 'ani--scaleinout';
buttons[index].addEventListener("animationend", btnBlinkRun, { once: true });
}
btnBlinkRun();
.btn{
width: 30px;
height: 30px;
background: blue;
border-radius: 100%;
margin-bottom: 10px;
}
#ani--scaleinout {
animation: zoominout 1s ease-in;
}
@keyframes zoominout {
50% {
transform: scale(1.4);
}
100% {
transform: scale(1);
}
}
<div>
<div class="btn" id="ani--scaleinout"></div>
<div class="btn"></div>
<div class="btn"></div>
</div>