Как запретить проигрывать вторую анимацию, пока не закончилась первая и наоборот? JS
При нажатии на кнопку выезжает div,
если нажать на эту кнопку два или больше раз
div начинает дергаться вправо и влево:
'use strict';
let button = document.querySelector('button'),
anBox = document.querySelector('#anima');
function animationl() {
let pos = 100,
id = setInterval(frame, 10);
function frame() {
if (pos == 0) {
clearInterval(id);
} else {
pos--;
anBox.style.right = pos + '%';
}
}
}
function animationr() {
let pos = 0,
id = setInterval(frame, 10);
function frame() {
if (pos == 100) {
clearInterval(id);
} else {
pos++;
anBox.style.right = pos + '%';
}
}
}
button.addEventListener('click', function l() {
animationl();
button.removeEventListener('click', l);
button.addEventListener('click', function r() {
animationr();
button.removeEventListener('click', r);
button.addEventListener('click', l);
});
});
#anima {
position: absolute;
background-color: rgb(0, 0, 0);
width: 100%;
height: 30%;
right: 100%;
}
.buy-btn {
position: absolute;
left: 15%;
top: 50%;
width: 65%;
height: 10%;
cursor: pointer;
background-color: rgb(131, 60, 60);
border: 1px solid black;
font-size: 15px;
font-weight: bold;
color: blanchedalmond;
transition: all .5s;
}
.buy-btn:hover {
background-color: rgb(218, 112, 112);
}
.buy-btn:active {
background-color: white;
}
<div id="anima"></div>
<button class="buy-btn">BUY</button>
Не могу найти способ запретить проигрывать сразу две анимации.
Ответы (2 шт):
Если с минимальным изменением кода, так:
'use strict';
let button = document.querySelector('button'),
anBox = document.querySelector('#anima');
let animating = false; // <--
function animationl() {
animating = true; // <--
let pos = 100, id = setInterval(frame, 10);
function frame() {
if (pos == 0) {
clearInterval(id);
animating = false; // <--
} else {
pos--;
anBox.style.right = pos + '%';
}
}
}
function animationr() {
animating = true; // <--
let pos = 0, id = setInterval(frame, 10);
function frame() {
if (pos == 100) {
clearInterval(id);
animating = false; // <--
} else {
pos++;
anBox.style.right = pos + '%';
}
}
}
let curr_fn = animationr;
button.addEventListener('click', function() {
if (animating) return; // <-- return
curr_fn = (curr_fn == animationl) ? animationr : animationl;
// Переключает текущую функцию, кторую следуют запустить.
curr_fn();
});
#anima {
position: absolute;
background-color: rgb(0, 0, 0);
width: 100%;
height: 30%;
right: 100%;
}
.buy-btn {
position: absolute;
left: 15%;
top: 50%;
width: 65%;
height: 10%;
cursor: pointer;
background-color: rgb(131, 60, 60);
border: 1px solid black;
font-size: 15px;
font-weight: bold;
color: blanchedalmond;
transition: all .5s;
}
.buy-btn:hover {
background-color: rgb(218, 112, 112);
}
.buy-btn:active {
background-color: white;
}
<div id="anima"></div>
<button class="buy-btn">BUY</button>
Завести внешнюю переменную let animating = false; вначале каждой анимации сделать её true и при клике, if (animating) return;
Но вообще-то можно переложить логику анимации на CSS transition: 0.5s linear; а при клике только переключать необходимое финальное значение:
'use strict';
let button = document.querySelector('button');
let box = document.querySelector('#anima');
let value = 100;
button.addEventListener("click", function() {
value = (value === 0) ? 100 : 0;
box.style.right = value + "%";
});
#anima {
position: absolute;
background-color: rgb(0, 0, 0);
width: 100%;
height: 30%;
right: 100%;
transition: 0.5s linear;
}
.buy-btn {
position: absolute;
left: 15%;
top: 50%;
width: 65%;
height: 10%;
cursor: pointer;
background-color: rgb(131, 60, 60);
border: 1px solid black;
font-size: 15px;
font-weight: bold;
color: blanchedalmond;
transition: all .5s;
}
.buy-btn:hover {
background-color: rgb(218, 112, 112);
}
.buy-btn:active {
background-color: white;
}
<div id="anima"></div>
<button class="buy-btn">BUY</button>
Чтобы анимация была плавной лучше делать ее с помощью window.requestAnimationFrame. В таком случае браузер оптимизирует перерисовку контента, обновляя элемент не через определенные интервалы времени (как в случае с setInterval), а каждый раз во время очередного обновления кадра, что делает анимацию плавной, с учетом частоты обновления кадров монитора. Это новый и современный подход к созданию анимаций.
'use strict';
//******************************************************
function animate(duration, callbackStart, callbackStep, callbackEnd) {
var starttime = null;
function step(timestamp) {
if (!starttime) {
starttime = timestamp;
}
var runtime = timestamp - starttime,
progress = runtime / duration;
callbackStep(Math.max(0, Math.min(progress, 1)));
if (runtime < duration) {
window.requestAnimationFrame(step);
} else {
callbackEnd();
}
}
callbackStart();
window.requestAnimationFrame(step);
}
//******************************************************
var button = document.querySelector('button'),
anBox = document.querySelector('#anima');
var dir = false, // направление анимации (true = прямо, false = обратно)
anima = false; // активность анимации (true = запущена, false = отключена)
button.addEventListener('click', function() {
// Проверяем не запущена ли уже анимация
if (!anima) {
// Меняем направление
dir = !dir;
// Анимация на 1000 милисекунд
animate(1000, function start() {
// Перед стартом анимации
anima = true;
anBox.style.right = dir ? '100%' : '0%';
}, function step(x) {
// Во время анимации х меняется от 0 до 1
anBox.style.right = 100 * (dir ? 1 - x : x) + '%';
}, function end() {
// После конца анимации
anima = false;
anBox.style.right = dir ? '0%' : '100%';
});
}
});
#anima {
position: absolute;
background-color: rgb(0, 0, 0);
width: 100%;
height: 30%;
right: 100%;
}
.buy-btn {
position: absolute;
left: 15%;
top: 50%;
width: 65%;
height: 10%;
cursor: pointer;
background-color: rgb(131, 60, 60);
border: 1px solid black;
font-size: 15px;
font-weight: bold;
color: blanchedalmond;
transition: all .5s;
}
.buy-btn:hover {
background-color: rgb(218, 112, 112);
}
.buy-btn:active {
background-color: white;
}
<div id="anima"></div>
<button class="buy-btn">BUY</button>