Проблема с setInterval и animation

102
23 апреля 2021, 17:20

Необходимо, чтобы синий(С) квадратик перемещался за зеленым(З) по оси Х. Но если во время движения С квдарата переместить З квадрат, начинается ерунда с С квадратом. Подскажите как выйти из ситуации. Codepen.

var blue = document.getElementById('blue'); 
var green = document.getElementById('green'); 
 
 
// MOVE green 
green.addEventListener("mousedown", MouseDown, false); 
 
function MouseDown(EO) { 
    EO = EO || window.event; 
    green.style.cursor = "all-scroll"; 
    green.style.zIndex++; 
    let greenPos = getElementPos(EO, green); 
 
    document.addEventListener("mousemove", MouseMove, false); 
 
    function MouseMove(EO) { 
        EO = EO || window.event; 
        green.style.top = EO.clientY - greenPos.top + 'px'; 
        green.style.left = EO.clientX - greenPos.left + 'px'; 
        EO.preventDefault(); 
    } 
 
    document.addEventListener("mouseup", MouseUp, false); 
 
    function MouseUp(EO) { 
        document.removeEventListener("mousemove", MouseMove, false); 
        green.style.cursor = "default"; 
        EO = EO || window.event; 
    } 
    green.addEventListener("mouseup", moveblue, false); 
} 
 
// Move blue at diagonals (quick path) 
 
function moveblue(EO) { 
    let Xposblue = (blue.getBoundingClientRect()).left; 
    let Xposgreen = (green.getBoundingClientRect()).left; 
 
 
    var animationX = setInterval(frameX, 0); 
 
    // X-axis 
    if (Xposblue > Xposgreen) { 
        var lengthX = (Xposblue - Xposgreen) / 500; 
    } 
    if (Xposblue < Xposgreen) { 
        var lengthX = (Xposgreen - Xposblue) / 500; 
    } 
 
 
    function frameX() { 
        if (Xposgreen == Math.ceil(Xposblue) || Xposgreen ==  Xposblue + 100 || Xposgreen == Xposblue - 100) { 
            clearInterval(animationX); 
        } else if (Xposgreen > Xposblue) { 
            Math.ceil(Xposblue += lengthX); 
            blue.style.left = Xposblue + 'px'; 
        } else if (Xposgreen < Xposblue) { 
            Math.ceil(Xposblue -= lengthX); 
            blue.style.left = Xposblue + 'px'; 
        } 
    }; 
  
 
} 
 
 
 
// Position cursor over object 
function getElementPos(EO, elem) { 
    var posgreenUnderWindow = elem.getBoundingClientRect(); 
    return { 
        left: Math.floor(EO.clientX - posgreenUnderWindow.left), 
        top: Math.floor(EO.clientY - posgreenUnderWindow.top) 
    }; 
}
body { 
  width:100%;  
} 
 
#green, 
#blue { 
    width: 150px; 
    height: 150px; 
    border: 1px solid #000; 
    display: block; 
    position: absolute; 
} 
 
#green { 
    background: green; 
    left: 0; 
} 
 
#blue { 
    background: blue; 
    right: 0; 
}
<div id="green"></div> 
    <div id="blue"></div>

Answer 1

Сделал через setInterval, сколько там Вы генерируете таймаутов я не смог понять, но их точно больше чем надо...

var blue = document.getElementById('blue'); 
var green = document.getElementById('green'); 
 
setInterval(function() { 
  
  let bx = blue.getBoundingClientRect().x 
  let dx = bx - green.getBoundingClientRect().x; 
  let adx = Math.abs(dx); 
 
  if (adx > 1) 
    blue.style.left = bx-Math.sign(dx)*Math.max(adx/44, 1) + 'px' 
 
}, 10) 
 
 
// MOVE green 
green.addEventListener("mousedown", MouseDown, false); 
 
function MouseDown(EO) { 
    EO = EO || window.event; 
    green.style.cursor = "all-scroll"; 
    green.style.zIndex++; 
    let greenPos = getElementPos(EO, green); 
 
    document.addEventListener("mousemove", MouseMove, false); 
 
    function MouseMove(EO) { 
        EO = EO || window.event; 
        green.style.top = EO.clientY - greenPos.top + 'px'; 
        green.style.left = EO.clientX - greenPos.left + 'px'; 
        EO.preventDefault(); 
    } 
 
    document.addEventListener("mouseup", MouseUp, false); 
 
    function MouseUp(EO) { 
        document.removeEventListener("mousemove", MouseMove, false); 
        green.style.cursor = "default"; 
        EO = EO || window.event; 
    } 
} 
 
function getElementPos(EO, elem) { 
    var posgreenUnderWindow = elem.getBoundingClientRect(); 
    return { 
        left: Math.floor(EO.clientX - posgreenUnderWindow.left), 
        top: Math.floor(EO.clientY - posgreenUnderWindow.top) 
    }; 
}
#green, #blue { 
    width: 50px; 
    height: 50px; 
    display: block; 
    position: absolute; 
} 
 
#green { 
    background: green; 
    left: 0; 
} 
 
#blue { 
    background: blue; 
    right: 0; 
}
<div id="blue"></div> 
<div id="green"></div>

READ ALSO
Как в AJAX сделать GET запрос, чтобы url не менялся [закрыт]

Как в AJAX сделать GET запрос, чтобы url не менялся [закрыт]

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение

115
Правильная реализация меню

Правильная реализация меню

Подскажите, как правильно реализовать два "меню"

108
Компиляция Less в css в Brackets и VSCode

Компиляция Less в css в Brackets и VSCode

Я только начинаю работать с препроцессором LessНо компилировать его через Koola не хочется

87
Определить где вызвана SASS функция

Определить где вызвана SASS функция

Есть sass функция, возможно ли внутри нее проверить где она вызвана/во что обернута?

74