2013-10-07 7 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

난 당신이 다른 aproach의 문제를 해결하는 것이 좋습니다,하지만 당신은 당신의 방법을 사용하여 주장하는 경우,이 같은 짓을 일 얻어야한다 :

http://jsfiddle.net/RdYQb/

당신은

var drag=0.95; // Drag coeficient 
+0

당신을 감사로 드래그 계수 (減 衰 係數)를 설정할 수 있습니다! 정말 좋아요. 하지만 이벤트 페이지 데이터를 가져 오는 데 사용 된 방법 때문에 터치 장치에서 작동하도록 만들 수는 없습니다. 당신은 최고의 apraoch에 대한 recommand 무엇입니까? 나는 versatil 이벤트를 처리하고 생성하는 방법에 대해 더 자세히 배우려고 노력합니다 ... – lolo