#css #ios #animation #safari #css-animations
Вопрос:
Я создал анимацию для перемещения элемента в поле зрения, когда пользователь где-то нажимает. Элемент оформлен так, чтобы быть за кадром. Когда анимация запущена, она перемещает элемент на экране и используется animation-fill-mode: forwards
для сохранения положения элемента после окончания анимации. При втором щелчке элемент снова отправляется за кадр с другой анимацией.
Проблема в iOS (протестирована на 14.6), когда пользователь поворачивает устройство — по какой-то причине конечные значения не пересчитываются, поэтому элемент оказывается неправильно расположенным на экране. Вы можете видеть это явно, когда запускается анимация «отправить за кадр» — элемент переходит в предполагаемую начальную позицию анимации, которая должна была совпадать с конечной точкой предыдущей анимации. При циклическом воспроизведении анимации скачка нет
На следующем изображении это показано в действии; после поворота устройства обратите внимание, что положение красной рамки находится в неправильном положении: при переходе от портретной к альбомной ориентации коробка находится слишком далеко вправо, при переходе от альбомной к портретной ориентации коробка находится слишком далеко влево.
Проблема не возникает на Android с Chrome — окно перемещено правильно.
Ниже приведен код, используемый для создания изображения выше.
Это просто ошибка в iOS, или я что-то делаю не так?
Обновление: Похоже, эта проблема на самом деле не ограничивается мобильными устройствами: на рабочем столе Safari при изменении размера окна браузера возникает та же проблема — вместо того, чтобы изменять положение элемента из-за vw
единиц измерения, он каким-то образом сдвигает элемент. Chrome и Firefox ведут себя так, как ожидалось.
<html>
<head>
<title>animation test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
label {
font-size: 24px;
}
.elem {
position: fixed;
bottom: -40vw;
left: -40vw;
transform: rotate3d(0, 0, 1, 45deg);
transform-origin: 50% 100%;
width: 30vw;
height: 43vw;
background-color: red;
}
.anim--in {
animation: anim-in 1s;
animation-fill-mode: forwards;
}
.anim--out {
animation: anim-out 1s;
animation-fill-mode: backwards;
}
@keyframes anim-in {
0% {
bottom: -40vw;
left: -40vw;
}
100% {
bottom: -2vw;
left: -15vw;
}
}
@keyframes anim-out {
0% {
bottom: -2vw;
left: -15vw;
}
100% {
bottom: -40vw;
left: -40vw;
}
}
</style>
</head>
<body>
<label><input id="trigger" type="checkbox">Tap me to animate</label>
<div class="elem"></div>
<script>
const trigger = document.getElementById("trigger");
trigger.addEventListener("click", () => {
const elem = document.getElementsByClassName("elem")[0];
if (elem.classList.contains("anim--in")) {
elem.classList.remove("anim--in");
elem.classList.add("anim--out");
} else {
elem.classList.remove("anim--out");
elem.classList.add("anim--in");
}
console.log("click!");
});
</script>
</body>
</html>