Javascript 如何将requestAnimationFrame与setInterval一起使用?
请参阅下面的代码片段 它会在单击按钮时创建一个加载器。但动画并不平滑Javascript 如何将requestAnimationFrame与setInterval一起使用?,javascript,html,css,animation,Javascript,Html,Css,Animation,请参阅下面的代码片段 它会在单击按钮时创建一个加载器。但动画并不平滑 我最近读到了requestAnimationFrame函数,它可以完成这项工作。但是,由于在requestAnimationFrame函数中无法指定时间,我如何使用它来完全替换setInterval 它可以与setInterval一起使用吗 设idx=1; 常数timetoEnd=5000; 功能进度条(宽度){ this.width=宽度| | 0; this.id=`pBar-${idx++}`; this.create
我最近读到了
requestAnimationFrame
函数,它可以完成这项工作。但是,由于在requestAnimationFrame
函数中无法指定时间,我如何使用它来完全替换setInterval
它可以与setInterval
一起使用吗
设idx=1;
常数timetoEnd=5000;
功能进度条(宽度){
this.width=宽度| | 0;
this.id=`pBar-${idx++}`;
this.create=()=>{
让pBar=document.createElement('div');
pBar.id=this.id;
pBar.className=`p-bar`;
pBar.innerHTML=`;
返回pBar;
};
this.animator=()=>{
let element=document.querySelector(`${(this.id)}div`);
如果(此宽度小于100){
这个.width++;
element.style.width=`${this.width}%`;
}否则{
clearInterval(这个.interval);
}
};
this.animate=()=>{
this.interval=setInterval(this.animator,timetoEnd/100);
}
}
函数addLoader(){
设bar1=新进度条(40);
let container=document.querySelector(“容器”);
container.appendChild(bar1.create());
bar1.animate();
}
.p-bar{
宽度:400px;
高度:20px;
背景:1px固体#ccc;
利润率:10px;
溢出:隐藏;
边界半径:4px;
}
.p-bar.装载机{
宽度:0;
背景:1565C0;
身高:100%;
}
你说得对,requestAnimationFrame
是制作动画时避免UI阻塞的推荐方法
您可以在开始时记住绝对开始时间,而不是在每一帧都尝试这样做。然后,它只是一个基于开始时间和当前时间之间的增量时间计算宽度的问题
另外,document.querySelector
被认为是一个相对“繁重”的操作,所以我添加了this.element
,以避免在每一帧都这样做
下面是计算新宽度的方法:((100-this.startWidth)/timetoEnd)*deltaT+this.startWidth
100-这个.startWidth
是我们必须设置动画的总宽度(100-this.startWidth)/timetoEnd
是每秒必须增加的宽度(1)((100-this.startWidth)/timetoEnd)*deltaT
是我们必须添加到(1)的宽度设idx=1;
常数timetoEnd=5000;
功能进度条(startWidth){
this.startWidth=startWidth | | 0;
this.id=`pBar-${idx++}`;
this.create=()=>{
让pBar=document.createElement('div');
pBar.id=this.id;
pBar.className=`p-bar`;
pBar.innerHTML=`;
返回pBar;
};
this.animator=()=>{
const deltaT=Math.min(new Date().getTime()-this.start,timetoEnd);
如果(deltaT{
this.element=document.querySelector(`${(this.id)}div`);
this.start=new Date().getTime();
这个。动画师();
}
}
函数addLoader(){
设bar1=新进度条(40);
let container=document.querySelector(“容器”);
container.appendChild(bar1.create());
bar1.animate();
}
.p-bar{
宽度:400px;
高度:20px;
背景:1px固体#ccc;
利润率:10px;
溢出:隐藏;
边界半径:4px;
}
.p-bar.装载机{
宽度:0;
背景:1565C0;
身高:100%;
}
:“…回调方法被传递一个参数,DOMHighResTimeStamp
,该参数指示requestAnimationFrame()排队的回调开始触发的当前时间。”请检查有关如何使用该信息的。您的解决方案看起来不错。但是,只有一个问题,我们是否不清除requestAnimationFrame?requestAnimationFrame
仅请求一个帧,就这一点而言,它的行为类似于setTimeout
。这就是我在这里调用requestAnimationFrame
的原因。我得到了它。不过,我观察到一件事,上面的宽度计算并不能使内部宽度达到100%。如果检查DOM,每个加载程序都以不同的宽度完成。oups:)我的错,我将解决方案编辑为maxdeltaT
到timetoEnd
。由于我们不知道何时执行死刑,deltaT可能会超过5000人。然而,它并没有使宽度达到100%,所以我在末尾添加了一个小的else if块来实现这一点。:)我接受了你的回答。希望得到回报。