首页 > 解决方案 > 编辑 CSS 动画

问题描述

我在网上找到了一个 css 动画,但我想稍微编辑一下。

这是动画的链接

有没有我可以让这个动画只有在点击网站上的某个按钮时才运行,是否有可能门只打开一次,它会导致门另一端的不同站点?

现在门动画无限次运行。请帮忙

body {
  display: flex;
  width: 100%;
  height: 100vh;
  background: #222;
  perspective: 100vw;
  overflow: hidden;
  animation: squiggly-anim 0.4s infinite;
  -webkit-animation: squiggly-anim 0.2s infinite;
}

@-webkit-keyframes squiggly-anim {
  0% {
    filter: url("#squiggly-0");
  }
  25% {
    filter: url("#squiggly-1");
  }
  50% {
    filter: url("#squiggly-2");
  }
  75% {
    filter: url("#squiggly-3");
  }
  100% {
    filter: url("#squiggly-4");
  }
}

@keyframes squiggly-anim {
  0% {
    filter: url("#squiggly-0");
  }
  25% {
    filter: url("#squiggly-1");
  }
  50% {
    filter: url("#squiggly-2");
  }
  75% {
    filter: url("#squiggly-3");
  }
  100% {
    filter: url("#squiggly-4");
  }
}

body .door {
  position: absolute;
  width: 100px;
  height: 200px;
  left: calc(50% - 50px);
  top: calc(50% - 100px);
  box-shadow: inset 0 -5px 0 0 #222, inset 0 0 0 1px #fff, 0 5px 0 0 #222, 0 0 0 100vw #222;
  perspective: 500px;
  transform-style: preserve-3d;
  -webkit-animation: scaling 5s linear infinite;
  animation: scaling 5s linear infinite;
  transform: translateZ(-1px);
}

body .door:nth-of-type(3) {
  -webkit-animation-delay: 1.25s;
  animation-delay: 1.25s;
}

body .door:nth-of-type(3) .face {
  -webkit-animation-delay: 1.25s;
  animation-delay: 1.25s;
}

body .door:nth-of-type(2) {
  -webkit-animation-delay: 2.5s;
  animation-delay: 2.5s;
}

body .door:nth-of-type(2) .face {
  -webkit-animation-delay: 2.5s;
  animation-delay: 2.5s;
}

body .door:nth-of-type(1) {
  -webkit-animation-delay: 3.75s;
  animation-delay: 3.75s;
}

body .door:nth-of-type(1) .face {
  -webkit-animation-delay: 3.75s;
  animation-delay: 3.75s;
}

@-webkit-keyframes scaling {
  0% {
    transform: translateZ(0vw);
    opacity: 1;
    z-index: 0;
  }
  50% {
    transform: translateZ(100vw);
    opacity: 1;
    z-index: 1;
  }
  95% {
    transform: translateZ(200vw);
    opacity: 1;
    z-index: 2;
  }
  100% {
    transform: translateZ(300vw);
    opacity: 0;
    z-index: 3;
  }
}

@keyframes scaling {
  0% {
    transform: translateZ(0vw);
    opacity: 1;
    z-index: 0;
  }
  50% {
    transform: translateZ(100vw);
    opacity: 1;
    z-index: 1;
  }
  95% {
    transform: translateZ(200vw);
    opacity: 1;
    z-index: 2;
  }
  100% {
    transform: translateZ(300vw);
    opacity: 0;
    z-index: 3;
  }
}

@keyframes scaling {
  0% {
    transform: translateZ(0vw);
    opacity: 1;
    z-index: 0;
  }
  50% {
    transform: translateZ(100vw);
    opacity: 1;
    z-index: 1;
  }
  95% {
    transform: translateZ(200vw);
    opacity: 1;
    z-index: 2;
  }
  100% {
    transform: translateZ(300vw);
    opacity: 0;
    z-index: 3;
  }
}

@keyframes scaling {
  0% {
    transform: translateZ(0vw);
    opacity: 1;
    z-index: 0;
  }
  50% {
    transform: translateZ(100vw);
    opacity: 1;
    z-index: 1;
  }
  95% {
    transform: translateZ(200vw);
    opacity: 1;
    z-index: 2;
  }
  100% {
    transform: translateZ(300vw);
    opacity: 0;
    z-index: 3;
  }
}

@keyframes scaling {
  0% {
    transform: translateZ(0vw);
    opacity: 1;
    z-index: 0;
  }
  50% {
    transform: translateZ(100vw);
    opacity: 1;
    z-index: 1;
  }
  95% {
    transform: translateZ(200vw);
    opacity: 1;
    z-index: 2;
  }
  100% {
    transform: translateZ(300vw);
    opacity: 0;
    z-index: 3;
  }
}

@keyframes scaling {
  0% {
    transform: translateZ(0vw);
    opacity: 1;
    z-index: 0;
  }
  50% {
    transform: translateZ(100vw);
    opacity: 1;
    z-index: 1;
  }
  95% {
    transform: translateZ(200vw);
    opacity: 1;
    z-index: 2;
  }
  100% {
    transform: translateZ(300vw);
    opacity: 0;
    z-index: 3;
  }
}

@keyframes scaling {
  0% {
    transform: translateZ(0vw);
    opacity: 1;
    z-index: 0;
  }
  50% {
    transform: translateZ(100vw);
    opacity: 1;
    z-index: 1;
  }
  95% {
    transform: translateZ(200vw);
    opacity: 1;
    z-index: 2;
  }
  100% {
    transform: translateZ(300vw);
    opacity: 0;
    z-index: 3;
  }
}

body .door:after {
  content: "";
  position: absolute;
  width: 200vw;
  height: 100vw;
  left: -50vw;
  bottom: 5px;
  box-shadow: 0 1px 0 0 #fff;
  z-index: -1;
}

body .door .face {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(100% - 4px);
  transform-style: preserve-3d;
  box-shadow: inset 0 0 0 1px #fff;
  background: #222;
  transform-origin: left;
  -webkit-animation: swing 5s ease-in-out infinite;
  animation: swing 5s ease-in-out infinite;
}

body .door .face:before {
  content: "";
  position: absolute;
  width: 10px;
  height: 10px;
  box-shadow: 0 0 0 1px #fff;
  border-radius: 100%;
  right: 10px;
  top: calc(50% - 5px);
  transform-style: preserve-3d;
  transform: translateZ(6px);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  background: #222;
}

body .door .face:after {
  content: "";
  position: absolute;
  width: 4px;
  height: 2.5px;
  box-shadow: 0 0 0 1px #fff;
  opacity: 0.75;
  border-radius: 0;
  right: 10px;
  top: calc(50% - 1.25px);
  transform-style: preserve-3d;
  transform: translateZ(2.5px) rotateY(90deg);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  background: #222;
}

@-webkit-keyframes swing {
  15% {
    transform: rotateY(0deg);
  }
  50% {
    transform: rotateY(-125deg) translateZ(-2px);
  }
  75% {
    transform: rotateY(-125deg);
  }
  100% {
    transform: rotateY(-125deg);
  }
}

@keyframes swing {
  15% {
    transform: rotateY(0deg);
  }
  50% {
    transform: rotateY(-125deg) translateZ(-2px);
  }
  75% {
    transform: rotateY(-125deg);
  }
  100% {
    transform: rotateY(-125deg);
  }
}

body .door .face .right {
  position: absolute;
  width: 10%;
  background: #222;
  height: 100%;
  top: 0;
  right: -10%;
  transform-origin: left;
  transform: rotateY(90deg);
  box-shadow: inset 0 0 0 1px #fff;
}
<div class='door'>
  <div class='face'>
    <div class='right'></div>
  </div>
</div>
<div class='door'>
  <div class='face'>
    <div class='right'></div>
  </div>
</div>
<div class='door'>
  <div class='face'>
    <div class='right'></div>
  </div>
</div>
<div class='door'>
  <div class='face'>
    <div class='right'></div>
  </div>
</div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="display:none">
<defs>
<filter id="squiggly-0">
<feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="0"/>
<feDisplacementMap id="displacement" in="SourceGraphic" in2="noise" scale="2" />
</filter>
<filter id="squiggly-1">
<feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="1"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="3" />
</filter>
<filter id="squiggly-2">
<feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="2"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="2" />
</filter>
<filter id="squiggly-3">
<feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="3"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="3" />
</filter>
<filter id="squiggly-4">
<feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="4"/>
<feDisplacementMap in="SourceGraphic" in2="noise" scale="1" />
</filter>
</defs>
</svg>

标签: csscss-animations

解决方案


这个问题有三个主要部分。

首先,如何在动画中只有一扇门。有 4 个带类门的 div。如果我们取出其中的 3 个,剩下的一个动画,但在动画之前有一个延迟(在原始动画中需要这样,以便 4 个门在交错的时间开始它们的运动)所以我们把它取出来。当我们这样做时,我们注意到有几个重复的@keyframes - 只有最后一个会被使用,所以我们也删除了它们。

其次,要求是在单击按钮时启动门动画。所以我们添加一个按钮元素并在 JS 中附加一个事件监听器。单击时,它将向门添加“打开”类。在 CSS 中,门和门面的动画发生了变化,因此在类打开时添加它们。u

第三个要求是当门打开时去一个网站。理想情况下,人们希望网站随着门的打开而逐渐显现。如果网站在我们的控制之下,这是可以实现的,例如代码可以在网站开始时运行,它会逐渐显示出来。如果不是,可以通过将目标网站放在 iframe 中并逐渐显示它来实现类似的效果。但是,许多网站不允许这样做,并且在此片段中只是为了好玩,我们在门后放置了一张图片,并且只有在网站完全打开后才访问该网站。这只是为了展示可能性。可能有更好的方法 - 让我们希望如此。

let page = "https://stackoverflow.com";
let button = document.getElementById('opendoor');
let door = document.querySelector('.door');
let face = document.querySelector('.face');

//document.querySelector("#target").src = page;//only do this if the target website lets you have an iframe

button.addEventListener('click', function () {
  door.classList.add('open');
  button.style.display = 'none';
  document.body.style.animation = 'none';
});

face.addEventListener('webkitAnimationEnd', gotopage);//webkit still needed for some browsers
face.addEventListener('animationEnd', gotopage);

function gotopage() {
  document.getElementById('doorwrapper').style.display = 'none';
  window.location= page;
}
* {
   margin: 0;
   padding: 0;
   box-sizing: border-box;
 }
 
 body {
   background-color: #222;
   width: 100%;
   height: 100vh;
   overflow: hidden; 
   perspective: 100vw;
   overflow: hidden;
   animation: squiggly-anim 0.4s infinite;  
 }
 
 #doorwrapper {
      position: absolute;
      top: -10px;
      left: -10px;/* attempt to stop shakiness at margin black against white */
      display: flex;
      width: calc(100vw + 20px);
      height: calc(100vh + 20px);
      background-color: transparent;
      z-index: 99999;
    }

    @keyframes squiggly-anim {
      0% {
        filter: url("#squiggly-0");
      }
      25% {
        filter: url("#squiggly-1");
      }
      50% {
        filter: url("#squiggly-2");
      }
      75% {
        filter: url("#squiggly-3");
      }
      100% {
        filter: url("#squiggly-4");
      }
    }

    #doorwrapper .door {
      position: absolute;
      width: 100px;
      height: 200px;
      left: calc(50% - 50px);
      top: calc(50% - 100px);
      box-shadow: inset 0 -5px 0 0 #222, inset 0 0 0 1px #fff, 0 5px 0 0 #222, 0 0 0 100vw #222;
      perspective: 500px;
      transform-style: preserve-3d;
      animation-fill-mode: forwards;
      transform: translateZ(-1px);
    }
    
    #doorwrapper .door.open {
      animation: scaling 5s linear 1;
    }

    @keyframes scaling {
      0% {
        transform: translateZ(0vw);
        opacity: 1;
      }
      50% {
        transform: translateZ(100vw);
        opacity: 1;
      }
      95% {
        transform: translateZ(200vw);
        opacity: 1;
      }
      100% {
        transform: translateZ(300vw);
        opacity: 0;
      }
    }

    #doorwrapper .door:after {
      content: "";
      position: absolute;
      width: 200vw;
      height: 100vw;
      left: -50vw;
      bottom: 5px;
      box-shadow: 0 1px 0 0 #fff;
      z-index: -1;
    }

    #doorwrapper .door .face {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: calc(100% - 4px);
      transform-style: preserve-3d;
      box-shadow: inset 0 0 0 1px #fff;
      background: #222;
      transform-origin: left;
      animation-fill-mode: forwards;
    }
    
    #doorwrapper .door.open .face {
      animation: swing 5s ease-in-out 1;  
    }

    #doorwrapper .door .face:before {
      content: "";
      position: absolute;
      width: 10px;
      height: 10px;
      box-shadow: 0 0 0 1px #fff;
      border-radius: 100%;
      right: 10px;
      top: calc(50% - 5px);
      transform-style: preserve-3d;
      transform: translateZ(6px);
      backface-visibility: hidden;
      background: #222;
    }

    #doorwrapper .door .face:after {
      content: "";
      position: absolute;
      width: 4px;
      height: 2.5px;
      box-shadow: 0 0 0 1px #fff;
      opacity: 0.75;
      border-radius: 0;
      right: 10px;
      top: calc(50% - 1.25px);
      transform-style: preserve-3d;
      transform: translateZ(2.5px) rotateY(90deg);
      backface-visibility: hidden;
      background: #222;
    }

    @keyframes swing {
      15% {
        transform: rotateY(0deg);
      }
      50% {
        transform: rotateY(-125deg) translateZ(-2px);
      }
      75% {
        transform: rotateY(-125deg);
      }
      100% {
        transform: rotateY(-125deg);
      }
    }

    #doorwrapper .door .face .right {
      position: absolute;
      width: 10%;
      background: #222;
      height: 100%;
      top: 0;
      right: -10%;
      transform-origin: left;
      transform: rotateY(90deg);
      box-shadow: inset 0 0 0 1px #fff;
    }
<div id="doorwrapper">
    <div class='door'>
      <div class='face'>
        <div class='right'></div>
      </div>
    </div>
</div>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="display:none">
    <defs>
    <filter id="squiggly-0">
    <feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="0"/>
    <feDisplacementMap id="displacement" in="SourceGraphic" in2="noise" scale="2" />
    </filter>
    <filter id="squiggly-1">
    <feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="1"/>
    <feDisplacementMap in="SourceGraphic" in2="noise" scale="3" />
    </filter>
    <filter id="squiggly-2">
    <feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="2"/>
    <feDisplacementMap in="SourceGraphic" in2="noise" scale="2" />
    </filter>
    <filter id="squiggly-3">
    <feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="3"/>
    <feDisplacementMap in="SourceGraphic" in2="noise" scale="3" />
    </filter>
    <filter id="squiggly-4">
    <feTurbulence id="turbulence" baseFrequency="0.01" numOctaves="3" result="noise" seed="4"/>
    <feDisplacementMap in="SourceGraphic" in2="noise" scale="1" />
    </filter>
    </defs>
    </svg>

  <button id="opendoor" style="position: absolute; top: 10px; left: 10px; color: white; background-color: red; z-index: 99999;">Open the door</button>
  
<!-- YOUR WEBSITE - OR IFRAME WITH THE TARGET WEBSITE IN IT (OR WILL GO TO WEBSITE ON END OF ANIMATION IF IFRAME NOT ALLOWED -->
<!-- <iframe id="target" width=100% height=100% src=""></iframe> -->


<img id="mywebsite" src="https://i.stack.imgur.com/qsQbR.jpg" style="position: relative; top: 0; left: 0; z-index: 0; width: 100vw; height: auto;"/>


推荐阅读