Как сделать так, чтобы элементы плавно перетаскивались мышью, если их положение задано в процентах?

Я делаю возможность перетаскивания элементов на моей странице. Пользователь должен перетащить любой элемент с заданной позицией % или px. Перетаскивание элементов с px позициями работает хорошо, но перетаскивание элементов с % позициями происходит слишком быстро, и элемент убегает от мыши.

Каким образом я могу это исправить? Я думаю, что мне, вероятно, нужно сделать некоторые вычисления, поэтому элемент не будет двигаться, пока мышь не пробежит некоторое расстояние, но я не понимаю, какие именно вычисления я должен сделать. Вероятно, это должно зависеть от того, сколько pixels в 1%.

<html style="height: 100%;">
<head>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
    <title>test export</title>
    <script type='text/javascript'>
        var curr_moving_elem;
        var last_x, last_y;

        function getIndexOfFirstNonDigitSymbolInString(str) {
            if (!str)
                return -1;

            var index = -1;

            for (var i = 0; i < str.length; i++)
                if (str[i] != '-' && (str[i] < '0' || str[i] > '9')) {
                    index = i;
                    break;
                }

            return index;
        }

        function getIntegerFromAnyHTMLValue(str_val) {
            int_val = 0;
            var first_non_digit = getIndexOfFirstNonDigitSymbolInString(str_val);

            if (first_non_digit < 0)
                return NaN;

            var digits_only = str_val.substring(0, first_non_digit);

            return Number(digits_only);
        }

        function getStrSuffixFromAnyHTMLValue(str_val, suffix) {
            suffix = "";
            var first_non_digit = getIndexOfFirstNonDigitSymbolInString(str_val);

            if (first_non_digit < 0)
                return "";

            return str_val.substring(first_non_digit);
        }

        function handleMouseDown(e) {
            if (e.button == 0) {
                var main_elem_under_mouse = getMainElemUnderMouseClickOrDownOrMoveOrUp(e);

                if (main_elem_under_mouse && (main_elem_under_mouse.style.position.toLowerCase() == "absolute" || main_elem_under_mouse.style.position.toLowerCase() == "relative" || main_elem_under_mouse.style.position.toLowerCase() == "fixed")) {
                    curr_moving_elem = main_elem_under_mouse;
                    last_x = e.x;
                    last_y = e.y;
                }
            }
        }

        function handleMouseMove(e) {
            if (curr_moving_elem && e.button == 0) {
                var curr_top = curr_moving_elem.style.top;
                var curr_left = curr_moving_elem.style.left;

                var int_top = getIntegerFromAnyHTMLValue(curr_top);
                var top_suffix = getStrSuffixFromAnyHTMLValue(curr_top);

                var int_left = getIntegerFromAnyHTMLValue(curr_left);
                var left_suffix = getStrSuffixFromAnyHTMLValue(curr_left);

                var new_top = (int_top + (e.y - last_y)) + top_suffix;
                curr_moving_elem.style.top = new_top;

                var new_left = (int_left + (e.x - last_x)) + left_suffix;
                curr_moving_elem.style.left = new_left;

                last_x = e.x;
                last_y = e.y;
            }
        }

        function handleMouseUp(e) {
            //if (e.button == 0)
            //{
            curr_moving_elem = null;
            last_x = null;
            last_y = null;
            //}
        }

        function getMainElemUnderMouseClickOrDownOrMoveOrUp(e) {
            var elem;
            var evt = e || window.event;

            if (!evt)
                return null;

            if (evt.target)
                elem = evt.target;
            else if (evt.srcElement)
                elem = evt.srcElement;

            if (elem && elem.nodeType == 3) // defeat Safari bug
                elem = elem.parentNode;

            if (elem)
                if (elem.getAttribute('data-mainElem'))
                    return elem;
                else {
                    var parent = elem.parentElement;

                    while (parent && !parent.getAttribute('data-mainElem'))
                        parent = parent.parentElement;

                    if (parent && parent.getAttribute('data-mainElem'))
                        return parent;
                }
        }
    </script>
</head>
<body style="height: 100%; margin: 0px;" onmousedown="handleMouseDown(event);" onmousemove="handleMouseMove(event);"
    onmouseup="handleMouseUp(event);">
    <div data-mainelem='true' id='Div_107' style="position: ABSOLUTE; height: 20%; width: 35%;
        top: 10px; left: 5px; background-color: #800000; background-position: left top;
        background-repeat: repeat;">
    </div>
    <div data-mainelem='true' id='Div_108' style="position: ABSOLUTE; height: 40%; width: 25%;
        top: 10%; left: 5%; background-color: #00FF00; background-position: left top;
        background-repeat: repeat;">
    </div>
</body>
</html>

person Kosmo零    schedule 20.05.2015    source источник


Ответы (1)


Я думаю, что ваша проблема здесь: e.x - last_x. Это вернет расстояние мыши в пикселях, но вам нужно в процентах. Что вам нужно, чтобы установить это в процентах от экрана. Что-то типа:

var percent_x = ((e.x - last.x)/window.innerWidth)*100

Но тогда вам придется различать проценты или пиксели.

person Julien Grégoire    schedule 20.05.2015
comment
Спасибо. Это уже нечто. Я попробую применить его и посмотреть, работает ли он. - person Kosmo零; 20.05.2015