mixin cuboid()
  .cuboid(class!=attributes.class)
    - let s = 0
    while s < 6
      .cuboid__side
      - s++
.scene
  .helicopter__tilter
    .helicopter__wrapper
      .helicopter
        .helicopter__rotor
          +cuboid()(class="cuboid--rotor")
        .helicopter__cockpit
          +cuboid()(class="cuboid--cockpit")
          .helicopter__base-light
            +cuboid()(class="cuboid--base-light cuboid--light")
          .helicopter__chair
            .helicopter__chair-back
              +cuboid()(class="cuboid--chair")
            .helicopter__chair-bottom
              +cuboid()(class="cuboid--chair")
          .helicopter__dashboard
            +cuboid()(class="cuboid--dashboard")
        .helicopter__tail
          +cuboid()(class="cuboid--tail")
        .helicopter__fin
          +cuboid()(class="cuboid--fin")
          .helicopter__triblade
          .helicopter__tail-light
            +cuboid()(class="cuboid--tail-light cuboid--light")
        .helicopter__stabilizer
          +cuboid()(class="cuboid--stabilizer")
        .helicopter__skids
          .helicopter__skid--left.helicopter__skid
            +cuboid()(class="cuboid--skid")
          .helicopter__skid--right.helicopter__skid
            +cuboid()(class="cuboid--skid")
        .helicopter__wing
          +cuboid()(class="cuboid--wing")
          .helicopter__wing-light.helicopter__wing-light--left
            +cuboid()(class="cuboid--wing-light cuboid--light")
          .helicopter__wing-light.helicopter__wing-light--right
            +cuboid()(class="cuboid--wing-light cuboid--light")
        .helicopter__launchers
          .helicopter__launcher.helicopter__launcher--left
            +cuboid()(class="cuboid--launcher")
          .helicopter__launcher.helicopter__launcher--right
            +cuboid()(class="cuboid--launcher")
        .helicopter__blades
View Compiled
.cuboid
  width 100%
  height 100%
  position relative
  // 1 is the top and go t, r, b, l, f, b

  &__side:nth-of-type(1)
    height calc(var(--thickness) * 1vmin)
    width 100%
    position absolute
    top 0
    transform translate(0, -50%) rotateX(90deg)

  &__side:nth-of-type(2)
    height 100%
    width calc(var(--thickness) * 1vmin)
    position absolute
    top 50%
    right 0
    transform translate(50%, -50%) rotateY(90deg)

  &__side:nth-of-type(3)
    width 100%
    height calc(var(--thickness) * 1vmin)
    position absolute
    bottom 0
    transform translate(0%, 50%) rotateX(90deg)

  &__side:nth-of-type(4)
    height 100%
    width calc(var(--thickness) * 1vmin)
    position absolute
    left 0
    top 50%
    transform translate(-50%, -50%) rotateY(90deg)

  &__side:nth-of-type(5)
    height 100%
    width 100%
    transform translate3d(0, 0, calc(var(--thickness) * 0.5vmin))
    position absolute
    top 0
    left 0

  &__side:nth-of-type(6)
    height 100%
    width 100%
    transform translate3d(0, 0, calc(var(--thickness) * -0.5vmin)) rotateY(180deg)
    position absolute
    top 0
    left 0

*
*:after
*:before
  box-sizing border-box
  transform-style preserve-3d
  transition background 0.25s, transform 0.25s

:root
  --on 1
  --extruded 0
  --base-size 20
  --helicopter-height calc(var(--base-size) * 1vmin)
  --helicopter-width calc(var(--helicopter-height) * 2)
  --helicopter-one 'hsl(0, 0%, %s)' % calc((60 + (var(--on, 0) * 35)) * 1%)
  --helicopter-two 'hsl(0, 0%, %s)' % calc((55 + (var(--on, 0) * 35)) * 1%)
  --helicopter-three 'hsl(0, 0%, %s)' % calc((50 + (var(--on, 0) * 35)) * 1%)
  --helicopter-four 'hsl(0, 0%, %s)' % calc((40 + (var(--on, 0) * 35)) * 1%)
  --chair-one 'hsl(0, 0%, %s)' % calc((20 + (var(--on, 0) * 15)) * 1%)
  --chair-two 'hsl(0, 0%, %s)' % calc((15 + (var(--on, 0) * 15)) * 1%)
  --chair-three 'hsl(0, 0%, %s)' % calc((10 + (var(--on, 0) * 15)) * 1%)
  --chair-four 'hsl(0, 0%, %s)' % calc((5 + (var(--on, 0) * 15)) * 1%)
  --dash-one 'hsl(0, 0%, %s)' % calc((50 + (var(--on, 0) * 15)) * 1%)
  --dash-two 'hsl(0, 0%, %s)' % calc((45 + (var(--on, 0) * 15)) * 1%)
  --dash-three 'hsl(0, 0%, %s)' % calc((40 + (var(--on, 0) * 15)) * 1%)
  --dash-four 'hsl(0, 0%, %s)' % calc((35 + (var(--on, 0) * 15)) * 1%)
  // --chair-one hsl(0, 0%, 35%)
  // --chair-two hsl(0, 0%, 30%)
  // --chair-three hsl(0, 0%, 25%)
  // --chair-four hsl(0, 0%, 20%)
  // --dash-one hsl(0, 0%, 65%)
  // --dash-two hsl(0, 0%, 60%)
  // --dash-three hsl(0, 0%, 55%)
  // --dash-four hsl(0, 0%, 50%)
  --accent-one 'hsl(10, 60%, %s)' % calc((30 + (var(--on, 0) * 35)) * 1%)
  --accent-two 'hsl(10, 60%, %s)' % calc((25 + (var(--on, 0) * 35)) * 1%)
  --accent-three 'hsl(10, 60%, %s)' % calc((20 + (var(--on, 0) * 35)) * 1%)
  --accent-four 'hsl(10, 60%, %s)' % calc((15 + (var(--on, 0) * 35)) * 1%)
  --rocket-one 'hsl(1, 60%, %s)' % calc((20 + (var(--on, 0) * 25)) * 1%)
  --rocket-two 'hsl(1, 60%, %s)' % calc((15 + (var(--on, 0) * 25)) * 1%)
  --rocket-three 'hsl(1, 60%, %s)' % calc((10 + (var(--on, 0) * 25)) * 1%)
  --rocket-four 'hsl(1, 60%, %s)' % calc((5 + (var(--on, 0) * 25)) * 1%)
  --screen-one 'hsla(210, 80%, %s, 0.45)' % calc((25 + (var(--on, 0) * 25)) * 1%)
  --screen-two 'hsla(210, 80%, %s, 0.4)' % calc((25 + (var(--on, 0) * 25)) * 1%)
  --screen-three 'hsla(210, 80%, %s, 0.35)' % calc((25 + (var(--on, 0) * 25)) * 1%)
  --screen-four 'hsla(210, 80%, %s, 0.35)' % calc((25 + (var(--on, 0) * 25)) * 1%)
  // --screen-one hsla(210, 80%, 50%, 0.45)
  // --screen-two hsla(210, 80%, 50%, 0.4)
  // --screen-three hsla(210, 80%, 50%, 0.35)
  // --screen-four hsla(210, 80%, 50%, 0.35)
  --bg 'hsl(210, 80%, %s)' % (calc((15 + (var(--on, 0) * 75)) * 1%))

body
  min-height 100vh
  display grid
  place-items center
  overflow hidden
  touch-action none

.scene
  position fixed
  top 50%
  left 50%
  transform translate3d(-50%, -50%, 100vmin)
  transform translate3d(-50%, -50%, 100vmin) rotateX(-24deg) rotateY(44deg) rotateX(calc(var(--rotate-x, 0) * 1deg)) rotateY(calc(var(--rotate-y, 0) * 1deg))

.helicopter
  height 100%
  width 100%
  position absolute
  top 50%
  left 50%
  // background hsla(280, 80%, 70%, 0.5)
  transform translate(-20%, -50%)

  @keyframes shift
    0%, 10%, 90%, 100%
      transform translate(-20%, -50%) translate3d(0, 0, 0)
    20%, 50%
      transform translate(-20%, -50%) translate3d(0, 0, 10vmin)
    60%, 80%
      transform translate(-20%, -50%) translate3d(0, 0, -10vmin)

  &__wrapper
    position absolute
    top 50%
    left 50%
    transform translate(-50%, -50%)
    // background hsla(210, 30%, 50%, 0.5)
    animation float 1s infinite linear
    height var(--helicopter-height)
    width var(--helicopter-width)

    @keyframes float
      50%
        transform translate(-50%, -65%)

  &__base-light
    --hue 20
    bottom -6%
    width 6%
    height 6%
    left 47%
    position absolute

  &__tail-light
    --hue 15
    top -20%
    width 20%
    height 20%
    position absolute
    left 65%

  &__wing-light
    --hue 90
    --speed 0.4
    top -50%
    width 10%
    height 50%
    position absolute
    left 45%

    &--left
      transform translate3d(0, 0, calc(var(--base-size) * 0.5vmin))
    &--right
      transform translate3d(0, 0, calc(var(--base-size) * -0.5vmin))

  & > *
    position absolute

  &__rotor
    top 0
    left 30%
    height 14%
    width 8%

  &__cockpit
    left 0
    top 14%
    width 54%
    height 70%

  &__tail
    top 30%
    height 20%
    width 46%
    left 54%

  &__fin
    right 2%
    top 10%
    height 20%
    width 10%

  &__stabilizer
    right 2%
    top 30%
    height 10%
    width 10%

  &__skids
    bottom 0
    left 0
    height 6%
    width 70%

  &__wing
    height 6%
    width 22%
    left 28%
    top 60%

  &__launchers
    height 10%
    width 18%
    left 30%
    top 66%

  &__chair
    position absolute
    left 18%
    top 30%
    width 28%
    height 58%

  &__chair-back
    position absolute
    width 25%
    right 0
    top 0
    height 100%

  &__chair-bottom
    position absolute
    height 20%
    right 0
    bottom 0
    width 80%

  &__launcher
    position absolute
    top 0
    left 0
    height 100%
    width 100%

    &--left
      transform translate3d(0, 0, calc(var(--base-size) * -0.425vmin))
    &--right
      transform translate3d(0, 0, calc(var(--base-size) * 0.425vmin))

  &__triblade
    position absolute
    height 100%
    width 100%
    left 50%
    top 50%
    transform translate3d(-25%, -75%, calc(var(--base-size) * 0.07vmin)) scale(1.25)
    border-radius 50%
    overflow hidden
    animation rotate-tri 0.2s infinite linear

    @keyframes rotate-tri
      to
        transform translate3d(-25%, -75%, calc(var(--base-size) * 0.07vmin)) scale(1.25) rotate(-360deg)


    &:after
    &:before
      content ''
      position absolute
      top 50%
      left 50%
      height 100%
      width 15%
      background var(--chair-four)
      transform translate(-50%, -50%)

    &:after
      transform translate(-50%, -50%) rotate(90deg)

  &__blades
    height calc(var(--helicopter-height) * 2)
    width calc(var(--helicopter-height) * 2)
    left 34%
    top 0%
    transform translate(-50%, -50%) rotateX(90deg) translate3d(0, 0, 1px)
    border-radius 50%
    overflow hidden
    animation blades infinite 0.1s linear

    &:after
    &:before
      content ''
      height 100%
      width 10%
      background linear-gradient(var(--chair-one) 0 5%, var(--accent-one) 5% 10%, var(--chair-one) 10% 90%, var(--accent-one) 90% 95%, var(--chair-one) 95% 100%)
      position absolute
      top 50%
      left 50%
      transform translate(-50%, -50%)
    &:after
      transform translate(-50%, -50%) rotate(90deg)


  &__skid
    position absolute
    top 0
    left 0
    height 100%
    width 100%

    &:after
    &:before
      content ''
      position absolute
      left 16%
      width 4%
      bottom 0
      height 400%
      background var(--chair-four)
      transform-origin 50% 100%
      transform rotateX(calc(25 * var(--coefficient, 1deg)))

    &:before
      left 56%

    &--left
      transform translate3d(0, 0, calc(var(--base-size) * 0.4vmin))


    &--right
      --coefficient -1deg
      transform translate3d(0, 0, calc(var(--base-size) * -0.4vmin))

  &__dashboard
    position absolute
    left 2%
    top 50%
    width 16%
    height 38%
    background 'hsla(20, 80%, 50%, %s)' % calc((1 - var(--extruded)) * 0.25)

.cuboid--cockpit
  --thickness calc((var(--base-size) * 0.6) * var(--extruded))

  div
    background var(--helicopter-four)

    &:nth-of-type(1)
      background linear-gradient(90deg, var(--screen-one) 0 50%, var(--helicopter-one) 50% 100%) 50% 50% / 100% 100% no-repeat

    &:nth-of-type(2)
      &:after
        content ''
        position absolute
        top 50%
        left 50%
        height calc(100% - 1px)
        width calc(100% - 1px)
        background hsl(280, 40%, 50%)
        transform translate3d(-50%, -50%, calc(var(--helicopter-width) * -0.27))
    &:nth-of-type(4) //Front
      background transparent
      background linear-gradient(var(--screen-two) 0% 80%, var(--helicopter-one) 80% 100%) 50% 50% / 100% 100% no-repeat

    &:nth-of-type(5) //Right
      background transparent
      background linear-gradient(var(--helicopter-three), var(--helicopter-three)) 100% 50% / 50% 100% no-repeat,
                linear-gradient(var(--screen-three) 0% 80%, var(--helicopter-three) 80% 100%) 0% 50% / 50% 100% no-repeat

      &:after
        content ''
        position absolute
        top 50%
        height 50%
        width 25%
        right 15%
        transform translate3d(0%, -60%, 1px) scale(0.75)
        background url(https://assets.codepen.io/605876/avatar.png)
        background-size contain
        background-repeat no-repeat
        filter saturate(0.5)

    &:nth-of-type(6) //Left
      background transparent
      background linear-gradient(var(--helicopter-two), var(--helicopter-two)) 0 50% / 50% 100% no-repeat,
                linear-gradient(var(--screen-four) 0% 80%, var(--helicopter-two) 80% 100%) 100% 50% / 50% 100% no-repeat
      &:after
        content ''
        position absolute
        top 50%
        height 50%
        width 25%
        left 15%
        transform translate3d(0%, -60%, 1px) scale(0.75)
        background url(https://assets.codepen.io/605876/avatar.png)
        background-size contain
        background-repeat no-repeat
        filter saturate(0.5)


.cuboid--tail
  --thickness calc((var(--base-size) * 0.4) * var(--extruded))
  --clip polygon(0 0, 100% 40%, 100% 60%, 0 100%)
  div
    background var(--accent-four)

    &:nth-of-type(1)
      background var(--accent-one)
      -webkit-clip-path var(--clip)
      clip-path var(--clip)

    &:nth-of-type(2)
      background var(--accent-one)
      background linear-gradient(90deg,transparent 0 40%, var(--accent-four) 40% 60%, transparent 60% 100%)
    &:nth-of-type(3)
      background var(--accent-two)
      -webkit-clip-path var(--clip)
      clip-path var(--clip)
    &:nth-of-type(4)
      background var(--accent-three)
    &:nth-of-type(5)
      background transparent
      &:after
        content ''
        position absolute
        top 0
        left 0
        height 100%
        width 100%
        background var(--accent-three)
        transform-origin 0 50%
        transform rotateY(10deg)
    &:nth-of-type(6)
      background transparent
      &:after
        content ''
        position absolute
        top 0
        left 0
        height 100%
        width 100%
        background var(--accent-three)
        transform-origin 100% 50%
        transform rotateY(-10deg)

.cuboid--stabilizer
  --thickness calc((var(--base-size) * 0.4) * var(--extruded))

  div
    background var(--helicopter-four)

    &:nth-of-type(1)
      background var(--helicopter-one)
    &:nth-of-type(3)
      background var(--helicopter-two)
    &:nth-of-type(4)
      background var(--helicopter-three)

.cuboid--fin
  --thickness calc((var(--base-size) * 0.1) * var(--extruded))

  div
    background var(--helicopter-four)

    &:nth-of-type(1) //TOP
      background linear-gradient(90deg, transparent 0 50%, var(--helicopter-one) 50% 100%)
    &:nth-of-type(3)
      background var(--helicopter-two)
    &:nth-of-type(4) //FRONT
      background transparent
      &:after
        content ''
        position absolute
        bottom 0
        left 0
        background var(--helicopter-two)
        height 110%
        width 100%
        transform-origin 50% 100%
        transform rotateX(-24deg)
    &:nth-of-type(5)
      background var(--helicopter-three)
      --clip polygon(0 100%, 50% 0, 100% 0, 100% 100%)
      -webkit-clip-path var(--clip)
      clip-path var(--clip)
    &:nth-of-type(6)
      background var(--helicopter-three)
      --clip polygon(0 0%, 50% 0, 100% 100%, 0 100%)
      -webkit-clip-path var(--clip)
      clip-path var(--clip)

.cuboid--skid
  --thickness calc((var(--base-size) * 0.06) * var(--extruded))

  div
    background var(--chair-four)

    &:nth-of-type(1)
      background var(--chair-one)
    &:nth-of-type(3)
      background var(--chair-two)
    &:nth-of-type(4)
      background var(--chair-three)

.cuboid--dashboard
  --thickness calc((var(--base-size) * 0.52) * var(--extruded))

  div
    background var(--dash-four)

    &:nth-of-type(1)
      background var(--dash-one)
    &:nth-of-type(3)
      background var(--dash-two)
    &:nth-of-type(4)
      background var(--dash-three)

.cuboid--chair
  --thickness calc((var(--base-size) * 0.4) * var(--extruded))

  div
    background var(--chair-four)

    &:nth-of-type(1)
      background var(--chair-one)
    &:nth-of-type(3)
      background var(--chair-two)
    &:nth-of-type(4)
      background var(--chair-three)

.cuboid--wing
  --thickness calc((var(--base-size) * 1.1) * var(--extruded))

  div
    background var(--accent-four)

    &:nth-of-type(1)
      background var(--accent-one)
    &:nth-of-type(3)
      background var(--accent-two)
    &:nth-of-type(4)
      background var(--accent-three)

.cuboid--rotor
  --thickness calc((var(--base-size) * 0.14) * var(--extruded))

  div
    background var(--dash-four)

    &:nth-of-type(1)
      background var(--dash-one)
    &:nth-of-type(3)
      background var(--dash-two)
    &:nth-of-type(4)
      background var(--dash-three)

.cuboid--launcher
  --thickness calc((var(--base-size) * 0.08) * var(--extruded))

  div
    background var(--rocket-four)

    &:nth-of-type(1)
      background var(--rocket-one)
    &:nth-of-type(3)
      background var(--rocket-two)
    &:nth-of-type(4)
      background var(--rocket-three)

.cuboid--light
  --thickness calc(var(--base-size) * 0.035)
  animation flash calc((1 - var(--on, 0)) * (var(--speed, 1) * 1s)) infinite

  div
    background 'hsla(%s, 90%, 50%, %s)' % (var(--hue, 10) var(--alpha, 0))

@keyframes blades
  to
    transform translate(-50%, -50%) rotateX(90deg) translate3d(0, 0, 1px) rotate(-360deg)

.helicopter__ammo
  height 50%
  width 30%
  position absolute
  top 50%
  left 0
  transform translate(0, -50%)

.cuboid--ammo
  --thickness calc(var(--base-size) * 0.05)

  div
    background 'hsl(%s, 80%, 80%)' % var(--hue)
View Compiled
import gsap from 'https://cdn.skypack.dev/gsap'
import { GUI } from 'https://cdn.skypack.dev/dat.gui'

const CONTROLLER = new GUI()
const CONFIG = {
  'rotate-x': -360,
  'rotate-y': -360,
  extrude: false
}
const UPDATE = () => {
  Object.entries(CONFIG).forEach(([key, value]) => {
    document.documentElement.style.setProperty(`--${key}`, value)
  })
  document.documentElement.style.setProperty('--extruded', CONFIG.extrude ? 1 : 0)
}
const PLANE_FOLDER = CONTROLLER.addFolder('Plane')
PLANE_FOLDER.add(CONFIG, 'rotate-x', -360, 360, 1)
  .name('Rotate X (deg)')
  .onChange(UPDATE)
PLANE_FOLDER.add(CONFIG, 'rotate-y', -360, 360, 1)
  .name('Rotate Y (deg)')
  .onChange(UPDATE)
CONTROLLER.add(CONFIG, 'extrude')
  .name('Extrude?')
  .onChange(UPDATE)
UPDATE()

let FIRING = false

const LEFT_LAUNCHER = document.querySelector('.helicopter__launcher--left')
const RIGHT_LAUNCHER = document.querySelector('.helicopter__launcher--right')

gsap.ticker.add((time, deltaTime, frame) => {
  if (FIRING) {
    const AMMO = document.createElement('div')
    AMMO.innerHTML = `
      <div class="cuboid cuboid--ammo">
        <div class="cuboid__side"></div>
        <div class="cuboid__side"></div>
        <div class="cuboid__side"></div>
        <div class="cuboid__side"></div>
        <div class="cuboid__side"></div>
        <div class="cuboid__side"></div>
      </div>
    `
    AMMO.className = 'helicopter__ammo'
    AMMO.style.setProperty('--hue', Math.random() * 360)
    if (frame % 2 === 0) LEFT_LAUNCHER.appendChild(AMMO)
    else RIGHT_LAUNCHER.appendChild(AMMO)

    gsap.to(AMMO, {
      xPercent: () => gsap.utils.random(-3000, -2000),
      // duration: 0.2,
      onComplete: () => AMMO.remove(),
    })
  }
})

gsap.ticker.fps(24)

document.addEventListener('pointerdown', () => {
  FIRING = true
})
document.addEventListener('pointerup', () => {
  FIRING = false
})
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.