Re: [csswg-drafts] [cssom-view-1] Provide onAnimationEnd callback in scrollIntoView options (#3744)

I had issues with the workarounds other commenter provided so I made this function that basically returns a cancellable promise that smoothly scrolls if needed. It isn't perfect, but i hope it helps someone

```ts
type SmoothScrollIntoViewArgs = {
  scrollee: HTMLElement;
  durationMs?: number;
  direction?: 'horizontal' | 'vertical';
  abortSignal?: AbortSignal;
};

export const smoothScrollIntoView = ({
  scrollee,
  abortSignal,
  direction = 'horizontal',
  durationMs = 250,
}: SmoothScrollIntoViewArgs) => {
  abortSignal?.throwIfAborted();
  const container = scrollee.parentElement!;

  const [moveProp, compareProp] =
    direction === 'horizontal'
      ? (['scrollLeft', 'offsetLeft'] as const)
      : (['scrollTop', 'offsetTop'] as const);

  if (durationMs === 0) durationMs = 0.1;

  const startPos = container[moveProp];
  const targetPos = scrollee[compareProp] - container[compareProp];

  const startingDifference = targetPos - startPos;

  if (startingDifference > -1 && startingDifference < 1) {
    return Promise.resolve();
  }

  const constrainer = startPos > targetPos ? Math.max : Math.min;
  const speed = startingDifference / durationMs;
  return new Promise<void>((resolve) => {
    let startTime = undefined as DOMHighResTimeStamp | undefined;
    const move = (timeFrame: DOMHighResTimeStamp) => {
      abortSignal?.throwIfAborted();
      if (startTime === undefined) {
        startTime = timeFrame;
        requestAnimationFrame(move);
        return;
      }

      const elapsed = timeFrame - startTime;

      const toScroll = speed * elapsed;

      const toScrollTo = constrainer(targetPos, startPos + toScroll);

      container[moveProp] = toScrollTo;

      const currentPos = container[moveProp];
      const currentTargetPos = scrollee[compareProp] - container[compareProp];
      const diff = currentPos - currentTargetPos;

      if (diff > 1 || diff < -1) {
        requestAnimationFrame(move);
      } else {
        resolve();
      }
    };
    requestAnimationFrame(move);
  });
};


```

-- 
GitHub Notification of comment by Pentadome
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3744#issuecomment-2294103706 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Friday, 16 August 2024 19:40:44 UTC