Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hatemhosny/9d449889a1a196020d5b220d104fcdf9 to your computer and use it in GitHub Desktop.
Save hatemhosny/9d449889a1a196020d5b220d104fcdf9 to your computer and use it in GitHub Desktop.
3D CSS Plane 😎 (Tap to Toggle + Mouse Move Parallax)
mixin cuboid()
.cuboid(class!=attributes.class)
- let s = 0
while s < 6
.cuboid__side
- s++
.scene
.cloud.cloud--one
.cloud__shift
.cloud__body
div
+cuboid()(class="cuboid--cloud")
div
+cuboid()(class="cuboid--cloud")
div
+cuboid()(class="cuboid--cloud")
.cloud.cloud--two
.cloud__shift
.cloud__body
div
+cuboid()(class="cuboid--cloud")
div
+cuboid()(class="cuboid--cloud")
div
+cuboid()(class="cuboid--cloud")
.cloud.cloud--three
.cloud__shift
.cloud__body
div
+cuboid()(class="cuboid--cloud")
div
+cuboid()(class="cuboid--cloud")
div
+cuboid()(class="cuboid--cloud")
.plane__floater
.plane__looper
.plane
.plane__wheels
.plane__axle
+cuboid()(class="cuboid--axle")
.plane__wheel.plane__wheel--left
+cuboid()(class="cuboid--wheel-left")
.plane__wheel.plane__wheel--right
+cuboid()(class="cuboid--wheel-right")
.plane__body
+cuboid()(class="cuboid--body")
.plane__nose
+cuboid()(class="cuboid--nose")
.plane__propellor
.propellor
.plane__screen
+cuboid()(class="cuboid--screen")
.plane__wings.wings
.wings__top
+cuboid()(class="cuboid--wings-top")
.wings__ghost
+cuboid()(class="cuboid--wings-ghost")
.wings__bottom
+cuboid()(class="cuboid--wings-bottom")
.wings__strobe.wings__strobe--left
+cuboid()(class="cuboid--strobe")
.wings__strobe.wings__strobe--right
+cuboid()(class="cuboid--strobe")
.plane__tail
+cuboid()(class="cuboid--tail")
.plane__stabilizer.plane__stabilizer--horizontal
+cuboid()(class="cuboid--horizontal-stabilizer")
.plane__stabilizer.plane__stabilizer--vertical
+cuboid()(class="cuboid--vertical-stabilizer")
.plane__beacon
+cuboid()(class="cuboid--beacon")
import gsap from 'https://cdn.skypack.dev/gsap'
const BOUNDS = 50
document.addEventListener('pointermove', ({ x, y }) => {
const newX = gsap.utils.mapRange(0, window.innerWidth, -BOUNDS, BOUNDS, x)
const newY = gsap.utils.mapRange(0, window.innerHeight, BOUNDS, -BOUNDS, y)
gsap.set(document.documentElement, {
'--rotate-x': newY,
'--rotate-y': newX,
})
})
let CHECKED = false
document.addEventListener('pointerdown', e => {
CHECKED = !CHECKED
document.documentElement.style.setProperty('--dark', CHECKED ? 1 : 0)
})
.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
body
min-height 100vh
display grid
place-items center
background var(--bg)
overflow hidden
:root
--dark 0
--base-size 20
--plane-height calc(var(--base-size) * 1vmin)
--plane-width calc(var(--plane-height) * 1.6)
--white-one 'hsl(0, 0%, %s)' % calc((90 - (var(--dark) * 30)) * 1%)
--white-two 'hsl(0, 0%, %s)' % calc((85 - (var(--dark) * 30)) * 1%)
--white-three 'hsl(0, 0%, %s)' % calc((80 - (var(--dark) * 30)) * 1%)
--white-four 'hsl(0, 0%, %s)' % calc((75 - (var(--dark) * 30)) * 1%)
--white-five 'hsl(0, 0%, %s)' % calc((70 - (var(--dark) * 30)) * 1%)
--accent-hue 10
--accent-one 'hsl(%s, 80%, %s)' % (var(--accent-hue) calc((60 - (var(--dark) * 20)) * 1%))
--accent-two 'hsl(%s, 80%, %s)' % (var(--accent-hue) calc((55 - (var(--dark) * 20)) * 1%))
--accent-three 'hsl(%s, 80%, %s)' % (var(--accent-hue) calc((50 - (var(--dark) * 20)) * 1%))
--accent-four 'hsl(%s, 80%, %s)' % (var(--accent-hue) calc((45 - (var(--dark) * 20)) * 1%))
--accent-five 'hsl(%s, 80%, %s)' % (var(--accent-hue) calc((40 - (var(--dark) * 20)) * 1%))
--screen 'hsla(210, 80%, %s, 0.25)' % calc((70 - (var(--dark) * 20)) * 1%)
--metal-one 'hsl(0, 0%, %s)' % calc((60 - (var(--dark) * 20)) * 1%)
--metal-two 'hsl(0, 0%, %s)' % calc((50 - (var(--dark) * 20)) * 1%)
--metal-three 'hsl(0, 0%, %s)' % calc((40 - (var(--dark) * 20)) * 1%)
--wheel-one hsl(0, 0%, 10%)
--wheel-two hsl(0, 0%, 5%)
--wheel-three hsl(0, 0%, 0%)
--wheel-hub 'hsl(0, 0%, %s)' % calc((98 - (var(--dark) * 20)) * 1%)
--bg 'hsl(210, 80%, %s)' % calc((90 - (var(--dark) * 76)) * 1%)
--night hsl(210, 80%, 16%)
--cloud-one 'hsl(0, 0%, %s)' % calc((98 - (var(--dark) * 35)) * 1%)
--cloud-two 'hsl(0, 0%, %s)' % calc((94 - (var(--dark) * 35)) * 1%)
--cloud-three 'hsl(0, 0%, %s)' % calc((90 - (var(--dark) * 35)) * 1%)
--cloud-four 'hsl(0, 0%, %s)' % calc((86 - (var(--dark) * 35)) * 1%)
--cloud-five 'hsl(0, 0%, %s)' % calc((82 - (var(--dark) * 35)) * 1%)
--cloud-six 'hsl(0, 0%, %s)' % calc((78 - (var(--dark) * 35)) * 1%)
.scene
transform translate(-50%, -50%)
position fixed
top 50%
left 50%
transform translate3d(-50%, -50%, 100vmin) rotateX(-24deg) rotateY(44deg) rotateX(calc(var(--rotate-x, 0) * 1deg)) rotateY(calc(var(--rotate-y, 0) * 1deg))
.plane
height var(--plane-height)
width var(--plane-width)
// background hsla(210, 80%, 80%, 0.5)
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
animation roll 10s infinite ease-out alternate
&__floater
position absolute
width var(--plane-width)
height var(--plane-width)
transform translate(-50%, -50%)
top 50%
left 50%
animation float 2s infinite ease-in-out
&__looper
position absolute
width var(--plane-width)
height var(--plane-width)
transform translate(-50%, -50%)
top 50%
left 50%
transform-origin 50% 0
animation loop 10s infinite ease-in-out
*
position absolute
&__body
height 40%
width 36%
bottom 20%
left 10%
&__wheels
bottom 0
width calc(var(--plane-height) * 0.2)
left 32%
transform translate(-50%, 0)
height 20%
&__axle
height 50%
width 50%
top 50%
left 50%
transform translate(-50%, -50%)
&__wheel
height 100%
width 100%
top 0
left 0
&__wings
height 70%
width 40%
bottom 19%
left 12%
&__tail
height 40%
width 54%
bottom 20%
left 46%
&__nose
height 30%
width 10%
bottom 25%
&__stabilizer--horizontal
height 9%
width 16%
right 1%
bottom 50%
&__screen
bottom 60%
left 30%
width 6%
height 14%
&__propellor
height calc(var(--base-size) * 0.75vmin)
width calc(var(--base-size) * 0.75vmin)
left -1%
bottom 40%
transform translate(-50%, 50%) rotateY(-90deg)
&:after
content ''
position absolute
top 50%
left 50%
transform translate3d(-50%, -50%, 2px)
height 16%
width 16%
border-radius 50%
background var(--white-one)
&__stabilizer--vertical
height 20%
width 20%
right 0
bottom 60%
&__beacon
right 1%
bottom 80%
height 2%
width 2%
&__wheel--left
transform translate3d(0, 0, calc(var(--base-size) * 0.3vmin))
&__wheel--right
transform translate3d(0, 0, calc(var(--base-size) * -0.3vmin))
.propellor
height 100%
width 100%
animation spin 0.35s infinite linear
&:after
&:before
content ''
height 100%
width 10%
position absolute
top 50%
left 50%
background linear-gradient(transparent 0 5%, var(--accent-two) 5% 15%, transparent 15% 85%, var(--accent-two) 85% 95%, transparent 95%), hsl(0, 0%, 0%)
transform translate(-50%, -50%) rotate(calc(var(--r, 45) * 1deg))
&:after
--r -45
.wings
&__ghost
height 80%
width 80%
left 50%
bottom 10%
transform translate(-50%, 0)
&__top
top 0
height 10%
width 100%
left 0
&__bottom
bottom 0
height 10%
width 100%
left 0
&__strobe
bottom 10%
height 4%
width 4%
left 50%
&--left
transform translate3d(-50%, 0, calc(var(--base-size) * 1vmin))
&--right
transform translate3d(-50%, 0, calc(var(--base-size) * -1vmin))
.cloud
height 10vmin
width 15vmin
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
&__shift
height 100%
width 100%
animation pan calc(var(--speed, 5) * 1s) calc(var(--delay, 5) * -1s) infinite ease-in-out both
&__body
height 100%
width 100%
animation scale calc(var(--speed, 5) * 1s) calc(var(--delay, 5) * -1s) infinite linear
&__body > div
position absolute
&:nth-of-type(1)
bottom 0
left 25%
width 60%
height 90%
--thickness calc(var(--base-size) * 0.2)
&:nth-of-type(2)
bottom 0
left 0
width 50%
height 60%
--thickness calc(var(--base-size) * 0.3)
&:nth-of-type(3)
bottom 0
right 0%
width 60%
height 40%
--thickness calc(var(--base-size) * 0.4)
&--one
--speed 2
--delay 3
transform translate(-50%, -50%) translate3d(-40vmin, 20vmin, 26vmin)
&--two
--speed 4
--delay 1
transform translate(-50%, -50%) translate3d(30vmin, -15vmin, -34vmin)
&--three
--speed 6
--delay 2
transform translate(-50%, -50%) translate3d(50vmin, 35vmin, -14vmin)
.cuboid
&--body
--thickness calc(var(--base-size) * 0.4)
div
background var(--white-two)
&:nth-of-type(1)
background var(--white-one)
&:nth-of-type(2)
background var(--white-two)
&:nth-of-type(3)
background var(--white-three)
&:nth-of-type(4)
background var(--white-four)
&:nth-of-type(5):after
&:nth-of-type(6):after
content ''
position absolute
top 50%
left 50%
height calc(var(--base-size) * 0.25vmin)
width calc(var(--base-size) * 0.25vmin)
background-image url("https://assets.codepen.io/605876/avatar.png")
background-size cover
filter saturate(0.65)
transform translate3d(-50%, -50%, 1px)
&--screen
--thickness calc(var(--base-size) * 0.26)
div
background var(--screen)
&--tail
--thickness calc(var(--base-size) * 0.3)
div
background var(--white-two)
&:nth-of-type(1)
background var(--white-one)
&:after
content ''
position absolute
height 74%
width 50%
background var(--metal-three)
top 50%
right 50%
transform translate3d(-50%, -50%, 1px)
&:nth-of-type(2)
background linear-gradient(var(--white-two) 0 30%, transparent 30%)
&:nth-of-type(3)
background linear-gradient(90deg, var(--white-two) 0 20%, transparent 20%)
&:after
content ''
position absolute
background var(--white-four)
top 0%
left 20%
height 100%
width 87%
transform-origin 0 50%
transform rotateY(-22deg)
&:nth-of-type(5)
background transparent
overflow hidden
&:after
content ''
position absolute
bottom 70%
height 100%
width 100%
background var(--white-two)
transform-origin 100% 100%
transform rotate(-22deg) scale(2) translate(10%, 0)
&:nth-of-type(6)
background transparent
overflow hidden
&:after
content ''
position absolute
bottom 70%
height 100%
width 100%
background var(--white-two)
transform-origin 0% 100%
transform rotate(22deg) scale(2) translate(-10%, 0)
&--nose
--thickness calc(var(--base-size) * 0.3)
div
background var(--metal-three)
&:nth-of-type(1)
background var(--metal-one)
&:nth-of-type(2)
background var(--metal-two)
&:nth-of-type(3)
background var(--metal-one)
&--wings-ghost
&--wings-top
&--wings-bottom
--thickness calc(var(--base-size) * 2.2)
div
background var(--accent-one)
&:nth-of-type(1)
background var(--accent-two)
&:nth-of-type(2)
&:nth-of-type(5)
background var(--accent-three)
&:nth-of-type(4)
background var(--accent-four)
&:nth-of-type(3)
background var(--accent-five)
&--wings-ghost
div
&:nth-of-type(3)
&:nth-of-type(5)
&:nth-of-type(6)
&:nth-of-type(1)
background transparent
&:nth-of-type(2)
&:nth-of-type(4)
background linear-gradient(90deg, transparent 0 5%, var(--metal-one) 5% 7%, transparent 7% 33%, var(--metal-one) 33% 35%, transparent 35% 65%, var(--metal-one) 65% 67%, transparent 67% 93%, var(--metal-one) 93% 95%, transparent 95%)
&--axle
--thickness calc(var(--base-size) * 0.5)
div
background var(--metal-two)
&:nth-of-type(3)
background var(--metal-three)
&:nth-of-type(2)
&:nth-of-type(1)
background var(--metal-one)
&:nth-of-type(6)
background var(--metal-one)
&--horizontal-stabilizer
--thickness calc(var(--base-size) * 0.65)
div
background var(--accent-one)
&:nth-of-type(1)
background var(--accent-two)
&:nth-of-type(2)
&:nth-of-type(5)
background var(--accent-three)
&:nth-of-type(3)
&:nth-of-type(4)
background var(--accent-four)
&--vertical-stabilizer
--thickness calc(var(--base-size) * 0.2)
div
background var(--accent-one)
&:nth-of-type(1)
background linear-gradient(270deg, var(--accent-two) 0 30%, transparent 30%)
&:nth-of-type(4)
background transparent
&:after
content ''
background var(--accent-four)
height 150%
bottom 0
left 0
position absolute
width 100%
transform-origin 50% 100%
transform rotateX(-48deg)
&:nth-of-type(5)
background transparent
overflow hidden
&:after
content ''
position absolute
top 100%
transform-origin 0 0
transform rotate(-42deg)
background var(--accent-three)
height 150%
width 160%
&:nth-of-type(6)
background transparent
overflow hidden
&:after
content ''
position absolute
top 100%
right 0
transform-origin 100% 0
transform rotate(42deg)
background var(--accent-three)
height 150%
width 160%
&--wheel-left
&--wheel-right
--thickness calc(var(--base-size) * 0.1)
div
background var(--wheel-one)
&:nth-of-type(1)
&:nth-of-type(2)
&:nth-of-type(4)
background var(--wheel-two)
&:nth-of-type(3)
background var(--wheel-three)
&:nth-of-type(5)
&:nth-of-type(6)
&:after
content ''
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
height 40%
width 40%
background var(--wheel-hub)
&--cloud
div
&:nth-of-type(1)
background var(--cloud-one)
&:nth-of-type(2)
background var(--cloud-two)
&:nth-of-type(3)
background var(--cloud-three)
&:nth-of-type(4)
background var(--cloud-four)
&:nth-of-type(5)
background var(--cloud-five)
&:nth-of-type(6)
background var(--cloud-six)
&--beacon
--thickness calc(var(--base-size) * 0.02)
animation flash calc(var(--dark) * 1s) infinite
div
background 'hsla(0, 90%, 50%, %s)' % var(--alpha)
&--strobe
--thickness calc(var(--base-size) * 0.02)
animation flash calc(var(--dark) * 0.5s) infinite
div
background 'hsla(0, 90%, 98%, %s)' % var(--alpha)
@keyframes flash
50%
--alpha 1
@keyframes spin
to
transform rotate(360deg)
@keyframes float
50%
transform translate(-50%, -40%)
@keyframes loop
0%, 40%
transform translate(-50%, -50%)
50%, 100%
transform translate(-50%, -50%) rotateZ(360deg)
@keyframes roll
0%, 85%
transform translate(-50%, -50%)
90%, 100%
transform translate(-50%, -50%) rotateX(-360deg)
@keyframes nightshift
0%, 50%
background var(--bg)
75%, 100%
background var(--night)
@keyframes scale
0%, 5%, 95%, 100%
transform scale(0)
10%, 90%
transform scale(1)
@keyframes pan
0%
transform translate(-1000%, 0)
100%
transform translate(1000%, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment