Css 动画:转换不能反向工作

Css animation: transition not working in reverse direction

我正在尝试使用 HTML/CSS 制作此侧导航栏,我在其中添加了一些悬停动画。每当您将鼠标悬停在一个图标上时,它都会缩放到两倍,而导航栏中的其余项目则会分散。但我的问题不是因为我已经使用 javascript 和 CSS 实现了该动画。问题是动画在相反方向上运行不流畅。所以我试图添加短 CSS 动画来检查反向动画过渡是否正常工作,但事实并非如此。

这是我的 CSS 代码:

ul{
    list-style: none;
    }
    .navmenu{
      position: fixed;
      top: 50%;
      transform: translateY(-50%);
    }
    .navmenu ul{
      padding-left: 40px;
      position: relative;
    }
    .navmenu ul li {
      padding: 15px 0;
    }
    .navmenu ul li a{
      text-decoration: none;
      position: relative;
      font-size: 1.8rem;
      font-weight: 900;
    }
    .navmenu ul li a i{
      -webkit-transition: all 2s ease-in;
              transition: all 2s ease-in;
    }
    .navmenu ul li a:hover i{
      -webkit-animation: slide-out-top 0.2s ease-out both;
              animation: slide-out-top 0.2s ease-out both;
      color: orange;
    }

    @-webkit-keyframes slide-out-top {
      0% {
        -webkit-transform: scale(1) translateY(0);
                transform: scale(1) translateY(0);
      }
      100% {
        -webkit-transform: scale(0.8,0.8) translateY(-60px);
                transform: scale(0.8,0.8) translateY(-60px);
      }
    }
    @keyframes slide-out-top {
      0% {
        -webkit-transform: scale(1) translateY(0);
                transform: scale(1) translateY(0);
      }
      100% {
        -webkit-transform: scale(0.8,0.8) translateY(-60px);
                transform: scale(0.8,0.8) translateY(-60px);
      }
    }

这是它的 HTML 代码:

<nav class="navmenu">
    <ul>
      <li><a href="#home" class=""><i class="fas fa-home"></i><span>Home</span></a></li>
      <li><a href="#projects" class=""><i class="fas fa-laptop-code"></i><span>Projects</span></a></li>
      <li><a href="#skills" class=""><i class="fas fa-code"></i><span>Skills</span></a></li>
      <li><a href="#training" class=""><i class="fas fa-dumbbell"></i><span>Training</span></a></li>
      <li><a href="#education" class=""><i class="fas fa-user-graduate"></i><span>Education</span></a> 
      </li>
      <li><a href="#contact_me" class=""><i class="far fa-address-book"></i><span>Contact me</span></a> 
      </li>
    </ul>
</nav>

https://codepen.io/naveen444/pen/zYooJzd?editors=1100

我在网上读到动画和过渡是不同的,过渡可以反转,但动画不行,但我以前用过 CSS 动画,我记得过渡:全是 2;可以平滑地反转所有转换。如果我说错了什么,请原谅我。我是这方面的绝对初学者,请指正。

您可以在 hover 上执行 transform: scale(0.8) translateY(-60px); 而不是添加 animation。我在 css 之后进行了更改,并分叉了你的 codepen。这是你想要的。

.navmenu ul li a i{
  position: relative;
  -webkit-transition: -webkit-transform 1s;
  transition: transform 1s;
  color: orange;
}
.navmenu ul li a:hover i{
  -webkit-transform: scale(0.8) translateY(-60px);
  transform: scale(0.8) translateY(-60px);
  color: orange;
}

这里也是片段。

body {
  background: black;
}

ul {
  list-style: none;
}

.navmenu {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
}

.navmenu ul {
  padding-left: 40px;
  position: relative;
}

.navmenu ul li {
  padding: 15px 0;
}

.navmenu ul li a {
  text-decoration: none;
  position: relative;
  font-size: 1.8rem;
  font-weight: 900;
}

.navmenu ul li a span {
  font-size: 1rem;
  padding-left: 20px;
  color: orange;
  /*   transition: all 0.1s; */
  font-weight: 600;
  display: none;
}

.navmenu ul li a i {
  position: relative;
  -webkit-transition: -webkit-transform 1s;
  transition: transform 1s;
  color: orange;
}

.navmenu ul li a:hover i {
  -webkit-transform: scale(0.8) translateY(-60px);
  transform: scale(0.8) translateY(-60px);
  color: orange;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />

<body>
  <nav class="navmenu">
    <ul>
      <li><a href="#home" class=""><i class="fas fa-home"></i><span>Home</span></a></li>
      <li><a href="#projects" class=""><i class="fas fa-laptop-code"></i><span>Projects</span></a></li>
      <li><a href="#skills" class=""><i class="fas fa-code"></i><span>Skills</span></a></li>
      <li><a href="#training" class=""><i class="fas fa-dumbbell"></i><span>Training</span></a></li>
      <li><a href="#education" class=""><i class="fas fa-user-graduate"></i><span>Education</span></a></li>
      <li><a href="#contact_me" class=""><i class="far fa-address-book"></i><span>Contact me</span></a></li>
    </ul>
  </nav>

</body>

这些不是经典的过渡,而是关键帧动画。使用纯 CSS,你可以这样做;

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

.intern:hover {
    -webkit-animation: out 1s;
}

@-webkit-keyframes in {
    from   { -webkit-transform: rotate(0deg); }
    to { -webkit-transform: rotate(360deg);}
}

@-webkit-keyframes out {
    0%   { -webkit-transform: rotate(360deg); }
    100% { -webkit-transform: rotate(0deg); }
}
<div style = "width : 100px; height : 100px; background-color : red" class ="intern"></div>

运行 代码片段,您可以找到它在鼠标移开时执行动画。

您可以使用 class 样式定义前后状态,add/remove 这些 class 带有事件侦听器。一种状态将有一个 mouseover 侦听器,而另一种状态将有一个 mouseleave 侦听器。然后,您需要使用 css 定义前后状态。然后将您的@keyframes 规则添加到这些特定的 classes.

例如,您有一个 class 样式元素,我们可以将其称为 before 状态 #icon。然后你有一个 class 就是 hover 状态 slidein 根据您希望动画完成补间时状态的外观设置样式。@keyframes 规则中为特定 class 设置动画参数。然后你为 mouseout 状态设置另一个 class ,这有一个特定的样式,你希望元素在 returns 到它的 原始状态。根据来自 mouseover 的元素状态添加 @keyframes 规则。最后,使用 setTimeout 删除 mouseout 状态 class与动画时长一致。

我在父元素上添加了一个黄色 BG 来说明悬停触发事件监听器和动画元素之间的关系。

const icon = document.querySelectorAll('.icon')

const animate = (el, duration) => {
  const root = document.documentElement;
  // conditional that sets the CSS variable to the duration called in your function
  // using the css :root element, checks if the duration is over one second and 
  // formats the root variable to seconds/milliseconds accordingly
  if (`${duration}`.length > 3) {
    let whole = `${duration}`.slice(0, `${duration}`.length - 3);    
    root.style.setProperty('--duration', `${whole}s`);
  } else {
    root.style.setProperty('--duration', `.${duration}s`);
  }
  el.forEach((node) => {
    node.addEventListener('mouseenter', (e) => {
      node.children[0].classList.add('slidein');
    })
    node.addEventListener('mouseleave', (e) => {
      node.children[0].classList.add('slideout');
      node.children[0].classList.remove('slidein');
      setTimeout(() => {
        node.children[0].classList.remove('slideout')
      }, duration)
    })
  })
  console.log(root)
}

animate(icon, 650)
:root {
  --top-pos: -30px;
  --duration: 0.7s;
  --scale-to: scale(0.6)
}

#parent {
  margin-top: 30px;
  height: 50px;
  width: 50px;
}

.icon img {
  width: 50px;
  height: 50px;
}

.icon {
  margin: 10px 0;
  background: yellow;
}

.slidein {
  animation: slidein var(--duration) ease-out;
  position: relative;
  top: var(--top-pos);
  transform: var(--scale-to);
}

.slideout {
  animation: slideout var(--duration) ease-out;
  position: relative;
  transform: var(--scale-to);
  top: 0px;
}

@keyframes slidein {
  0% {
    top: 0px;
    transform: scale(1);
  }
  100% {
    top: var(--top-pos);
    transform: var(--scale-to);
  }
}

@keyframes slideout {
  0% {
    top: var(--top-pos);
    transform: var(--scale-to);
  }
  100% {
    top: 0px;
    transform: scale(1);
  }
}
<div id="parent">
  <div class="icon">
    <img src="https://nextgate.com/wp-content/uploads/2018/02/icon-implementation.png">
  </div>
  <div class="icon">
    <img src="https://res.cloudinary.com/logrhythm/image/upload/c_scale,w_175/v1519675460/icons/training-advanced-admin-icon.png">
  </div>
  <div class="icon">
    <img src="http://haltin.com.tr/wp-content/uploads/2015/12/icon_integrity-6.png">
  </div>
  <div class="icon">
    <img src="http://www.stephensre.com/images/icons-selling/icon-inspect.png">
  </div>
</div>

你能检查下面的代码吗link?希望对你有用。

您可以使用 transformtransition 属性 在导航栏图标上使用过渡 属性 而不使用 animation@-webkit-keyframes 来制作流畅的动画].

请参考这个link:https://jsfiddle.net/yudizsolutions/zpL3yc4n/