Протестировано в Google Chrome 73 (официальная сборка) (64-разрядная версия).
Также протестировано в последних стабильных Mozilla, Opera и Safari.
Похоже, что это ошибка только Chrome. Надеюсь, что есть обходной путь, пока команда Chrome не исправит ошибку.
Демо
Я создал Codepen , чтобы показать проблему.
const div = document.querySelector('div');
const cssTransition = 2500;
const states = [
['INITIAL', 'translate(0)', cssTransition / 2],
['A', 'translate(0, 100px)', cssTransition + 500],
['B', 'translate(100px, 100px)', cssTransition / 2],
];
let cursor = 0;
const animate = () => {
cursor = (cursor + 1) % states.length;
const [name, value, delay] = states[cursor];
setTimeout(() => {
div.innerText = name;
div.style.transform = value;
animate();
}, delay);
};
animate();
div {
width: 100px;
height: 100px;
background: brown;
color: white;
font-size: 25px;
font-family: sans-serif;
text-align: center;
line-height: 100px;
margin: 50px auto;
transition: 2.5s ease;
}
<div>INITIAL</div>
Задача
Анимируйте элемент с помощью JavaScript, чтобы изменить его положение на экране, используя свойство преобразования CSS3.
Условия:
- Элемент имеет фиксированное время перехода (определено в файле CSS).
- В любой момент анимации JavaScript может установить новую позицию элемента, т. Е. Изменение произойдет до завершения существующей анимации.
- Новая позиция элемента заранее не известна => т.е. список классов CSS здесь не вариант.
Проблема в - переход не плавный, потому что новая анимация скачет с начальной позиции предыдущей анимации вместо плавного перехода с текущей позиции.
Фактическое поведение
Когда свойство CSS-преобразования элемента изменяется во время перехода (то есть до завершения текущей анимации), следующая анимация начинается с начального состояния предыдущей анимации.
- шаги 1-5 - первая анимация (переход между начальным и A-состояниями).
- шаги 6-10 - вторая анимация (переход между начальным и B-состояниями).
- шаг 3 - это место, где первая анимация была прервана из-за изменения свойства финального преобразования, то есть здесь начинается вторая анимация.
Как видите, анимация переходит в начальное состояние, которое является неправильным (нежелательным). Позиция на шаге 6 должна быть рядом с шагом 3.
Ожидаемое поведение
Изменение свойства CSS-преобразования должно сбрасывать внутренний таймер анимации на 0 (поэтому новая анимация будет длиться, как определено в свойстве перехода), но сохранять текущее состояние преобразования в качестве исходного состояния для следующей анимации.
- шаги 1-5 - первая анимация (переход между начальным и A-состояниями).
- шаги 6-10 - вторая анимация (переход между промежуточными состояниями «ПЕРВОНАЧАЛЬНО в А» и В).
- шаг 3 - это место, где первая анимация была прервана из-за изменения свойства финального преобразования, то есть здесь начинается вторая анимация.
Как видите, новая анимация начинается именно там, где и ожидается - с шага 3 и приятно перемещает элемент в новую позицию.
Спасибо за чтение. Ждем вашей помощи.