STARFOX Arwing Drone из игры на чистом CSS
Космический истребитель STARFOX Arwing Drone из игры, который воспроизвели с анимацией полета в космосе на чистом CSS
PUG
.container
- for (i = 0; i < 400; i++)
.trigger
.monitor
.camera.o-x
.camera.o-y
.camera.o-z
.awing
.stars
- for (i = 0; i < 40; i++)
.star
.fly.o-x
.fly.o-y
.fly.o-z
.free_bounce
.free_rotate
.body
.cockpit
.under
.back
.left
.right
.edge_left
.edge_right
.boosts
- for (i = 0; i < 30; i++)
.boost
.wing_left
.under
.back
.left
.right
.wing_right
.under
.back
.left
.right
SCSS
body {
background: #000;
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
perspective: 500px;
}
.container {
position: relative;
display: grid;
grid-template-rows: repeat(20, 5vh);
grid-template-columns: repeat(20, 5vw);
transform-style: preserve-3d;
}
.trigger {
&:active ~ .monitor {
.body {
transform: rotateY(360deg);
}
}
@for $i from 1 through 20 {
@for $j from 1 through 20 {
$key: ($i - 1) * 20 + $j;
&:nth-child(#{$key}) {
&:hover ~ .monitor {
.fly {
&.o-x {
transform: translateZ(($i - 10) * 25px);
}
&.o-z {
transform: translateX(($j - 10) * 25px) rotateY(($j - 10) * -6deg);
}
}
.camera {
&.o-y {
transform: rotateY(($j - 10) * -3deg);
}
&.o-x {
transform: rotateX(($i - 10) * 3deg);
}
}
}
}
}
}
}
.monitor {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
transform-style: preserve-3d;
}
.camera {
position: absolute;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: 500ms;
}
.awing {
position: absolute;
top: 50%;
left: 50%;
transform-style: preserve-3d;
transform: scale(1.5) rotateY(180deg) rotateX(90deg);
.stars {
position: absolute;
transform-style: preserve-3d;
.star {
position: absolute;
width: 1px;
height: 30px;
background: rgba(255, 255, 255, 0.8);
@for $i from 1 through 40 {
&:nth-child(#{$i}) {
height: random(50) + 20px;
top: random(500) + 0px;
left: random(1000) - 500px;
$duration: random(1500) + 500ms;
animation:
shootingStar#{$i} $duration linear infinite,
fadeInOut $duration linear infinite;
}
$starZ: random(500) - 200px;
@keyframes shootingStar#{$i} {
0% {
transform: translateY(random(300) + 100px) translateZ(#{$starZ});
}
100% {
transform: translateY(random(300) - 1000px) translateZ(#{$starZ});
}
}
}
}
}
.fly.o-x {
transform-style: preserve-3d;
transition: 500ms;
}
.fly.o-y {
transform-style: preserve-3d;
transition: 500ms;
animation: flyY random(10000) + 10000ms cubic-bezier(0.545, 0.080, 0.520, 0.975) infinite;
}
.fly.o-z {
transform-style: preserve-3d;
transition: 500ms;
}
.body {
transform-style: preserve-3d;
transform-origin: 50% 50% 0px;
transition: 2000ms cubic-bezier(0.175, 0.885, 0.320, 1.275);
}
.free_bounce {
transform-style: preserve-3d;
animation: freeBounce 3000ms cubic-bezier(0.545, 0.080, 0.520, 0.975) alternate infinite;
}
.free_rotate {
transform-style: preserve-3d;
animation: freeRotate 2000ms cubic-bezier(0.545, 0.080, 0.520, 0.975) alternate infinite;
}
.cockpit {
display: flex;
transform-style: preserve-3d;
transform: rotateX(-12deg);
.left {
width: 30px;
height: 150px;
background: linear-gradient(0deg, rgba(#fff,1) 0%,rgba(#ccc,1) 100%);
clip-path: polygon(
100% 0%,
0% 25%,
100% 100%
);
transform-origin: 100% 0;
transform: rotateY(-45deg);
}
.right {
width: 30px;
height: 150px;
background: linear-gradient(0deg, rgba(#aaa,1) 0%,rgba(#888,1) 100%);
clip-path: polygon(
0% 0%,
100% 25%,
0% 100%
);
transform-origin: 0 0;
transform: rotateY(45deg);
}
.under {
position: absolute;
width: 60px;
height: 150px;
background: linear-gradient(0deg, rgba(#666,1) 0%,rgba(#333,1) 100%);
clip-path: polygon(
14.5% 23.5%,
85.5% 23.5%,
50% 100%
);
transform-origin: 50% 100%;
transform: rotateX(10.7deg) rotateY(180deg);
backface-visibility: hidden;
}
.back {
position: absolute;
width: 60px;
height: 150px;
background: radial-gradient(ellipse at center, rgba(44,164,244,1) 0%,rgba(13,37,191,1) 67%);
clip-path: polygon(
14.5% 25%,
85.5% 25%,
50% 6%
);
transform-origin: 50% 25%;
transform: translateZ(-21.5px) rotateX(-45deg) rotateY(180deg);
backface-visibility: hidden;
}
.edge_left {
position: absolute;
width: 80px;
height: 40px;
background: #fff;
background: linear-gradient(0deg, rgba(#fff,1) 0%,rgba(#aaa,1) 100%);
clip-path: polygon(
0% 0%,
80% 15%,
100% 100%
);
transform-origin: 100% 100%;
transform: translateX(-70px) translateZ(-20px) rotateY(-20deg) rotateX(20deg);
}
.edge_right {
position: absolute;
width: 80px;
height: 40px;
background: linear-gradient(0deg, rgba(#aaa,1) 0%,rgba(#888,1) 100%);
clip-path: polygon(
100% 0%,
20% 15%,
0% 100%
);
transform-origin: 0 100%;
transform: translateX(50px) translateZ(-20px) rotateY(20deg) rotateX(20deg);
}
}
.wing_left {
position: absolute;
top: 0;
display: flex;
transform-style: preserve-3d;
transform-origin: 50% 30%;
transform: rotateX(-30deg) translate(-20px, 8px) scaleY(1.2);
.left {
width: 20px;
height: 120px;
background: linear-gradient(0deg, rgba(#748EED,1) 0%,rgba(#3554CE,1) 100%);
clip-path: polygon(
100% 5.5%,
0% 25%,
100% 100%
);
transform-origin: 100% 0;
transform: rotateY(-60deg);
}
.right {
width: 20px;
height: 120px;
background: linear-gradient(0deg, rgba(#3f55ba,1) 0%,rgba(#2F49B5,1) 100%);
clip-path: polygon(
0% 5.5%,
100% 25%,
0% 100%
);
transform-origin: 0 0;
transform: rotateY(60deg);
}
.under {
position: absolute;
width: 40px;
height: 120px;
background: #2a3567;
clip-path: polygon(
25% 23.5%,
75% 23.5%,
50% 100%
);
transform-origin: 50% 100%;
transform: rotateX(11deg) translateZ(-1px) rotateY(180deg);
backface-visibility: hidden;
}
.back {
position: absolute;
width: 40px;
height: 120px;
background: #2a3b89;
clip-path: polygon(
25% 25%,
75% 25%,
50% 0%
);
transform-origin: 50% 25%;
transform: translateZ(-18px) rotateX(-39deg) rotateY(180deg);
backface-visibility: hidden;
}
}
.wing_right {
position: absolute;
top: 0;
display: flex;
transform-style: preserve-3d;
transform-origin: 50% 30%;
transform: rotateX(-30deg) translate(40px, 8px) scaleY(1.2);
.left {
width: 20px;
height: 120px;
background: linear-gradient(0deg, rgba(#748EED,1) 0%,rgba(#3554CE,1) 100%);
clip-path: polygon(
100% 5.5%,
0% 25%,
100% 100%
);
transform-origin: 100% 0;
transform: rotateY(-60deg);
}
.right {
width: 20px;
height: 120px;
background: linear-gradient(0deg, rgba(#3f55ba,1) 0%,rgba(#2F49B5,1) 100%);
clip-path: polygon(
0% 5.5%,
100% 25%,
0% 100%
);
transform-origin: 0 0;
transform: rotateY(60deg);
}
.under {
position: absolute;
width: 40px;
height: 120px;
background: #2a3567;
clip-path: polygon(
25% 23.5%,
75% 23.5%,
50% 100%
);
transform-origin: 50% 100%;
transform: rotateX(11deg) rotateY(180deg);
backface-visibility: hidden;
}
.back {
position: absolute;
width: 40px;
height: 120px;
background: #2a3b89;
clip-path: polygon(
25% 25%,
75% 25%,
50% 0%
);
transform-origin: 50% 25%;
transform: translateZ(-18px) rotateX(-39deg) rotateY(180deg);
backface-visibility: hidden;
}
}
.boosts {
position: absolute;
left: 50%;
transform-style: preserve-3d;
transform-origin: 50% 0;
transform: rotateX(12deg);
}
.boost {
position: absolute;
width: 10px;
height: 50px;
margin-left: -5px;
background: #00aaff;
@for $i from 1 through 30 {
&:nth-child(#{$i}) {
height: random(40) + 40px;
animation: boost#{$i} random(1500) + 500ms linear infinite;
}
$z: random(20) * -1px;
$x: random(40) - 20px;
$rotate: random(360) + 0deg;
@keyframes boost#{$i} {
0% {
transform: translateZ(random(20) * -1 - 10px) translateY(random(20) - 60px) translateX(random(30) - 15px) rotateY($rotate);
opacity: 0.6;
}
100% {
transform: translateZ(random(20) * -1px) translateY(-300px) translateX(random(80) - 40px) rotateY($rotate);
opacity: 0;
}
}
}
}
}
@keyframes fadeInOut {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes barrelRoll {
0% {
transform: rotateY(0deg) rotateX(-15deg);
}
50% {
transform: rotateY(375deg) rotateX(-15deg);
}
70% {
transform: rotateY(355deg) rotateX(-15deg);
}
80% {
transform: rotateY(360deg) rotateX(-15deg);
}
100% {
transform: rotateY(360deg) rotateX(-15deg);
}
}
@keyframes cameraRotate {
0% {
transform: scale(1.5) rotateX(70deg) rotateZ(0 + 20deg);
}
100% {
transform: scale(1.5) rotateX(70deg) rotateZ(360 - 20deg);
}
}
@keyframes slide {
0% {
left: 110%;
}
100% {
left: -10%;
}
}
@keyframes flyX {
0% {
transform: translateX(0px);
}
25% {
transform: translateX(180px);
}
50% {
transform: translateX(0px);
}
75% {
transform: translateX(-180px);
}
100% {
transform: translateX(0px);
}
}
@keyframes flyY {
0% {
transform: translateY(0px);
}
25% {
transform: translateY(200px);
}
50% {
transform: translateY(0px);
}
75% {
transform: translateY(-200px);
}
100% {
transform: translateY(0px);
}
}
@keyframes flyZ {
0% {
transform: translateZ(0px);
}
25% {
transform: translateZ(150px);
}
50% {
transform: translateZ(0px);
}
75% {
transform: translateZ(-150px);
}
100% {
transform: translateZ(0px);
}
}
@keyframes freeBounce {
0% {
transform: translateZ(-10px);
}
100% {
transform: translateZ(10px);
}
}
@keyframes freeRotate {
0% {
transform: rotateY(-5deg);
}
100% {
transform: rotateY(5deg);
}
}