css - 编辑 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>
解决方案
这个问题有三个主要部分。
首先,如何在动画中只有一扇门。有 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;"/>
推荐阅读
- python - csv 写入器在一列中输出
- ios - Is there a way to hide a UILabel when the user starts typing, and then make it re-appear if the user removes all input?
- reactjs - How to call separate code for every single prop in useEffect
- java - What is an alternative to comparing two string with regex
- schema.org - SDTT error: "Service is not a known valid target type for the itemReviewed property"
- vba - VBA using SUMIFS with more criteria
- javascript - FullCalendar get events from database
- html - bootstrap-select 在点击后不显示下拉菜单
- reactjs - 如何在不同的服务器上托管不同的路由?
- c++ - C++ - 如何通过引用传递对象以访问其方法?