为什么这个 Javascript 动画在我的 PC 和我的 Pixel 6 手机上以不同的速度显示?我正在使用 delta 计时,但它不起作用

问题描述 投票:0回答:0

简而言之问题

这是一个 Codepen 演示:https://codepen.io/axis80/pen/MWPrPNE?editors=0010。两个滑块都应在 30 秒内完成一个 RGB 循环,但是在我的 Pixel 6 和移动 Chrome 浏览器上,底部的平滑滚动滑块需要 38 秒或更长时间。

更多详情

我正在尝试修改 SplideJS 的平滑滚动扩展,以便它在所有设备上以相同的速度滚动,而不管它们的帧速率如何。为此,我添加了一些实现增量计时的代码,即对于每一帧,它计算自上一帧以来经过的秒数,并将其乘以每秒移动的像素数,以确定在当前帧中移动多远框架。

Delta 计时似乎不起作用。如果我将它设置为每 10000 毫秒完成一张幻灯片(三张幻灯片总共 30000 毫秒),它在我的桌面上运行良好 (60fps) 并在该时间范围内完成幻灯片。不过,在我的 Google Pixel 6 手机上(可变帧率通常为 90-120),它的速度要慢得多(完成三张幻灯片需要 38000 毫秒或更长的时间)。

我已经检查了我的代码两天了,我看不出任何错误。我已将变量转储到控制台,它所做的所有计算似乎在台式机和移动设备上均正常。它只是在手机上运行速度较慢。有没有人知道可能导致这种情况的原因?

代码

  /**
   * Tracks the time that the last frame was rendered.
   */
  let lastRenderTimestamp: number;

  /**
   * Called on every animation frame while the auto scroll is active.
   */
  function move(): void {
    const position    = getPosition();
    const destination = computeDestination( position );

    if ( position !== destination ) {
      // Following line applies CSS transform: translate to move the slider
      translate( destination ); 
      updateIndex( ( currPosition = getPosition() ) );
    } else {
      if ( lastRenderTimestamp ) {
        pause( false );

        if ( autoScrollOptions.rewind ) {
          const speedValue = ( autoScrollOptions.speedMode === 'main' ? options.speed : autoScrollOptions.speed );
          Splide.go( speedValue > 0 ? 0 : Components.Controller.getEnd() );
        }
      }
    }

    throttledUpdateArrows();
    updateLastRenderTimestamp();
  }

  /**
   * Returns the position to move.
   *
   * @param position - The current position.
   *
   * @return A computed destination.
   */
  function computeDestination( position: number ): number {

    let pixelsToMoveThisFrame = 0;
    if ( autoScrollOptions.speedMode === 'main' && lastRenderTimestamp) {
      const elapsedTime = performance.now() - lastRenderTimestamp;
      const pixelsPerSecond = slideSize( null, null ) / options.speed;
      pixelsToMoveThisFrame = pixelsPerSecond * elapsedTime;
    } else {
      pixelsToMoveThisFrame = autoScrollOptions.speed || 1;
    }
    position += orient( pixelsToMoveThisFrame );

    if ( Splide.is( SLIDE ) ) {
      position = clamp( position, getLimit( false ), getLimit( true ) );
    }

    return position;
  }

  /**
   * Moves the slider to the provided position.
   *
   * @param position    - The position to move to.
   * @param preventLoop - Optional. If `true`, sets the provided position as is.
   */
  function translate( position: number, preventLoop?: boolean ): void {
    if ( ! Splide.is( FADE ) ) {
      const destination = preventLoop ? position : loop( position );
      style( list, 'transform', `translate${ resolve( 'X' ) }(${ destination }px)` );
      position !== destination && emit( EVENT_SHIFTED );
    }
  }

这是我的 Pixel 6 的屏幕截图,显示了增量计算的快照:

我已经手工完成了这些计算,它们对我来说似乎都是正确的。

这是一个包含更多详细信息的 Github 问题:https://github.com/Splidejs/splide-extension-auto-scroll/issues/10

有什么想法吗?

javascript animation game-development timedelta
© www.soinside.com 2019 - 2024. All rights reserved.