即使您在中途停止悬停,如何强制动画完成然后反向开始悬停?

时间:2021-01-25 13:15:09

标签: javascript html jquery css

我发现了这个代码笔,我觉得它非常有趣,我正在尝试在悬停时开始,然后保持打开状态直到您停止悬停,然后它会反转并关闭。我的问题是,首先,它要么在悬停时做动画,然后在悬停时直接跳到开始。此外,当在动画中途离开悬停时,它只会跳回开始。我试过“.box:hover 和 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>

2 个答案:

答案 0 :(得分:0)

阅读 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>

最初,动画是暂停的。当身体悬停但框没有悬停时,动画会暂停。当框悬停时,动画运行。我认为这正是您所需要的。

答案 1 :(得分:0)

我猜你的问题的答案是这样的

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)"  
    />