单击其中一个面时如何使 3d 立方体动画平滑过渡?

How to make a smooth transition of a 3d cube animation when you click on one of the faces?

我需要确保当您单击其中一个面时,立方体会随着该面平滑旋转并且动画停止。而当你关闭脸部时,尺寸逐渐减小,动画继续。也许有人做了类似的事情并分享了一个例子?

现在只为 TOP 完成。但是如何制作流畅的动画我不敢想象。

document.addEventListener("DOMContentLoaded", function() {

  let cube = document.querySelector('#D3Cube');
  let side1 = document.querySelector('#side1');
  let closeBtn = document.querySelector('.closeLink');

  cube.addEventListener('mouseover', function(){
    cube.style.animationPlayState = "paused";
  });
  cube.addEventListener('mouseout', function(){
    cube.style.animationPlayState = "running";
  });

  side1.addEventListener('click', function(){
    cube.classList.remove("animatCube");
    cube.classList.add("animateTop");
  });
  closeBtn.addEventListener('click', function(){
    cube.classList.remove("animateTop");
    cube.classList.add("animatCube");
});


});
#wrapD3Cube {
    width: 500px;
    height: 500px;
    margin: 200px auto;
}
#D3Cube {
    width: 300px;
    height: 300px;
    top: 50px;
    transform-style: preserve-3d;

    margin: auto;
    position: relative;
    transform-style: preserve-3d;
}

.animatCube{
  animation: cube 5s linear infinite;
  transform: rotateX(-22deg) rotateY(-38deg) rotateZ(0deg);
}
.animateTop{
  transform: rotateX(-90deg) rotateY(0deg) rotateZ(0deg) scale3d(1.5, 1, 1.5);
}

@keyframes cube {
  100%  {  transform: rotateX(-22deg) rotateY(-398deg) rotateZ(0deg); }
}
#D3Cube > div {
  position: absolute;
  transition: all 0.5s linear;
  width: 300px;
  height: 300px;
  float: left;
  overflow: hidden;
  opacity: 0.85;
}
#side1 {
  transform: rotatex(90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: purple;
  backface-visibility:hidden;
}
#side2 {
  transform: rotateY(-90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #ffaf1c;
  backface-visibility:hidden;
}
#side3 {
  transform: translateX(0px) translateY(0px) translateZ(150px);
  background-color: #58d568;
  backface-visibility:hidden;
}
#side4 {
  transform: rotateY(90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #ed3030;
  backface-visibility:hidden;
}
#side5 {
  transform: rotateY(180deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #1c5ffe;
  backface-visibility:hidden;
}
#side6 {
  transform: rotateX(-90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #f2f215;
  backface-visibility:hidden;
}
<div id="wrapD3Cube">
  <div id="D3Cube" class="animatCube">
    <div class="slide" id="side1"><a class="closeLink" href="">x</a></div>
    <div class="slide" id="side2">2</div>
    <div class="slide" id="side3">3</div>
    <div class="slide" id="side4">4</div>
    <div class="slide" id="side5">5</div>
    <div class="slide" id="side6">6</div>
  </div>
</div>

点击面部时,可以使用getComputedStyle(cube).getPropertyValue("transform")获取点击面部时变换的当前状态。
然后,您将其应用到变换 属性 中以设置该状态,删除动画,添加 class 以显示面部 (animateTop),最后删除您刚刚为class 生效。

恢复正常时,删除内联停止 animation,一些 cube 动画将会发生。 5秒后,animateTop会被移除,然后只有动画会继续运行。

我还创建了两个变量以更好地控制:open 以检查面部何时打开或关闭。并且 changing 检查它何时转换为打开或关闭。

let open = false;
let changing = false;

document.addEventListener("DOMContentLoaded", function() {

  let cube = document.querySelector('#D3Cube');
  let side1 = document.querySelector('#side1');

  side1.addEventListener('click', function() {

    if (changing) {
      return;
    }

    if (!open && !changing) {

      open = true;
      changing = true;

      cube.classList.add('open')
      var compTransform = getComputedStyle(cube).getPropertyValue("transform");
      cube.style.transform = compTransform;
      cube.style.animation = 'none';
      cube.classList.add("animateTop");
      setTimeout(function() {
        cube.classList.remove('closed')
        cube.style.removeProperty('transform');
      }, 50);
      setTimeout(function() {
        changing = false;
      }, 1640);

    } else if (open && !changing) {

      open = false;
      changing = true;
      cube.classList.remove('open')
      setTimeout(function() {
        cube.classList.remove("animateTop");
        cube.classList.add('closed')
        changing = false;
      }, 4999);
      cube.style.removeProperty('animation');
    }
  });
});
#wrapD3Cube {
  width: 500px;
  height: 500px;
  margin: 200px auto;
}
#D3Cube {
  width: 300px;
  height: 300px;
  top: 50px;
  transform-style: preserve-3d;
  margin: auto;
  position: relative;
  transform-style: preserve-3d;
  transition: 1.64s;
}
#D3Cube.closed:hover {
  animation-play-state: paused;
  transition: animation 0s;
}
.closeLink {
  color: #f7f7f7;
  background-color: #333;
  font-size: 20px;
}
.animatCube{
  animation: cube 5s linear infinite;
  transform: rotateX(-22deg) rotateY(-38deg) rotateZ(0deg);
}
.animateTop{
  transform: rotateX(-90deg) rotateY(0deg) rotateZ(0deg) scale3d(1.5, 1, 1.5);
}
@keyframes cube {
  100%  {  transform: rotateX(-22deg) rotateY(-398deg) rotateZ(0deg); }
}
#D3Cube > div {
  position: absolute;
  transition: all 0.5s linear;
  width: 300px;
  height: 300px;
  float: left;
  overflow: hidden;
  opacity: 0.85;
}
#side1 {
  transform: rotatex(90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: purple;
  backface-visibility:hidden;
}
#side2 {
  transform: rotateY(-90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #ffaf1c;
  backface-visibility:hidden;
}
#side3 {
  transform: translateX(0px) translateY(0px) translateZ(150px);
  background-color: #58d568;
  backface-visibility:hidden;
}
#side4 {
  transform: rotateY(90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #ed3030;
  backface-visibility:hidden;
}
#side5 {
  transform: rotateY(180deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #1c5ffe;
  backface-visibility:hidden;
}
#side6 {
  transform: rotateX(-90deg) translateX(0px) translateY(0px) translateZ(150px);
  background-color: #f2f215;
  backface-visibility:hidden;
}
<div id="wrapD3Cube">
  <div id="D3Cube" class="animatCube closed">
    <div class="slide" id="side1"><a class="closeLink" href="">X</a></div>
    <div class="slide" id="side2">2</div>
    <div class="slide" id="side3">3</div>
    <div class="slide" id="side4">4</div>
    <div class="slide" id="side5">5</div>
    <div class="slide" id="side6">6</div>
  </div>
</div>