Javascript 如何使用RxJS生成requestAnimationFrame循环?
我的目标是创建一个动画循环a laJavascript 如何使用RxJS生成requestAnimationFrame循环?,javascript,rxjs,rxjs5,requestanimationframe,Javascript,Rxjs,Rxjs5,Requestanimationframe,我的目标是创建一个动画循环a larequestAnimationFrame,这样我就可以执行以下操作: animationObservable.subscribe(() => { // drawing code here }); 我尝试将此代码作为基本测试: let x = 0; Rx.Observable .of(0) .repeat(Rx.Scheduler.animationFrame) .takeUntil(Rx.Observable.time
requestAnimationFrame
,这样我就可以执行以下操作:
animationObservable.subscribe(() =>
{
// drawing code here
});
我尝试将此代码作为基本测试:
let x = 0;
Rx.Observable
.of(0)
.repeat(Rx.Scheduler.animationFrame)
.takeUntil(Rx.Observable.timer(1000))
.subscribe(() => console.log(x++));
我希望它能在1秒内记录从0到大约60的数字(因为这是我显示器的刷新率)。相反,它会快速记录数字(比requestAnimationFrame
的速度快得多),开始导致页面延迟,并最终在大约10000秒后溢出堆栈
为什么
animationFrame
调度程序会有这种行为,使用RxJS运行动画循环的正确方法是什么?这是因为Observable.of
的默认行为是立即发射
要更改此行为,应在调用的可观察时指定调度程序:
设x=0;
可观测
.of(0,Rx.Scheduler.animationFrame)
.重复
.takeUntil(接收可观测计时器(1000))
.subscribe(()=>console.log(x++))代码>
这就是我如何将requestAnimationFrame与rxjs结合使用的方法。我见过很多开发人员使用0而不是animationFrame.now()。最好是消磨时间,因为在动画中经常需要时间
const{Observable,Scheduler}=Rx;
const requestAnimationFrame$=可观察
.延迟(()=>可观察
.of(Scheduler.animationFrame.now(),Scheduler.animationFrame)
.重复
.map(start=>Scheduler.animationFrame.now()-start)
);
//示例用法
const duration$=duration=>requestAnimationFrame$
.map(时间=>时间/持续时间)
.takeWhile(进度=>进度<1)
.concat([1])
工期$(60000)
.认购((i)=>{
clockPointer.style.transform=`rotate(${i*360}度)`;
});代码>
从RxJs>=5.5开始,您可以通过以下方式进行操作:
import { animationFrameScheduler, of, timer } from 'rxjs';
import { repeat,takeUntil } from 'rxjs/operators';
let x = 0;
of(null, animationFrameScheduler)
.pipe(
repeat(),
takeUntil(timer(1000)),
)
.subscribe(() => {
console.log(x++);
});
或:
不知何故,我忽略了这一点,可能是因为当我第一次遇到这个问题时,我没有使用
的,而是使用了一些行为不同的东西。突然间,情况变得更清楚了。谢谢我尝试了interval和of+repeat,我注意到interval版本每帧发射两次,看看这个stackblitz:@pokrishka我想你应该在GitHub repo中将它作为一个bug打开:也许,在这个问题上引用你的评论和推文。这真的很酷!你能谈谈requestAnimationFrame$
Observable的构造吗?
import { animationFrameScheduler, of, timer } from 'rxjs';
import { repeat, tap, takeUntil } from 'rxjs/operators';
let x = 0;
of(null, animationFrameScheduler)
.pipe(
tap(() => {
console.log(x++);
}),
repeat(),
takeUntil(timer(1000)),
)
.subscribe();