如何反转关键帧?

时间:2018-08-21 20:11:45

标签: css reactjs sass

我尝试创建响应式网络应用,该应用在移动设备上的外观如下:

enter image description here

通过单击菜单栏,它将转换为:

enter image description here

样式用SCSS编写,外观如下:

.topbar-menu {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  position: relative;

  .topbar-navi-menu {
    margin-left: 15px;
    height: 30px;
    width: 40px;
    display: block;
    cursor: pointer;
    position: relative;

    i {
      position: absolute;
      height: 5px;
      width: 100%;
      background-color: #ffffff;

      &.topbar-animate-forward {
        &:first-child {
          animation: topbar-first-bulk 500ms forwards;
        }

        &:nth-child(2) {
          animation: topbar-middle-bulk 500ms forwards;
        }

        &:last-child {
          animation: topbar-last-bulk 500ms forwards;
        }
      }

      &:first-child {
        top: 0;
      }

      &:nth-child(2) {
        top: 50%;
        transform: translateY(-50%);
      }

      &:last-child {
        bottom: 0;
      }
    }

    @keyframes topbar-first-bulk {
      0% {
        top: 0;
        transform: translateY(0%) rotate(0deg);
      }

      25% {
        top: 50%;
        transform: translateY(-50%) rotate(0deg);
      }

      50% {
        top: 50%;
        transform: translateY(-50%) rotate(-45deg);
      }

      100% {
        top: 50%;
        transform: translateY(-50%) rotate(-45deg);
      }
    }

    @keyframes topbar-middle-bulk {
      0% {
        top: 50%;
        transform: translateY(-50%) rotate(0deg);
      }

      25% {
        top: 50%;
        transform: translateY(-50%) rotate(0deg);
      }

      50% {
        top: 50%;
        transform: translateY(-50%) rotate(45deg);
      }

      100% {
        top: 50%;
        transform: translateY(-50%) rotate(45deg);
      }
    }

    @keyframes topbar-last-bulk {
      0% {
        bottom: 0;
        transform: translateY(0%) rotate(0deg);
      }

      25% {
        bottom: 50%;
        transform: translateY(50%) rotate(0deg);
      }

      50% {
        bottom: 50%;
        transform: translateY(50%) rotate(-45deg);
      }

      100% {
        bottom: 50%;
        transform: translateY(50%) rotate(-45deg);
      }
    }
  }
}

我正在使用reasonreact,就像reactjs。 JSX结构:

<div className="topbar-container">
  <section className="topbar-menu">
    <a
      onClick={
        _evt => self.send(MobileMenuToggler(self.state.showMobileMenu))
      }
      className="topbar-navi-menu">
      <i className={self.state.mobileMenuAnimate} />
      <i className={self.state.mobileMenuAnimate} />
      <i className={self.state.mobileMenuAnimate} />
    </a>
  </section>
</div>

如何使用CSS将动画反转回到菜单栏?

1 个答案:

答案 0 :(得分:3)

使用过渡在状态之间进行交换。您不能告诉动画轻松地前进和后退,因为它们的插值(即动画播放的当前时间步长)是固定的。即使您突然告诉样式它应该向后而不是向前,它也不会以您想的方式进行动画处理,因为它将以相同的当前时间步应用新的插值函数,这意味着它将仅适应新的插值。

相反,应应用分层的过渡,并设置不同的过渡延迟,这些延迟与您删除“活动”类时希望它们的延迟相反。

例如,在您的样式中,您想要等待应用变换更改,直到动画达到25%。只需在该属性上设置过渡延迟即可。

考虑阅读本文以获取有关多步动画的更多详细信息:Using Multi-Step Animations and Transitions

const toggle = document.getElementById("toggle");

toggle.addEventListener("click", e => {
  toggle.classList.toggle("topbar-animate-forward");
});
.topbar-container {
  background-color: blue;
  padding: 1em;
}

.topbar-menu {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  position: relative;
}

.topbar-menu .topbar-navi-menu {
  margin-left: 15px;
  height: 30px;
  width: 40px;
  display: block;
  cursor: pointer;
  position: relative;
}

.topbar-menu .topbar-navi-menu i {
  position: absolute;
  height: 5px;
  width: 100%;
  background-color: #ffffff;
}

.topbar-menu .topbar-navi-menu i {
  transition: top 500ms ease-in-out 125ms, bottom 500ms ease-in-out 125ms, transform 500ms ease-in-out;
}

.topbar-menu .topbar-navi-menutopbar-animate-forward i {
  transition: top 500ms ease-in-out, bottom 500ms ease-in-out, transform 500ms ease-in-out 125ms;
}

.topbar-menu .topbar-navi-menu i:first-child {
  top: 0;
  transform: translateY(0%) rotate(0deg);
}

.topbar-menu .topbar-navi-menu.topbar-animate-forward i:first-child {
  top: 50%;
  transform: translateY(-50%) rotate(-45deg);
}

.topbar-menu .topbar-navi-menu i:nth-child(2) {
  top: 50%;
  transform: translateY(-50%);
}

.topbar-menu .topbar-navi-menu.topbar-animate-forward i:nth-child(2) {
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
}

.topbar-menu .topbar-navi-menu i:last-child {
  bottom: 0;
  transform: translateY(0%) rotate(0deg);
}

.topbar-menu .topbar-navi-menu.topbar-animate-forward i:last-child {
  bottom: 50%;
  transform: translateY(50%) rotate(-45deg);
}
<div class="topbar-container">
  <section class="topbar-menu">
    <a id="toggle" class="topbar-navi-menu">
      <i></i>
      <i></i>
      <i></i>
    </a>
  </section>
</div>