$l: 5em; $d: $l*sqrt(2); $b: 1.75*$l; @function xor($a, $b) { @return if($a*$b == 0 and $a + $b == 1, 1, 0); } @mixin paint($c, $dir) { $dtxt: if($dir == 0, right, left); background: linear-gradient(to $dtxt bottom, transparent 49%, currentColor 50%); color: $c; } @mixin cube($ixo, $izo, $state: 'final') { $f: if($state == 'final', .25, .5); transform: translate3d( $ixo*$b - (1 - $izo)*$l*$f, -.5*$l, (1 + $izo)*$l*$f ) if( $izo < 0, rotateY(90deg), rotate(-90deg) ) rotateX($izo*90deg); } @mixin pyramid($k, $izo, $state: 'final') { $f: if($state == 'final', 1, 1.5); transform: translate3d(0, 0, 2*$izo*$b) rotateY(($k - .5)*90deg) translate(-.5*$l*sqrt(2)*$f) rotateY(-45deg); } html, body { height: 100%; } body { overflow: hidden; margin: 0; perspective: 40em; background: #191919; } .assembly { &, * { position: absolute; bottom: 50%; left: 50%; transform-style: preserve-3d; } transform: translateY(.5*$l) rotateX(-22.5deg) rotateY(30deg); } .pyramid { @for $i from 0 to 12 { $j1: $i%3; $k1: floor($i/3); $ixo: ($k1 - 1.5); $izo: ($j1 - 1); $lightb: ($k1 + $j1 + 1)*8%; $lightl1: ($k1 + 5)*8%; &:nth-child(#{$i + 1}) { transform: translate3d($ixo*$b, 0, $izo*$b); animation: pos#{$i + 1} 4s linear infinite; @if $izo != 0 { /* 2 classes because specificity */ .pyramid__face.pyramid__face--base { animation-name: baseshade#{$i + 1}; } } .pyramid__face--lateral { @for $li from 0 to 4 { $lj: $li%2; $lk: floor($li/2); $xor: xor($lj, $lk); $lightl2: ($j1*4 + $k1 - $li + 5)*5%; &:nth-child(#{$li + 1}) { color: hsl(0, 0%, if($xor == 1, $lightl2, $lightl1)); } } } @at-root { @keyframes pos#{$i + 1} { 0%, 5%, 45%, 55%, 95%, 100% { transform: translate3d($ixo*$b, 0, $izo*$b); } @if $izo != 0 { 15%, 35% { @include cube($ixo, $izo, 'mid'); } 20%, 30% { @include cube($ixo, $izo); } } 65%, 85% { @include pyramid($k1, $izo, 'mid'); } 70%, 80% { @include pyramid($k1, $izo); } } @if $izo != 0 { @keyframes baseshade#{$i + 1} { 20%, 30% { background: hsl(0, 0%, $lightb); } } } } } } &__face { margin: 0 (-.5*$l); width: $l; height: $l; backface-visibility: hidden; &--lateral { transform-origin: 50% 100%; @for $i from 0 to 4 { $j: $i%2; $k: floor($i/2); $xor: xor($j, $k); &:nth-child(#{$i + 1}) { @if $xor == 1 { height: $d; } @else { animation: inherit; animation-name: no-flick; } transform: rotateY((1 - $i)*90deg) translateZ(.5*$l) if($xor == 1, rotateX(45deg), ()); @include paint( darken(silver, random(50)), $k ); } } } &--base { transform: rotateX(-90deg) translateZ(.5*$l); background: #000; .pyramid:not(:nth-child(3n + 2)) & { animation: inherit; } } } } @keyframes no-flick { 0%, 69.99%, 80.01%, 100% { opacity: .999; } 70%, 80% { opacity: .001; } }