用Vanilla JS反转动画的正确方法是?

时间:2018-11-13 07:21:05

标签: javascript html css

因此,我在这里有一个非常简单的示例,其中我通过JS应用动画来扩大我的内部div。但是,在尝试使用JS反转动画时,我发现它并没有过渡。而是突然恢复到原始状态。

示例:

const grow = document.querySelector('.grow');
const reverse = document.querySelector('.reverse');
const inner = document.querySelector('.inner');


grow.addEventListener('click', function() {
  inner.classList.add('grow');
})

//things I've tried

// reverse.addEventListener('click', function() {
//   inner.classList.add('reverse');
// })

reverse.addEventListener('click', function() {
  inner.style.animationDirection = 'reverse';
})
html, body {
  height: 100%;
  width: 100%;
  margin: 0;
}

.container {
  height: 100%;
  width: 100%;
  background: orange;
  position: relative;
}

.inner {
  position: absolute;
  bottom: 0;
  height: 52px;
  width: 80%;
  background: #fff;
}

.grow {
  animation: grow forwards 1s ease-in-out;
}

.reverse {
  animation: grow reverse 1s ease-in-out;
}

@keyframes grow {
  from {
    height: 52px;
  }
  
  to {
    height: 100%;
  }
}
<div class="container">
  <div class="inner">
    <button class="grow">Grow</button>
    <button class="reverse">Reverse</button>
  </div>
</div>

有人可以向我解释为什么会发生这种情况,以及如何在不添加标记为“缩小”的单独关键帧的情况下平稳地恢复过渡吗?

2 个答案:

答案 0 :(得分:3)

这是因为.grow.reverse都附加在.inner上,这使事情变得混乱了。您必须先删除.grow,然后再添加.reverse。但是,这一次删除.grow动画时,div的高度将再次降低到52px,因此在应用.reverse之前必须保持其高度。但是(再次),您需要在运行.inner之后降低.reverse的高度,否则它不会丢失其高度。因此,您可以执行以下操作:

reverse.addEventListener('click', function() {
  inner.classList.remove('grow');
  inner.style.height = '100%';

  // You need setTimeout() idk why
  setTimeout(function() {
    inner.classList.add('reverse');
    inner.style.height = '52px';
  }, 10);
})

答案 1 :(得分:0)

可悲的是,animationDirection属性仅对无限动画(source)有影响,因此您可能仍要考虑使用shrink

具有无限动画的代码:

const grow = document.querySelector('.grow');
const reverse = document.querySelector('.reverse');
const inner = document.querySelector('.inner');


grow.addEventListener('click', function() {
  inner.classList.add('grow');
})

//things I've tried

// reverse.addEventListener('click', function() {
//   inner.classList.add('reverse');
// })

reverse.addEventListener('click', function() {
  inner.style.animationDirection = 'reverse';
})
html, body {
  height: 100%;
  width: 100%;
  margin: 0;
}

.container {
  height: 100%;
  width: 100%;
  background: orange;
  position: relative;
}

.inner {
  position: absolute;
  bottom: 0;
  height: 52px;
  width: 80%;
  background: #fff;
}

.grow {
  animation: grow forwards 1s infinite;
}

.reverse {
  animation: grow reverse 1s infinite;
}

@keyframes grow {
  from {
    height: 52px;
  }
  
  to {
    height: 100%;
  }
}
<div class="container">
  <div class="inner">
    <button class="grow">Grow</button>
    <button class="reverse">Reverse</button>
  </div>
</div>

缩小解决方案:

const grow = document.querySelector('.grow');
const reverse = document.querySelector('.reverse');
const inner = document.querySelector('.inner');


grow.addEventListener('click', function() {
  inner.classList.add('grow');
})

//things I've tried

 reverse.addEventListener('click', function() {
   inner.classList.add('reverse');
 })
html, body {
  height: 100%;
  width: 100%;
  margin: 0;
}

.container {
  height: 100%;
  width: 100%;
  background: orange;
  position: relative;
}

.inner {
  position: absolute;
  bottom: 0;
  height: 52px;
  width: 80%;
  background: #fff;
}

.grow {
  animation: grow forwards 1s ease-in-out;
}

.reverse {
  animation: shrink forwards 1s ease-in-out;
}

@keyframes grow {
  from {
    height: 52px;
  }
  
  to {
    height: 100%;
  }
}

@keyframes shrink {
  from {
    height: 100%;
  }
  
  to {
    height: 52px;
  }
}
<div class="container">
  <div class="inner">
    <button class="grow">Grow</button>
    <button class="reverse">Reverse</button>
  </div>
</div>