- var blocks = 94;
.container
- var d = 6;
- while (d--) {
.digit
- }
.surface
- for (var b = 1;b <= blocks;++b) {
div(class="block b" + b)
.block-outer
.block-inner
.bottom
.front
.left
.right
- }
View Compiled
// container and surface
$sqSize: 20px;
$xSpaces: 27;
$ySpaces: 1;
$zSpaces: 5;
$contW: ($sqSize * $xSpaces) * 1.1;
$contH: $sqSize * $zSpaces * 2;
$xAngle: 105deg;
$zAngle: 0deg;
$prsp: 800px;
// colors
$tr: transparent;
$bl: #000;
$gry: #444;
$grn: #74d447;
// block properties
$w: 0.8; // block width
$g: (1 - $w) / 2; // half gap between blocks
// animation, transitions
$dur: 2s;
$tf: cubic-bezier(.4,.1,.6,.9);
$trans: 0.3s;
$bounce: 10px;
$tilt: 7deg;
// * Block placement *
// parameters: x-pos,y-pos,z-pos, width,depth,height, color
$blocks:
// * Hour *
// tens
(1+$g,1+$g,5+$g, $w,$w,$w, $grn)
(2+$g,1+$g,5+$g, $w,$w,$w, $grn)
(3+$g,1+$g,5+$g, $w,$w,$w, $grn)
(1+$g,1+$g,4+$g, $w,$w,$w, $grn)
(2+$g,1+$g,4+$g, $w,$w,$w, $grn)
(3+$g,1+$g,4+$g, $w,$w,$w, $grn)
(1+$g,1+$g,3+$g, $w,$w,$w, $grn)
(2+$g,1+$g,3+$g, $w,$w,$w, $grn)
(3+$g,1+$g,3+$g, $w,$w,$w, $grn)
(1+$g,1+$g,2+$g, $w,$w,$w, $grn)
(2+$g,1+$g,2+$g, $w,$w,$w, $grn)
(3+$g,1+$g,2+$g, $w,$w,$w, $grn)
(1+$g,1+$g,1+$g, $w,$w,$w, $grn)
(2+$g,1+$g,1+$g, $w,$w,$w, $grn)
(3+$g,1+$g,1+$g, $w,$w,$w, $grn)
// ones
(5+$g,1+$g,5+$g, $w,$w,$w, $grn)
(6+$g,1+$g,5+$g, $w,$w,$w, $grn)
(7+$g,1+$g,5+$g, $w,$w,$w, $grn)
(5+$g,1+$g,4+$g, $w,$w,$w, $grn)
(6+$g,1+$g,4+$g, $w,$w,$w, $grn)
(7+$g,1+$g,4+$g, $w,$w,$w, $grn)
(5+$g,1+$g,3+$g, $w,$w,$w, $grn)
(6+$g,1+$g,3+$g, $w,$w,$w, $grn)
(7+$g,1+$g,3+$g, $w,$w,$w, $grn)
(5+$g,1+$g,2+$g, $w,$w,$w, $grn)
(6+$g,1+$g,2+$g, $w,$w,$w, $grn)
(7+$g,1+$g,2+$g, $w,$w,$w, $grn)
(5+$g,1+$g,1+$g, $w,$w,$w, $grn)
(6+$g,1+$g,1+$g, $w,$w,$w, $grn)
(7+$g,1+$g,1+$g, $w,$w,$w, $grn)
// colon
(9+$g,1+$g,4+$g, $w,$w,$w, $grn)
(9+$g,1+$g,2+$g, $w,$w,$w, $grn)
// * Minute *
// tens
(11+$g,1+$g,5+$g, $w,$w,$w, $grn)
(12+$g,1+$g,5+$g, $w,$w,$w, $grn)
(13+$g,1+$g,5+$g, $w,$w,$w, $grn)
(11+$g,1+$g,4+$g, $w,$w,$w, $grn)
(12+$g,1+$g,4+$g, $w,$w,$w, $grn)
(13+$g,1+$g,4+$g, $w,$w,$w, $grn)
(11+$g,1+$g,3+$g, $w,$w,$w, $grn)
(12+$g,1+$g,3+$g, $w,$w,$w, $grn)
(13+$g,1+$g,3+$g, $w,$w,$w, $grn)
(11+$g,1+$g,2+$g, $w,$w,$w, $grn)
(12+$g,1+$g,2+$g, $w,$w,$w, $grn)
(13+$g,1+$g,2+$g, $w,$w,$w, $grn)
(11+$g,1+$g,1+$g, $w,$w,$w, $grn)
(12+$g,1+$g,1+$g, $w,$w,$w, $grn)
(13+$g,1+$g,1+$g, $w,$w,$w, $grn)
// ones
(15+$g,1+$g,5+$g, $w,$w,$w, $grn)
(16+$g,1+$g,5+$g, $w,$w,$w, $grn)
(17+$g,1+$g,5+$g, $w,$w,$w, $grn)
(15+$g,1+$g,4+$g, $w,$w,$w, $grn)
(16+$g,1+$g,4+$g, $w,$w,$w, $grn)
(17+$g,1+$g,4+$g, $w,$w,$w, $grn)
(15+$g,1+$g,3+$g, $w,$w,$w, $grn)
(16+$g,1+$g,3+$g, $w,$w,$w, $grn)
(17+$g,1+$g,3+$g, $w,$w,$w, $grn)
(15+$g,1+$g,2+$g, $w,$w,$w, $grn)
(16+$g,1+$g,2+$g, $w,$w,$w, $grn)
(17+$g,1+$g,2+$g, $w,$w,$w, $grn)
(15+$g,1+$g,1+$g, $w,$w,$w, $grn)
(16+$g,1+$g,1+$g, $w,$w,$w, $grn)
(17+$g,1+$g,1+$g, $w,$w,$w, $grn)
// colon
(19+$g,1+$g,4+$g, $w,$w,$w, $grn)
(19+$g,1+$g,2+$g, $w,$w,$w, $grn)
// * Second *
// tens
(21+$g,1+$g,5+$g, $w,$w,$w, $grn)
(22+$g,1+$g,5+$g, $w,$w,$w, $grn)
(23+$g,1+$g,5+$g, $w,$w,$w, $grn)
(21+$g,1+$g,4+$g, $w,$w,$w, $grn)
(22+$g,1+$g,4+$g, $w,$w,$w, $grn)
(23+$g,1+$g,4+$g, $w,$w,$w, $grn)
(21+$g,1+$g,3+$g, $w,$w,$w, $grn)
(22+$g,1+$g,3+$g, $w,$w,$w, $grn)
(23+$g,1+$g,3+$g, $w,$w,$w, $grn)
(21+$g,1+$g,2+$g, $w,$w,$w, $grn)
(22+$g,1+$g,2+$g, $w,$w,$w, $grn)
(23+$g,1+$g,2+$g, $w,$w,$w, $grn)
(21+$g,1+$g,1+$g, $w,$w,$w, $grn)
(22+$g,1+$g,1+$g, $w,$w,$w, $grn)
(23+$g,1+$g,1+$g, $w,$w,$w, $grn)
// ones
(25+$g,1+$g,5+$g, $w,$w,$w, $grn)
(26+$g,1+$g,5+$g, $w,$w,$w, $grn)
(27+$g,1+$g,5+$g, $w,$w,$w, $grn)
(25+$g,1+$g,4+$g, $w,$w,$w, $grn)
(26+$g,1+$g,4+$g, $w,$w,$w, $grn)
(27+$g,1+$g,4+$g, $w,$w,$w, $grn)
(25+$g,1+$g,3+$g, $w,$w,$w, $grn)
(26+$g,1+$g,3+$g, $w,$w,$w, $grn)
(27+$g,1+$g,3+$g, $w,$w,$w, $grn)
(25+$g,1+$g,2+$g, $w,$w,$w, $grn)
(26+$g,1+$g,2+$g, $w,$w,$w, $grn)
(27+$g,1+$g,2+$g, $w,$w,$w, $grn)
(25+$g,1+$g,1+$g, $w,$w,$w, $grn)
(26+$g,1+$g,1+$g, $w,$w,$w, $grn)
(27+$g,1+$g,1+$g, $w,$w,$w, $grn);
@mixin placeBlock($x, $y, $z, $w, $d, $h, $c) {
display: inherit;
transform: translate3d(
$sqSize*($x - 1),
$sqSize*(-$y - ($d - 1)),
($sqSize*$z) + ($sqSize*($h - 1))
);
.block-inner div {
background-color: $c;
&.top, &.bottom {
width: $sqSize * $w;
height: $sqSize * $d;
}
&.top {
transform: rotateX(-90deg) translateY(-$sqSize*($d - 1));
}
&.bottom {
transform: rotateX(-90deg) translateY(-$sqSize*($d - 1)) translateZ($sqSize*$h);
}
&.front, &.back {
width: $sqSize * $w;
height: $sqSize * $h;
}
&.front {
transform: translateZ($sqSize * ($d - 1));
}
&.left, &.right {
width: $sqSize * $d;
height: $sqSize * $h;
}
&.right {
transform: rotateY(-270deg) translate3d($sqSize, 0, $sqSize*($w - $d));
}
}
}
@mixin moveBlock($x, $y, $z) {
transform: translate3d($sqSize * $x,$sqSize * -$y,$sqSize * $z);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background:
radial-gradient(circle at center,$tr, $bl 95%),
linear-gradient($gry 2px, $tr 0) 0 0 / 20px 20px,
linear-gradient(90deg, $gry 2px, $bl 0) 0 0 / 20px 20px;
height: 100vh;
margin: 0;
overflow: hidden;
}
.container {
animation: bounce $dur $tf infinite;
display: flex;
margin: auto;
overflow: hidden;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: $contW;
height: $contH;
perspective: $prsp;
transform-style: preserve-3d;
}
.surface {
animation: tilt $dur (-$dur*0.75) $tf infinite;
display: block;
width: $sqSize * $xSpaces;
height: $sqSize * $ySpaces;
margin: auto;
transform-style: preserve-3d;
transform: translateY($sqSize * $zSpaces/2) rotateX($xAngle) rotateZ($zAngle);
will-change: transform;
}
.block {
display: none;
transform-style: preserve-3d;
position: absolute;
bottom: 0;
}
.block-inner > div {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
position: absolute;
width: $sqSize;
height: $sqSize;
&.top, &.bottom, &.left, &.right {
&:before {
background-color: #000;
content: "";
width: 100%;
height: 100%;
}
}
&.top, &.bottom {
&:before {
opacity: 0.2;
}
}
&.left, &.right {
&:before {
opacity: 0.4;
}
}
}
.block-outer, .block-inner {
position: relative;
width: $sqSize;
transform-style: preserve-3d;
}
.block-outer {
transition: transform $trans;
}
.block-inner {
transform: rotateX(-90deg) translateZ($sqSize);
}
.back {
transform: translateZ(-$sqSize) rotateY(180deg);
}
.left {
transform-origin: center left;
transform: rotateY(270deg) translateX(-$sqSize);
}
.right {
transform-origin: top right;
}
.top, .bottom {
transform-origin: top center;
}
// * Render blocks *
// one block only
@if length(nth($blocks,1)) == 1 {
.b1 {
@include placeBlock(
nth($blocks, 1),
nth($blocks, 2),
nth($blocks, 3),
nth($blocks, 4),
nth($blocks, 5),
nth($blocks, 6),
nth($blocks, 7)
);
}
}
// more than one block
@else {
@for $b from 1 through length($blocks) {
.b#{$b} {
@include placeBlock(
nth(nth($blocks, $b), 1),
nth(nth($blocks, $b), 2),
nth(nth($blocks, $b), 3),
nth(nth($blocks, $b), 4),
nth(nth($blocks, $b), 5),
nth(nth($blocks, $b), 6),
nth(nth($blocks, $b), 7)
);
}
}
}
// * Digit display *
.digit {
position: absolute;
}
@for $p from 1 through 6 {
$step: 15 * ($p - 1);
// deal with colons
$adj: if($p > 4,4,if($p > 2,2,0));
$step: $step + $adj;
._0:nth-of-type(#{$p}) ~ .surface {
.b#{5 + $step}, .b#{8 + $step}, .b#{11 + $step} {
.block-outer {
@include moveBlock(-1,0,0)
}
}
}
._1:nth-of-type(#{$p}) ~ .surface {
.b#{1 + $step}, .b#{4 + $step}, .b#{7 + $step}, .b#{10 + $step}, .b#{13 + $step} {
.block-outer {
@include moveBlock(2,0,0)
}
}
.b#{2 + $step}, .b#{5 + $step}, .b#{8 + $step}, .b#{11 + $step}, .b#{14 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
}
._2:nth-of-type(#{$p}) ~ .surface {
.b#{4 + $step} {
.block-outer {
@include moveBlock(2,0,0)
}
}
.b#{5 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
.b#{11 + $step} {
.block-outer {
@include moveBlock(-1,0,0)
}
}
.b#{12 + $step} {
.block-outer {
@include moveBlock(-2,0,0)
}
}
}
@if $p > 1 {
._3:nth-of-type(#{$p}) ~ .surface {
.b#{4 + $step}, .b#{10 + $step} {
.block-outer {
@include moveBlock(2,0,0)
}
}
.b#{5 + $step}, .b#{11 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
}
._4:nth-of-type(#{$p}) ~ .surface {
.b#{2 + $step}, .b#{5 + $step} {
.block-outer {
@include moveBlock(-1,0,0)
}
}
.b#{10 + $step}, .b#{13 + $step} {
.block-outer {
@include moveBlock(2,0,0)
}
}
.b#{11 + $step}, .b#{14 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
}
._5:nth-of-type(#{$p}) ~ .surface {
.b#{5 + $step} {
.block-outer {
@include moveBlock(-1,0,0)
}
}
.b#{6 + $step} {
.block-outer {
@include moveBlock(-2,0,0)
}
}
.b#{10 + $step} {
.block-outer {
@include moveBlock(2,0,0)
}
}
.b#{11 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
}
@if $p % 2 == 0 {
._6:nth-of-type(#{$p}) ~ .surface {
.b#{5 + $step} {
.block-outer {
@include moveBlock(-1,0,0)
}
}
.b#{6 + $step} {
.block-outer {
@include moveBlock(-2,0,0)
}
}
.b#{11 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
}
._7:nth-of-type(#{$p}) ~ .surface {
.b#{4 + $step}, .b#{7 + $step}, .b#{10 + $step}, .b#{13 + $step} {
.block-outer {
@include moveBlock(2,0,0)
}
}
.b#{5 + $step}, .b#{8 + $step}, .b#{11 + $step}, .b#{14 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
}
._8:nth-of-type(#{$p}) ~ .surface {
.b#{5 + $step}, .b#{11 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
}
._9:nth-of-type(#{$p}) ~ .surface {
.b#{5 + $step}, .b#{11 + $step} {
.block-outer {
@include moveBlock(1,0,0)
}
}
.b#{10 + $step} {
.block-outer {
@include moveBlock(2,0,0)
}
}
}
}
}
}
/* Animations */
@keyframes bounce {
from, 50%, to {
transform: translateY(0);
}
25%, 75% {
transform: translateY($bounce);
}
}
@keyframes tilt {
from, to {
transform: translateY($sqSize * $zSpaces/2) rotateX($xAngle) rotateZ(-$tilt);
}
50% {
transform: translateY($sqSize * $zSpaces/2) rotateX($xAngle) rotateZ($tilt);
}
}
View Compiled
window.addEventListener("load",update);
function update() {
let time = new Date(),
hr = time.getHours(),
min = time.getMinutes(),
sec = time.getSeconds();
// prepend 0s to single digits
if (hr < 10)
hr = "0" + hr;
if (min < 10)
min = "0" + min;
if (sec < 10)
sec = "0" + sec;
let timeStr = `${hr}${min}${sec}`,
digits = document.querySelectorAll(".digit"),
digitArr = [];
for (let d in digits) {
d = +d;
if (d < digits.length) {
digitArr[d] = timeStr.substr(d,1);
digits[d].className = "digit _" + digitArr[d];
}
}
setTimeout(update,1000);
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.