css动画如何使用“反向”进行悬停和退出事件?

GWo*_*ing 2 html css css-animations

鉴于此代码(http://jsfiddle.net/bzf1mkx5/

.intern {
    -webkit-animation: in 1s 1 reverse forwards;
}

.intern:hover {
    -webkit-animation: in 1s 1 normal forwards;
}

@-webkit-keyframes in {
    from   { -webkit-transform: scale(1); }
    to { -webkit-transform: scale(1.2);}
}
Run Code Online (Sandbox Code Playgroud)
<div style = "width : 100px; height : 100px; background-color : red" class ="intern"></div>
Run Code Online (Sandbox Code Playgroud)

为什么没有动画?错误在哪里?

编辑:通过使用两个独立的动画,它确实可以工作,但是拥有反向属性 有什么意义呢?

.intern {
    -webkit-animation: in2 1s 1 reverse forwards;
}

.intern:hover {
    -webkit-animation: in 1s 1 normal forwards;
}

@-webkit-keyframes in {
    from   { -webkit-transform: scale(1); }
    to { -webkit-transform: scale(1.2);}
}
@-webkit-keyframes in2 {
    from   { -webkit-transform: scale(1); }
    to { -webkit-transform: scale(1.2);}
}
Run Code Online (Sandbox Code Playgroud)
<div style = "width : 100px; height : 100px; background-color : red" class ="intern"></div>
Run Code Online (Sandbox Code Playgroud)

编辑2: 如果我使用更高的时间,我应该看到动画,即使我会看到从一种状态跳转到另一种状态的不良效果

.intern {
    -webkit-animation: in 20s 1 reverse forwards;
}

.intern:hover {
    -webkit-animation: in 20s 1 normal forwards;
}

@-webkit-keyframes in {
    from   { -webkit-transform: scale(1); }
    to { -webkit-transform: scale(4);}
}
Run Code Online (Sandbox Code Playgroud)
<div style = "width : 50px; height : 50px; background-color : red" class ="intern"></div>
Run Code Online (Sandbox Code Playgroud)

Tem*_*fif 6

我们先来了解一下什么reverse意思

动画每个周期都会向后播放。换句话说,每次动画循环时,动画都会重置到结束状态并重新开始。动画步骤向后执行,计时功能也相反。例如,缓入计时功能变为缓出。参考

我们举一个基本的例子来理解:

.box {
  width:50px;
  height:50px;
  margin:5px;
  background:red;
  position:relative;
}
.normal {
  animation: move normal  2s linear forwards;
}
.reverse {
  animation: move reverse 2s linear forwards;
}

@keyframes move{
  from {
    left:0;
  }
  to {
    left:300px;
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="box normal">

</div>

<div class="box reverse">

</div>
Run Code Online (Sandbox Code Playgroud)

我们有一个动画,第一个元素向前运行,而第二个元素向后运行。从技术上讲,这就像我们反转fromtoreverse有助于避免在相反方向定义新动画。我们定义了从左到右的动画,通过反向我们有从右到左的动画。到目前为止,这都是微不足道的。

现在,如果您运行由其名称定义的任何类型的动画,并且在修改该动画的属性的过程中,您将更改整个动画的行为,并且我们根据新动画再次计算当前状态的值。

例子:

.box {
  width:50px;
  height:30px;
  margin:5px;
  background:red;
  position:relative;
}
.normal,
.special{
  animation: move normal  20s linear forwards;
  background:blue;
}
.reverse,
div:hover .special{
  animation: move reverse 20s linear forwards;
  background:green;
}

@keyframes move{
  from {
    left:0;
  }
  to {
    left:300px;
  }
}

p {
 margin:0;
}
Run Code Online (Sandbox Code Playgroud)
<p>Reference</p>
<div class="box normal"></div>

<div class="box reverse"></div>
<p>Hover the element</p>
<div>
   <div class="box special"></div> 
</div>
Run Code Online (Sandbox Code Playgroud)

我们有 3 个元素同时使用相同的动画,因此它们都具有相同的进度。第三个动画与第一个动画相同,悬停时它与第二个动画相同。窍门就在这里!悬停时,您不会考虑元素的实际位置,而只是向另一个方向移动,但您将考虑 定义的新动画,reverse并考虑动画的实际进度来计算 left 的值。

如果该元素5s在正常状态下位于动画的atleft:100px位置,则在相反状态下我们将看到该元素left:200px,因此如果您将鼠标悬停在 处,您将在和 之间5s切换。你不会考虑并搬回100px200pxleft:100px0px

现在很清楚,如果动画结束,您只需在第一个状态和最后一个状态之间切换即可。您不会再次触发新的动画,因为我们正在处理相同的动画,并且我们只是更改了一个设置(方向)

.box {
  width:50px;
  height:30px;
  margin:5px;
  background:red;
  position:relative;
}
.normal,
.special{
  animation: move normal  1s linear forwards;
  background:blue;
}
.reverse,
div:hover .special{
  animation: move reverse 1s linear forwards;
  background:green;
}

@keyframes move{
  from {
    left:0;
  }
  to {
    left:300px;
  }
}

p {
 margin:0;
}
Run Code Online (Sandbox Code Playgroud)
<p>Reference</p>
<div class="box normal"></div>

<div class="box reverse"></div>
<p>Hover the element</p>
<div>
   <div class="box special"></div> 
</div>
Run Code Online (Sandbox Code Playgroud)


如果您更改任何其他属性,也会发生相同的逻辑。您不会看到直观的结果,因为您需要想象新动画将如何,以便确定当前状态将如何。

例如,如果我们更改计时功能

.box {
  width:50px;
  height:30px;
  margin:5px;
  background:red;
  position:relative;
}
.normal,
.special{
  animation: move  20s linear forwards;
  background:blue;
}
.reverse,
div:hover .special{
  animation: move 20s ease forwards;
  background:green;
}

@keyframes move{
  from {
    left:0;
  }
  to {
    left:300px;
  }
}

p {
 margin:0;
}
Run Code Online (Sandbox Code Playgroud)
<p>Reference</p>
<div class="box normal"></div>

<div class="box reverse"></div>
<p>Hover the element</p>
<div>
   <div class="box special"></div> 
</div>
Run Code Online (Sandbox Code Playgroud)

例如,如果我们更改持续时间:

.box {
  width:50px;
  height:30px;
  margin:5px;
  background:red;
  position:relative;
}
.normal,
.special{
  animation: move  20s linear forwards;
  background:blue;
}
.reverse,
div:hover .special{
  animation: move 30s linear forwards;
  background:green;
}

@keyframes move{
  from {
    left:0;
  }
  to {
    left:300px;
  }
}

p {
 margin:0;
}
Run Code Online (Sandbox Code Playgroud)
<p>Reference</p>
<div class="box normal"></div>

<div class="box reverse"></div>
<p>Hover the element</p>
<div>
   <div class="box special"></div> 
</div>
Run Code Online (Sandbox Code Playgroud)


您可以通过以下方式实现您正在寻找的内容transition,因为转换只会关心当前值,并且会在您需要时转换到新值(例如,在悬停时)

.intern {
  width: 100px;
  height: 100px;
  margin:50px;
  background-color: red;
  transition:10s all;
  
}

.intern:hover {
  transform:scale(4);
}
Run Code Online (Sandbox Code Playgroud)
<div style="" class="intern"></div>
Run Code Online (Sandbox Code Playgroud)

当您悬停时,您将启动一个持续的缩放动画10s,但如果您在返回到初始状态之前取消悬停。你不能用动画来做到这一点。动画需要完全运行,或者在中间突然取消它并返回到初始状态

即使您定义了两个动画,当运行的动画尚未结束时,您也不会总是在悬停时获得所需的结果。您将取消它并运行新的。

.intern {
  width: 100px;
  height: 100px;
  margin:50px;
  background-color: red;
  animation:in 5s linear forwards; 
}

.intern:hover {
  animation:out 5s linear forwards;
}

@keyframes in {
  from {
    transform:scale(1);
  }
  to {
    transform:scale(4);
  }
}
@keyframes out {
  from {
    transform:scale(4);
  }
  to {
    transform:scale(1);
  }
}
Run Code Online (Sandbox Code Playgroud)
<div style="" class="intern"></div>
Run Code Online (Sandbox Code Playgroud)

尝试快速悬停/取消悬停,您会看到不好的效果。只有将鼠标悬停在每个动画的末尾,您才会获得完美的结果。