即使您在中途停止悬停,如何强制动画完成然后反转以开始悬停?
Posted
技术标签:
【中文标题】即使您在中途停止悬停,如何强制动画完成然后反转以开始悬停?【英文标题】:How to force an animation to finish and then reverse to start on hover, even when you stop hovering mid way through? 【发布时间】:2021-04-29 07:13:52 【问题描述】:我发现了这个我觉得非常有趣的代码笔,并试图在悬停时启动,然后保持打开状态,直到您停止悬停,然后它会反转并关闭。我的问题是,首先,它要么在悬停时做动画,然后在悬停时直接跳到开始。同样,当在动画中途离开悬停时,它只是跳回到起点。我试过“.box:hover and box:hover:after”但没有成功。任何帮助将不胜感激!
The Pen 免责声明,这不是我的笔,我发现它并认为它很酷。 感谢the creator
*
margin:0;
padding:0;
.container
background: #f0f0f0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
.box
border-radius: 20px;
width: 60px;
height: 60px;
background: #f0f0f0;
box-shadow: 0 0 0 #cccccc,
0 0 0 #ffffff,
10px 10px 10px #cccccc inset,
-10px -10px 10px #ffffff inset;
animation: anime 3s cubic-bezier(0.16, 1, 0.3, 1) 1s infinite alternate;
/* animation-fill-mode: forwards; */
@keyframes anime
0%
width: 60px;
height: 60px;
background: #f0f0f0;
box-shadow: 0 0 0 #cccccc,
0 0 0 #ffffff,
10px 10px 10px #cccccc inset,
-10px -10px 10px #ffffff inset;
25%
width: 60px;
height: 60px;
background: #f8f8f8;
box-shadow: 10px 10px 10px #cccccc,
10px 10px 10px #ffffff,
0 0 0 #cccccc inset,
0 0 0 #ffffff inset;
50%
width: 60px;
height: 240px;
background: #f8f8f8;
box-shadow: 10px 10px 10px #cccccc,
10px 10px 10px #ffffff,
0 0 0 #cccccc inset,
0 0 0 #ffffff inset;
100%
width: 480px;
height: 240px;
background: #fafafa;
box-shadow: 40px 40px 40px #cccccc,
0 0 0 #ffffff,
0 0 0 #cccccc inset,
2px 2px 2px #ffffff inset;
<body>
<div class="container">
<div class="box"></div>
</div>
</body>
【问题讨论】:
【参考方案1】:我猜你的问题的答案应该是这样的
function fn(el, isEnter)
el.className = "";
requestAnimationFrame(() =>
requestAnimationFrame(() =>
el.className = isEnter? "in": "out";
);
);
.in
animation: k 1s forwards;
.out
animation: k 1s forwards;
animation-direction: reverse;
@keyframes k
from transform: rotate(0deg);
to transform: rotate(360deg);
<div style="width:100px; height:100px; background-color:red"
onmouseenter="fn(this, true)"
onmouseleave="fn(this, false)"
/>
【讨论】:
【参考方案2】:阅读animation-play-state
并查看hidden snippet。
如果你把这两者结合起来,你就会得到你所需要的:
*
margin:0;
padding:0;
.container
background: #f0f0f0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
.box
border-radius: 20px;
width: 60px;
height: 60px;
background: #f0f0f0;
box-shadow: 0 0 0 #cccccc,
0 0 0 #ffffff,
10px 10px 10px #cccccc inset,
-10px -10px 10px #ffffff inset;
animation: anime 3s cubic-bezier(0.16, 1, 0.3, 1) 1s infinite alternate;
animation-play-state: paused; /* added */
/* animation-fill-mode: forwards; */
body:hover .container .box
animation-play-state: paused; /* added */
body .container .box:hover
animation-play-state: running; /* added */
@keyframes anime
0%
width: 60px;
height: 60px;
background: #f0f0f0;
box-shadow: 0 0 0 #cccccc,
0 0 0 #ffffff,
10px 10px 10px #cccccc inset,
-10px -10px 10px #ffffff inset;
25%
width: 60px;
height: 60px;
background: #f8f8f8;
box-shadow: 10px 10px 10px #cccccc,
10px 10px 10px #ffffff,
0 0 0 #cccccc inset,
0 0 0 #ffffff inset;
50%
width: 60px;
height: 240px;
background: #f8f8f8;
box-shadow: 10px 10px 10px #cccccc,
10px 10px 10px #ffffff,
0 0 0 #cccccc inset,
0 0 0 #ffffff inset;
100%
width: 480px;
height: 240px;
background: #fafafa;
box-shadow: 40px 40px 40px #cccccc,
0 0 0 #ffffff,
0 0 0 #cccccc inset,
2px 2px 2px #ffffff inset;
<body>
<div class="container">
<div class="box"></div>
</div>
</body>
最初,动画是暂停的。当 body 悬停但 box 没有悬停时,动画会暂停。当框悬停时,动画运行。我想这正是你所需要的。
【讨论】:
嗯,是的,也不是。我希望它在悬停时完成动画,但如果我停止悬停,它会将动画的反向平稳地返回到开始。以上是关于即使您在中途停止悬停,如何强制动画完成然后反转以开始悬停?的主要内容,如果未能解决你的问题,请参考以下文章