2013-10-07 23 views
0

我寫了一個腳本來拖動div容器。它適用於觸摸和鼠標事件。jquery應用慣性拖動勢頭

爲了讓我的容器在touchend後移動,我有一些困難來編寫動量腳本。 我知道如何計算的勢頭,但我不知道是什麼來實現它的正確方法...

這裏我的腳本:

var divToDrag = $('.container'); 
var divOnDrag = $(document); 

var dragging = false; 
var swipe = false; 
var scrollY = false; 
var threshold = {x:30, y:10}; 
var swipeLeft = false; 
var swipeRight = false; 
var swipeUp = false; 
var swipeDown = false; 
var threshx = false; 
var threshy = false; 

var maxSpeed = 5; 

function prefix() { 
    styles = window.getComputedStyle(document.documentElement, ''), 
    pre = (Array.prototype.slice 
     .call(styles) 
     .join('') 
     .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']) 
    )[1], 
    dom = ('WebKit|Moz|MS|O').match(new RegExp('(' + pre + ')', 'i'))[1]; 
} 
prefix(); 

function pointerEventXY(e) { 
     out = {x:0, y:0}; 
     if(e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend'){ 
     touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 
     out.x = touch.pageX; 
     out.y = touch.pageY; 
     } else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove') { 
     out.x = e.pageX; 
     out.y = e.pageY; 
     } 
     return out; 
}; 

divOnDrag.on('mousedown touchstart', function(event){ 
    dragging = true; 
    divToDrag.stop(); 
    pointerEventXY(event); 
    startCoordsX = prevCoordsX = out.x; 
    startCoordsY = prevCoordsY = out.y; 
    divCoordsX = divToDrag.position().left; 
    divCoordsY = divToDrag.position().top; 
    initialCoordsX = startCoordsX - divCoordsX; 
    initialCoordsY = startCoordsY - divCoordsY; 
    divToDrag.data("mouseEvents",[event]); 
}) 

divOnDrag.on('mousemove touchmove', function(event){  
    if (dragging == true) { 
     pointerEventXY(event); 
     currentCoordsX = out.x; 
     currentCoordsY = out.y; 
     xthreshold = Math.abs(currentCoordsX - startCoordsX) 
     ythreshold = Math.abs(currentCoordsY - startCoordsY) 

     var mouseEvents = divToDrag.data("mouseEvents"); 
     if ((event.timeStamp - mouseEvents[ mouseEvents.length - 1 ].timeStamp) > 40){ 
      mouseEvents.push(event); 
      if (mouseEvents.length > 2){ 
       mouseEvents.shift(); 
      } 
     } 

     if(xthreshold > threshold.x && ythreshold < threshold.y && scrollY == false || swipe == true) { 
      event.preventDefault(); 
      swipe = true; 
      dragDirection(); 
      x = currentCoordsX - initialCoordsX - threshx; 
      y = currentCoordsY - initialCoordsY - threshy; 
      divToDrag.attr('style', '-'+pre+'-transition: all 0s ease-in !important; -'+pre+'-transform: translate3d('+x+'px, 0px, 0px)'); 
     } else if (xthreshold < threshold.x && ythreshold > threshold.y) { 
      scrollY = true; 
     } 
    } 
}) 

divOnDrag.on('mouseup touchend', function(event){ 
    dragging = false; 
    scrollY = false; 
    swipe = false; 
    swipeLeft = false; 
    swipeRight = false; 
    swipeUp = false; 
    swipeDown = false; 
    momentum(); 
}) 

function dragDirection() { 
    if (prevCoordsX < currentCoordsX) { 
     swipeRight = true; 
     threshx = threshold.x; 
    } else if (prevCoordsX > currentCoordsX) { 
     swipeLeft = true; 
     threshx = -threshold.x; 
    } 
    if (prevCoordsY < currentCoordsY) { 
     swipeDown = true; 
     threshy = threshold.y; 
    } else if (prevCoordsY > currentCoordsY) { 
     swipeUp = true; 
     threshy = -threshold.y; 
    } 
    if (swipeRight == true && swipeLeft == true || swipeUp == true && swipeDown == true) { 
     threshx = 0;  
     threshy = 0; 
     prevCoordsX = currentCoordsX - initialCoordsX; 
     prevCoordsY = currentCoordsY - initialCoordsY; 
    } 
    prevCoordsX = currentCoordsX; 
    prevCoordsY = currentCoordsY; 
} 

function momentum() { 
    var lastEvent = divToDrag.data("mouseEvents").shift(); 
    if (!lastEvent){ 
     return; 
    } 
    var deltaX = (event.pageX - lastEvent.pageX); 
    var deltaY = (event.pageY - lastEvent.pageY); 
    var deltaMS = Math.max((event.timeStamp - lastEvent.timeStamp),1); 
    var speedX = Math.max(Math.min((deltaX/deltaMS), maxSpeed),-maxSpeed); 
    var speedY = Math.max(Math.min((deltaY/deltaMS), maxSpeed),-maxSpeed); 
    var lastStepTime = new Date();  

    divToDrag.animate(
     {textIndent: 0}, 
     {duration: (Math.max(Math.abs(speedX), Math.abs(speedY)) * 3000), 
     step: function(currentStep){ 
       speedX *= (currentStep/100); 
       speedY *= (currentStep/100); 
       var now = new Date(); 
       var stepDuration = (now.getTime() - lastStepTime.getTime()); 
       lastStepTime = now; 
       var position = divToDrag.position(); 
       var newLeft = (position.left + (speedX * stepDuration)); 
       var newTop = (position.top + (speedY * stepDuration)); 
       console.log(newLeft) 
       divToDrag.css({transform: 'translateX('+newLeft+'px)'});  
      } 
     } 
    ); 
} 

和小提琴:http://jsfiddle.net/V5Jmu/2/

UPDATE

http://jsfiddle.net/RdYQb/12/

我做了一個新的撥弄它似乎更好的工作得益於matjazek答案

回答

2

我建議你解決不同的形式給出了這個問題,但如果你在使用你的方法堅持,這樣的事情應該完成這項工作:

http://jsfiddle.net/RdYQb/

您可以設置阻力系數與

var drag=0.95; // Drag coeficient 
+0

謝謝!這真的很好。但是由於用於獲取事件頁面數據的方法,我無法使其在觸摸設備上正常工作。你爲什麼推薦最好的apraoch?我嘗試瞭解更多關於處理和創建多功能活動的方法...... – lolo