我在页面上有两个元素,我想通过CSS制作动画(特别是-webkit-animation)。动画本身只是上下弹跳一个元素。一个元素总是显示和弹跳,另一个元素在鼠标悬停(悬停)之前不会动画。
我的问题是:无论第二个元素的动画何时开始,是否可以同步(两个元素同时达到顶点等)动画,而不管第二个元素的动画何时开始?
这是我的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/
(看到问题,鼠标悬停在黄色块上)
答案 0 :(得分:21)
我不认为它本身可能,但你可以通过使用弹跳包装和一些位置改变来实际破解类似的功能
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;
}
答案 1 :(得分:2)
答案 2 :(得分:2)
您可以使用setInterval
来维护第一个动画的动画状态,并为其他动画提供负延迟,以便在鼠标悬停时寻找匹配的关键帧。
在“操纵CSS动画”部分阅读有关state-keeping-interval-thing here的内容;了解寻求here的负延迟。
答案 3 :(得分:1)
鼠标悬停:
requestAnimationFrame(() => { ... add here "bounce" class to both elements })
应该很好地同步。
答案 4 :(得分:1)
计算并添加延迟,然后再添加类:
class Engine {
// Constructor, size defaults to 1
constructor(size = 1) {
// Sets size to size
this.size = size;
}
// Method
start() {
for (let i = 0; i < this.size, i++) {
alert('Brrr');
}
}
}
class Car {
// Constructor
constructor(name) {
// Sets engine to a new engine
this.engine = new Engine();
// Sets name to name
this.name = name;
}
// Method
introduceTo(name) {
alert(`Hey ${name}, here is my car ${this.name}.`);
}
}
let myCar = new Car('Ferrari');
myCar.engine = new Engine(5);
myCar.introduceTo('bro');
myCar.engine.start();
答案 5 :(得分:1)
这是我在同步不同元素和 pseudo-elements 的动画方面的小探索,多亏了上述想法,解决方案变得非常简单。我希望这个小代码对某人有所帮助。
window.addEventListener('animationstart', e =>
e.animationName == 'rgb' && e.target.getAnimations({subtree: true}).forEach(e => e.startTime = 0), true)
答案 6 :(得分:0)
我正在寻找此处提出的替代方案,因为:
经过进一步研究,我发现this module是bealearts的人。
它公开了一个非常简洁的API,使您可以通过引用动画的名称在整个应用中使动画保持同步:
import sync from 'css-animation-sync';
sync('spinner');
由于这似乎有点难以置信,所以我在这个小提琴中测试了库(是一个短文件),很高兴报告it works(将鼠标悬停在第三张图片上,我很快同步到第二张图片的动画):)。
信用:我使用Simurai的this fiddle中的动画作为我的小提琴的基础。
如果有人想复制此同步背后的机制,则代码是开放的,但从本质上讲,它使用动画本身的事件侦听器作为同步点:
window.addEventListener('animationstart', animationStart, true);
window.addEventListener('animationiteration', animationIteration, true);
希望这可以帮助下一个寻找解决此问题的人。
答案 7 :(得分:0)
您可以在设置交替状态的根元素上设置一个类,然后使用计时器替换该类
CSS
.alt .bouncy {
padding-top:5px !important;
}
.bouncy {
padding-top: 1px;
transition: padding-top ease 500ms;
}
HTML
<div class="container">
<div class="bouncy">Drip</div>
<div class="bouncy">droP</div>
<div>
JavaScript
$(function () {
setInterval(() => $(".container").toggleClass("alt"), 1000)
})
通过这种方式,过渡和计时器可以执行css动画的工作,但由单个主开关(容器)控制。