2016-07-25 96 views
1

我有這個滑塊,當我點擊其中一個它滑動到屏幕的中心。我遇到的問題是,如果我點擊已經靠近中心的,它移動得非常緩慢。 如果我點擊一個更遠,它需要相同的時間到達中心(但似乎是移動得更快;顯然這是一種幻覺)。 我想要做的就是讓他們都以相同的速度旅行。所以進一步離開中心需要更長的時間,但最接近的一個必須更快。動畫速度問題

目前我的代碼看起來是這樣的:

// Moves the current active item to the center 
moveToCenter: function (e, dragOptions, animate) { 

    // Get the central position 
    var center = $window.innerWidth/2, 
     rect = e.target.getBoundingClientRect(), 
     distance = center - rect.left - ((50 - 18)/2), // Make these variables? 
     positive = rect.left > center; 

    // If we should animation 
    if (animate) { 

     // Get our fake mouse position 
     var clientX = center, 
      target = center + distance, 
      offset = clientX/$window.innerWidth, 
      length = distance/$window.innerWidth; 

     // Initiate the first move 
     _setupMove(dragOptions, offset); 

     // Execute every 1 millisecond 
     var timer = $interval(function() { 

      // Get our new clientX 
      clientX = clientX + length; 
      offset = clientX/$window.innerWidth; 

      // Move 
      _moveElements(dragOptions, offset, service.updateDragElement); 

      // Should we stop? 
      var stop = positive ? clientX <= target : clientX >= target; 

      // If we should stop 
      if (stop) { 

       // Cancel the interval 
       $interval.cancel(timer); 
      } 
     }, 1); 

     // Otherwise 
    } else { 

     // Update the current position 
     dragOptions.currentX = distance/dragOptions.speed; 

     // Move our elements 
     service.updateDragElement(dragOptions); 
    } 
}, 

我知道它是與設置clientX做。我想,也許我需要工作了,我應該多遠基於時間,所以我創造了這個:

// Get our fake mouse position 
var clientX = center, 
    target = center + distance, 
    offset = clientX/windowWidth, 
    percent = distance/windowWidth, 
    interval = 1000 * percent; 

// Initiate the first move 
_setupMove(dragOptions, offset); 

// Execute every 1 millisecond 
var timer = $interval(function() { 

    // Get our new clientX 
    clientX = clientX + (distance * percent); 
    offset = clientX/windowWidth; 

    // Move 
    _moveElements(dragOptions, offset, service.updateDragElement); 

    // Should we stop? 
    var stop = positive ? clientX <= target : clientX >= target; 

    // If we should stop 
    if (stop) { 

     // Cancel the interval 
     $interval.cancel(timer); 
    } 
}, interval); 

在理論上它應該以相同的速度行駛,無論它有旅行的距離。但是這不起作用。

有沒有人有一些想法我可以解決這個問題?


我已經改變了我的代碼,這多虧了建議答案:

// Animates the slider 
animate: function (startTime, distance, duration, options) { 

    // Animate 
    requestAnimationFrame(function() { 

     // Get our offset 
     var now = Date.now(), 
      timeDelta = Math.min(now - startTime, duration), 
      timePercent = timeDelta/duration, 
      offset = timePercent * distance; 

     var finalX = options.finalX + offset; 

     // Create the transform 
     options.transform = 'translateX(' + finalX + 'px)'; 

     // Add to our element 
     options.element.style.transform = options.transform; 

     if (timeDelta < duration) { 
      service.animate(startTime, distance, duration, options); 
     } else { 
      options.finalX = finalX; 
      options.currentX = options.xOffset + (distance/$window.innerWidth); 
     } 
    }); 
}, 

// Moves the current active item to the center 
moveToCenter: function (e, dragOptions, animate) { 

    // Get the central position 
    var windowWidth = $window.innerWidth, 
     center = windowWidth/2, 
     rect = e.target.getBoundingClientRect(), 
     distance = center - rect.left - ((50 - 18)/2), // Make these variables? 
     positive = rect.left > center; 

    // If we should animation 
    if (animate) { 

     var start = center, 
      distance = center - rect.left - ((50 - 18)/2), // Make these variables? 
      now = Date.now(), 
      duration = distance/1; 

     // Animate our elements 
     service.animate(now, distance, duration, dragOptions); 

    // Otherwise 
    } else { 

     // Update the current position 
     dragOptions.currentX = distance/dragOptions.speed; 

     // Move our elements 
     service.updateDragElement(dragOptions); 
    } 
}, 

這就是現在滾動正確,如果我選擇留下任何東西的中心。當它處於中心的正確位置時,它只是跳到了這一點,而不是動畫。

回答

1

這裏是我推薦的方法。首先要弄清楚的速度你想:

var velocity = 1; // pixels/millisecond 

...然後用​​「循環」:

var startPoint = center; 
var endPoint = rect.left - 16; 
var distance = endPoint - startPoint; 
var startTime = Date.now(); 
var duration = distance/velocity; 

animate(); 

function animate() { 
    requestAnimationFrame(function() { 
    var now = Date.now(); 
    var timeDelta = Math.min(now - startTime, duration); 
    var timePercent = timeDelta/duration; 
    var offset = timePercent * distance; 
    _moveElements(dragOptions, offset, service.updateDragElement); 
    if (timeDelta < duration) { 
     animate(); 
    } 
    }); 
} 

使用setTimeout/setInterval可以添加人工滯後動畫和意志不是跨設備執行一致的。

+0

這在一個方向上效果很好,但是當朝另一個方向移動時,它只是跳躍。 – r3plica

+0

我剛剛更新了'var duration = Math.abs(distance)/ velocity'的持續時間。 – r3plica

+0

啊,是的,很好的更新。 – Jacob