Как синхронизировать анимацию CSS через несколько элементов?
У меня есть два элемента на странице, которые я хотел бы анимировать с помощью CSS (в частности, -webkit-animation). Сама анимация просто отскакивает от элемента вверх и вниз. Один элемент всегда отображается и подпрыгивает, а другой не анимируется до наведения мыши (зависания).
Мой вопрос: возможно ли синхронизировать (оба элемента достигают своей вершины одновременно и т.д.) анимацию для обоих элементов независимо от того, когда запущена анимация 2-го элемента?
Здесь мой HTML:
<div id="bouncy01">Drip</div>
<div id="bouncy02">droP</div>
и мой CSS:
@-webkit-keyframes bounce {
0% {-webkit-transform: translateY(0px);}
25% {-webkit-transform: translateY(-2px);}
50% {-webkit-transform: translateY(-4px);}
75% {-webkit-transform: translateY(-2px);}
100% {-webkit-transform: translateY(0px);}
}
#bouncy01,
#bouncy02 {
margin:10px;
float: left;
background: #ff0000;
padding: 10px;
border: 1px solid #777;
}
#bouncy01 {
-webkit-animation:bounce 0.25s ease-in-out infinite alternate;
}
#bouncy02 {
background: #ffff00;
}
#bouncy02:hover {
-webkit-animation:bounce 0.25s ease-in-out infinite alternate;
}
и, наконец, рабочая демонстрация проблемы: http://jsfiddle.net/7ZLmq/2/
(чтобы увидеть проблему, наведите указатель мыши на желтый блок)
Ответы
Ответ 1
Я не думаю, что это возможно изначально, но вы действительно можете взломать аналогичные функции, используя отскок оболочки и некоторые изменения позиции
HTML:
<div id="bouncywrap">
<div id="bouncy01">Drip</div>
<div id="bouncy02">droP</div>
<div>
CSS
@-webkit-keyframes bounce {
0% { padding-top:1px;}
/* using padding as it does not affect position:relative of sublinks
* using 0 instead of 0 b/c of a box-model issue,
* on kids wiht margin, but parents without margin, just try out
*/
50% { padding-top:5px;} /*desired value +1*/
100% { padding-top:1px;}
}
#bouncy01,
#bouncy02 {
margin:10px;
background: #ff0000;
padding: 10px;
border: 1px solid #777;
width:30px;
position:absolute;
}
#bouncywrap {
-webkit-animation:bounce 0.125s ease-in-out infinite;
position:relative;
width:140px;
height:50px;
/* background:grey; /*debug*/
}
#bouncy02 {
background: #ffff00;
left:60px;
top:2px; /*half of desired value, just a fix for the optic*/
}
#bouncy02:hover {
position:relative; /*here happens the magic*/
top:0px;
}
demo http://jsfiddle.net/A92pU/1/
Ответ 2
Похоже, вы можете просто складывать два из желтых и переключаться на видимость: наведите указатель мыши на родительский элемент.
Вам нужно, чтобы анимация всегда работала, иначе вы столкнетесь с проблемой синхронизации, которую у вас есть.
Я немного изменил ваш код, чтобы получить this.
Ответ 3
Вы можете использовать setInterval
для поддержания состояния анимации первой анимации и дать другой анимации отрицательную задержку для поиска соответствующего ключевого кадра при переходе мыши.
В разделе "Манипулирование CSS-анимациями" читайте информацию о состоянии сохранения состояния здесь; читайте об отрицательной задержке, чтобы искать здесь.
Ответ 4
при наведении мыши:
- удалить классы анимации из обоих элементов
- используйте
requestAnimationFrame(() => { ... add here "bounce" class to both elements })
Должен синхронизироваться красиво.
Ответ 5
Я искал альтернативное решение, предложенное здесь, потому что:
- Я анимирую цвет фона, который не может использовать магию позиционирования в принятом ответе.
- Я хотел избежать вычислений для очень простой анимации в моем приложении.
После дальнейших исследований я обнаружил этот модуль от bealearts.
Он предоставляет очень аккуратный API, который позволяет синхронизировать анимацию по всему приложению, ссылаясь на его имя:
import sync from 'css-animation-sync';
sync('spinner');
Поскольку это показалось слишком хорошим, чтобы быть правдой, я протестировал библиотеку (которая представляет собой один короткий файл) в этой скрипке и рад сообщить, что она работает (наведите на третье изображение и посмотрите что я быстро синхронизируюсь со вторым изображением анимации) :).
Предоставлено: я использовал анимацию из этой скрипки Симурая в качестве основы для моей скрипки.
Если кто-то хочет воспроизвести механизм, лежащий в основе этой синхронизации, код открыт, но по сути он использует прослушиватели событий для самой анимации в качестве точек синхронизации:
window.addEventListener('animationstart', animationStart, true);
window.addEventListener('animationiteration', animationIteration, true);
Надеюсь, что это поможет следующему человеку, ищущему решение этой проблемы.