254 Codepen

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);
  }
}

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи