2016-12-20 12 views
4

В принципе, я хочу, чтобы перетащить некоторый div в другой контейнер 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: Не знаю, почему он не хватает на один пиксель в правой и нижней части, вы должны будете сделать некоторое исследование на этом фронте. Похоже, что он не принимает во внимание границу, несмотря на то, что вы используете offsetWidth. Удачи!