javascript - 使javascript动画流畅?

标签 javascript html css dom-events

基本上我想要实现的是将一些 div 拖到另一个容器 div 中。内部 div 到达容器 div 的边界时应该停止。我设法完成了大部分工作。但问题是,如果我缓慢而小心地拖动内部 div,它会停在它应该位于边缘的位置,但是如果我更快地拖动它,它有时会溢出边缘或在边缘之前停止。这里有什么问题?我应该怎么做才能解决这个问题?

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 的位置时运行。

最佳答案

这是我的解决方案,我以前编写过视频游戏,您经常遇到这个问题。

您正在检查它是否会熄灭,但如果它熄灭则什么也不做!如果它到外面,你必须将它设置到边缘。

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();

编辑:不确定为什么它在右侧和底部缺少一个像素,您必须在这方面进行一些调查。尽管您使用了 offsetWidth,但它似乎没有考虑到边框。祝你好运!

关于javascript - 使javascript动画流畅?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41243987/

相关文章:

javascript - 如何在字符串中选择星号并设置其样式?

html - 谷歌地图 - 覆盖样式

css - 列在移动设备上显示不正确

javascript - 如何在我的 Rails 后端和浏览器的 Javascript 中为字符串生成哈希值?

javascript - scaleQuantile 函数没有输出我所期望的

javascript - EmberJS : Has no method lastObject, 下一个对象

javascript - 如何使用 Onsen UI 操作 DOM

javascript - 如何文本对齐 javascript ALERT?

javascript - mCustomScrollbar 预先添加新内容

javascript - 当前所选类中的目标类