3D scan art with pure CSS.
Inspiration https://twitter.com/TatsuyaBot/status/1119824771733049344
A Pen by Gavin Hall on CodePen.
.container | |
- for (i = 0; i < 400; i++) | |
.trigger | |
.monitor | |
.camera.o-x | |
.camera.o-y | |
.camera.o-z | |
.vr | |
- for (i = 0; i < 20; i++) | |
.vr_layer | |
.vr_layer_item |
3D scan art with pure CSS.
Inspiration https://twitter.com/TatsuyaBot/status/1119824771733049344
A Pen by Gavin Hall on CodePen.
$size: 350px; | |
$layer: 20; | |
body { | |
background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%); | |
height: 100vh; | |
overflow: hidden; | |
display: flex; | |
font-family: 'Anton', sans-serif; | |
justify-content: center; | |
align-items: center; | |
perspective: 1000px; | |
} | |
.container { | |
position: relative; | |
display: grid; | |
grid-template-rows: repeat(20, 5vh); | |
grid-template-columns: repeat(20, 5vw); | |
transform-style: preserve-3d; | |
} | |
.monitor { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
pointer-events: none; | |
transform-style: preserve-3d; | |
} | |
.trigger { | |
&:active ~ .monitor { | |
.vr_layer_item { | |
width: 40%; | |
height: 40%; | |
border-radius: 5px; | |
} | |
} | |
@for $i from 1 through 20 { | |
@for $j from 1 through 20 { | |
$key: ($i - 1) * 20 + $j; | |
&:nth-child(#{$key}) { | |
&:hover ~ .monitor { | |
.camera { | |
&.o-y { | |
transform: rotateY(($j - 10) * -8deg); | |
} | |
&.o-x { | |
transform: rotateX(($i - 10) * 8deg); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
.camera { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
transform-style: preserve-3d; | |
transition: 500ms; | |
&.o-y { | |
transform: rotateY(-30deg); | |
} | |
} | |
.vr { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
width: $size; | |
height: $size; | |
transform: translate(-50%, -50%); | |
transform-style: preserve-3d; | |
&_layer { | |
position: absolute; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
width: 100%; | |
height: 100%; | |
border: 1px solid rgba(#fff, 0.2); | |
background: rgba(#09f, 0.006); | |
border-radius: 10px; | |
transform: preserve-3d; | |
@for $i from 1 through $layer { | |
&:nth-child(#{$i}) { | |
transform: translateZ($i * $size / $layer - $size / 2); | |
} | |
&:nth-child(#{$i}) &_item { | |
animation-delay: $i * -210ms; | |
} | |
} | |
&_item { | |
width: 70%; | |
height: 70%; | |
border: 3px solid #fff; | |
border-radius: 100%; | |
background: rgba(#000, 0.05); | |
animation: sphere 3000ms cubic-bezier(0.215, 0.610, 0.355, 1.000) alternate infinite, color 5000ms linear alternate infinite; | |
transition: 500ms; | |
} | |
} | |
} | |
@keyframes sphere { | |
0% { | |
transform: scale(0) rotateZ(45deg); | |
} | |
50% { | |
transform: scale(0) rotateZ(45deg); | |
} | |
100% { | |
transform: scale(1) rotateZ(45deg); | |
} | |
} | |
@keyframes color { | |
0% { | |
border-color: #f55; | |
} | |
50% { | |
border-color: #55f; | |
} | |
100% { | |
border-color: #5f5; | |
} | |
} |
<link href="https://fonts.googleapis.com/css?family=Anton" rel="stylesheet" /> |