RXJS如何实现平滑滚动

时间:2019-07-18 20:16:40

标签: javascript typescript rxjs smooth-scrolling

我正在尝试使用RXJS实现平滑滚动功能。

以下代码可平滑滚动,但不按预期滚动。比达到目标所需的时间长得多。

有什么想法要解决吗?

const scrollableEl = document.getElementById('view');
const btn = document.getElementById('testBtn');
btn.addEventListener('click', () => {
  scrollTo(scrollableEl, 1000, 300);
});

function scrollTo(scrollableEl: HTMLElement, point: number, duration: number) {

  timer(0, 20, animationFrame).pipe(
    map((elapsedTime: number) => {
      const delta = point - scrollableEl.offsetTop;
      return {
        top: easeInOutQuad(elapsedTime, scrollableEl.offsetTop, delta, duration),
        elapsedTime
      };
    }),
    tap((target) => {
      console.log('scrollTo: ', target);
      scrollableEl.scrollTop = target.top;
    }),
    // Stop timer
    takeWhile((target: any) => target.elapsedTime < duration)
  ).subscribe();
}

以下是复制品:https://stackblitz.com/edit/rxjs-35vjhu

1 个答案:

答案 0 :(得分:2)

timer函数不会发出经过的时间,它的输出是一个从0:0、1、2、3等开始的数字序列。我认为您需要自己测量经过的时间:

const startTime = new Date().getTime();
timer(0, 20, animationFrame).pipe(
  map(() => {
    const elapsedTime = new Date().getTime() - startTime;
    const delta = point - scrollableEl.offsetTop;
    return {
      top: easeInOutQuad(elapsedTime, scrollableEl.offsetTop, delta, duration),
      elapsedTime
    };
  }),
  tap((target) => {
    console.log('scrollTo: ', target);
    scrollableEl.scrollTop = target.top;
  }),
  // Stop timer
  takeWhile((target: any) => target.elapsedTime < duration),
).subscribe();

这是更新的示例:https://stackblitz.com/edit/rxjs-dr44gy