chromium/third_party/blink/web_tests/animations/animationworklet/playback-rate-scroll-timeline-accelerated-property.html

<!DOCTYPE html>
<title>When playback rate of scroll-linked WorkletAnimation is updated,
       the underlying effect produces correct visual result.</title>
<style>
#box {
  width: 100px;
  height: 100px;
  background-color: #00ff00;
}

#covered {
  width: 100px;
  height: 100px;
  background-color: #ff8080;
}

#scroller {
  overflow: auto;
  height: 100px;
  width: 100px;
  will-change: transform; /* force compositing */
}

#contents {
  height: 1000px;
  width: 100%;
}
</style>

<div id="box"></div>
<div id="covered"></div>
<div id="scroller">
  <div id="contents"></div>
</div>

<script id="passthrough"  type="text/worklet">
registerAnimator("passthrough_animator", class {
  animate(currentTime, effect) {
    effect.localTime = currentTime;
  }
});
</script>

<script src="resources/animation-worklet-tests.js"></script>
<script>
if (window.testRunner) {
  testRunner.waitUntilDone();
}

runInAnimationWorklet(
  document.getElementById('passthrough').textContent
).then(()=>{
  const box = document.getElementById('box');
  const effect = new KeyframeEffect(box,
    [
     { transform: 'translateY(0)'},
     { transform: 'translateY(200px)'}
    ], {
      duration: 1000,
    }
  );

  const scroller = document.getElementById('scroller');
  const timeline = new ScrollTimeline({ scrollSource: scroller, orientation: 'block' });
  const animation = new WorkletAnimation('passthrough_animator', effect, timeline);
  animation.play();

  animation.playbackRate = 2;

  // Move the scroller to the quarter way point.
  const maxScroll = scroller.scrollHeight - scroller.clientHeight;
  scroller.scrollTop = 0.25 * maxScroll;

  if (window.testRunner) {
    waitForAnimationFrameWithCondition(_ => {
      return getComputedStyle(box).transform != 'matrix(1, 0, 0, 1, 0, 0)';
    }).then(_ => {
      testRunner.notifyDone();
    });
  }
});
</script>