2016-12-20 8 views
4

基本的に私が達成したいのは、あるdivを別のcontainer div内にドラッグすることです。内部divは、コンテナdivの境界に達すると停止する必要があります。私はほとんどの部分を行うことができました。しかし問題は、内側のdivをゆっくりとドラッグすると、慎重に、エッジにあるはずの場所で停止しますが、ドラッグすると高速にドラッグするとエッジがオーバーフローしたり、エッジの前に停止することがあります。ここでの問題は何ですか?これを解決するにはどうすればよいですか?上記のコードJavaScriptアニメーションを円滑にするには?

Here is full code

function mouseMove(e) { 
    e.preventDefault();  
    console.log("mouse moving");  

    if(isMouseDown > 0 && currentElement) { 
     mouseX = e.clientX;   
     mouseY = e.clientY; 

     var diffX = mouseX - lastMouseX; 
     var diffY = mouseY - lastMouseY;   

     if(diffX + lastElementX + elementWidth < rightLimit && diffX + lastElementX > leftLimit) { 
      lastElementX += diffX; 
      lastMouseX = mouseX; 
     } 

     if(diffY + lastElementY + elementHeight < bottomLimit && diffY + lastElementY > topLimit) { 
      lastElementY += diffY; 
      lastMouseY = mouseY;     
     }       

     setCurrentElementPosition(lastElementX, lastElementY);        
    }               
} 

、内側のdivの位置を変更するマウス移動イベントで実行されます。

答えて

2

ここは私のものです。私はdiffX/diffYから要素の動きをデカップリングしてきました:

https://jsfiddle.net/ttyrtjez/

// in onmousedown 
offsetX = e.clientX - lastElementX; 
offsetY = e.clientY - lastElementY; 

// in onmousemove 
var newElementX = mouseX - offsetX; 
var newElementY = mouseY - offsetY; 

if (newElementX + elementWidth >= rightLimit - 1) newElementX = rightLimit - elementWidth - 2; 
if (newElementX < leftLimit) newElementX = leftLimit; 
if (newElementY + elementHeight >= bottomLimit - 1) newElementY = bottomLimit - elementHeight - 2; 
if (newElementY < topLimit) newElementY = topLimit; 

setCurrentElementPosition(newElementX, newElementY); 
3

ここで私の解決策を紹介します。以前はビデオゲームをプログラミングしていましたが、この問題は多く発生しています。

あなたはそれが外に出るかどうか確認していますが、それがあれば何もしません!外に出る場合は、エッジに設定する必要があります。

https://jsfiddle.net/7btv7oqy/3/

var lastElementX = 0; //last X position of element 
var lastElementY = 0; //last Y position of element 
var lastMouseX = 0; //last X position of mouse 
var lastMouseY = 0;//last Y position of mouse 
var mouseX = 0; //current mouse position X 
var mouseY = 0; //current mouse position Y 

var currentElement = null; //currently selected div 
var elementWidth = 0; 
var elementHeight = 0; 

var container = null; //container div 
var isMouseDown = 0; //if greater than zero, mouse is down 

//limits of container div 
var bottomLimit = 0; 
var topLimit = 0; 
var leftLimit = 0; 
var rightLimit = 0; 

function init() { 
    container = document.getElementsByClassName("container")[0]; 

    topLimit = container.getBoundingClientRect().top; 
    bottomLimit = container.getBoundingClientRect().bottom; 
    leftLimit = container.getBoundingClientRect().left; 
    rightLimit = container.getBoundingClientRect().right; 

    document.addEventListener("mousedown", function mouseDown(e) { 
     e.preventDefault(); 
     ++isMouseDown; 
     document.addEventListener("mousemove", mouseMove); 

     setCurrentElement(getElementUnderMouse(e)); //set current element 
     currentElement.style.position = "absolute"; 

     lastElementX = currentElement.getBoundingClientRect().left; 
     lastElementY = currentElement.getBoundingClientRect().top; 

     lastMouseX = e.clientX; 
     lastMouseY = e.clientY; 


    }); 

    document.addEventListener("mouseup", function mouseUp(e) { 
     e.preventDefault(); 
     --isMouseDown; 
     setCurrentElement(null); 
     document.removeEventListener("mousemove", mouseMove); 
    }); 

} 

function mouseMove(e) { 
    e.preventDefault(); 
    console.log("mouse moving"); 
    // report(e); 

    if(isMouseDown > 0 && currentElement) { 
     mouseX = e.clientX; 
     mouseY = e.clientY; 

     var diffX = mouseX - lastMouseX; 
     var diffY = mouseY - lastMouseY; 

     if(diffX + lastElementX + elementWidth < rightLimit && diffX + lastElementX > leftLimit) { 
      lastElementX += diffX; 
     } else { 
      //without this, the location wouldn't update at all: 

      //check if it would go off the right edge, set to right edge 
      if (diffX + lastElementX + elementWidth >= rightLimit) { 
       lastElementX = rightLimit - elementWidth; 
      } 

      //check if it would go off the left edge, set to left edge 
      if(diffX + lastElementX <= leftLimit) { 
       lastElementX = leftLimit; 
      } 

     } 
     //this will always happen: 
     lastMouseX = mouseX; 

     if(diffY + lastElementY + elementHeight < bottomLimit && diffY + lastElementY > topLimit) { 
      lastElementY += diffY; 

     } else { 
      //without this, the location wouldn't update at all: 

      //check if it would go off the bottom edge, set to bottom edge 
      if(diffY + lastElementY + elementHeight >= bottomLimit) { 
       lastElementY = bottomLimit - elementHeight; 
      } 


      //check if it would go off the top edge, set to top edge 
      if(diffY + lastElementY <= topLimit) { 
       lastElementY = topLimit; 
      } 

     } 

     //this will always happen: 
     lastMouseY = mouseY; 

     setCurrentElementPosition(lastElementX, lastElementY); 
    } 
} 

function setCurrentElementPosition(left = null, top = null) { 
    if(currentElement) { 
     currentElement.style.top = top + 'px' 
     currentElement.style.left = left + 'px'; 
    } 
} 

function setCurrentElement(element) { 
    currentElement = element; 
    if(element) { 
     elementWidth = currentElement.offsetWidth; 
     elementHeight = currentElement.offsetHeight; 
    } else { 
     elementWidth = 0; 
     elementHeight = 0; 
    } 
} 

function hasClass(element, cls) { 
    return ("" + element.className + "").indexOf("" + cls + "") > -1; 
} 

function getElementUnderMouse(e) { 
    var x = e.clientX; 
    var y = e.clientY; 
    return document.elementFromPoint(x, y); 
} 

function report(e) { 
    console.log("isMouseDown: " + isMouseDown); 
    console.log("mouseX: " + e.clientX); 
    console.log("mouseY: " + e.clientY); 
    console.log("currentElement: " + currentElement); 
    console.log("currentElement top: " + currentElement.getBoundingClientRect().top); 
    console.log("currentElement bottom: " + currentElement.getBoundingClientRect().bottom); 
    console.log("container top: " + container.getBoundingClientRect().top); 
    console.log("container bottom: " + container.getBoundingClientRect().bottom); 
} 

init(); 

EDIT:それは右と下に1つの画素欠けている理由はわからない、あなたはその前にいくつかの調査を行う必要があるでしょう。 offsetWidthを使用しているにもかかわらず、国境を考慮していないようです。がんばろう!

関連する問題