.scene
- for (var cube = 0; cube < 100; cube++)
.cube.cube__small
.face.front
.face.back
.face.right
.face.left
.face.top
.face.bottom
View Compiled
/*--------------------
Body
--------------------*/
*,
*::before,
*::after {
box-sizing: border-box;
}
:root {
--h: 100px;
--a: 35px;
--b: 35px;
}
$hue: 240;
$rad: 3.2;
body {
height: 100vh;
margin: 0;
overflow: hidden;
perspective: 2000px;
display: flex;
justify-content: center;
align-items: center;
background: #fafafa;
padding-top: 100px;
}
.scene {
min-width: calc(var(--a) * 10);
min-height: calc(var(--b) * 10);
width: calc(var(--a) * 10);
height: calc(var(--b) * 10);
transform: rotateX(60deg) rotateZ(30deg);
transform-style: preserve-3d;
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: center;
align-items: center;
}
.cube {
width: var(--a);
height: var(--b);
.face {
position: absolute;
width: var(--a);
height: var(--h);
transform-origin: 0 0;
}
.bottom {
height: var(--b);
}
.top {
height: var(--b);
transform: translateZ(var(--h));
}
.front {
transform: rotateX(-90deg) translateY(calc(var(--h) * -1)) translateZ(var(--b));
}
.back {
transform: rotateX(-90deg) translateY(calc(var(--h) * -1));
}
.right {
transform: translateY(var(--b)) translateZ(var(--h)) translateX(var(--a)) rotateZ(-90deg) rotateX(-90deg);
width: var(--b);
}
.left {
transform: translateY(var(--b)) translateZ(var(--h)) rotateZ(-90deg) rotateX(-90deg);
width: var(--b);
}
}
.cube__small {
.face {
}
@for $i from 1 to 101 {
&:nth-child(#{$i}) {
$r: floor(($i - 1) / 10);
$c: ($i - 1 - $r * 10) + $r;
.face {
background: hsla($hue - $c * $rad, 60%, 60%, 1);
}
.top {
background: hsla($hue - $c * $rad, 65%, 55%, 1);
}
.front {
background: hsla($hue - $c * $rad, 70%, 48%, 1);
}
.right {
background: hsla($hue - $c * $rad, 75%, 44%, 1);
}
}
}
}
View Compiled
/*--------------------
Mouse
--------------------*/
let time = 0;
let leaveTimeout;
let leave = true;
let mouse = {
x: window.innerWidth / 2 + Math.cos(time) * window.innerWidth / 2,
y: window.innerHeight / 2,
};
const onMouseMove = (e) => {
clearTimeout(leaveTimeout);
leave = false;
mouse = {
x : e.clientX || e.pageX || e.touches[0].pageX || 0,
y: e.clientY || e.pageY || e.touches[0].pageY || 0
};
};
['mousemove', 'touchmove'].forEach(event => {
window.addEventListener(event, onMouseMove);
});
document.body.addEventListener('mouseleave', () => {
leaveTimeout = setTimeout(() => {
leave = true;
time = 0;
}, 1000);
});
/*--------------------
Distance
--------------------*/
const checkDistance = (x, y) => {
const diffX = mouse.x - x;
const diffY = mouse.y - y;
return Math.sqrt(diffX * diffX + diffY * diffY);
}
/*--------------------
Render
--------------------*/
let radius = .4;
let maxHeight = 150;
let minHeight = 0;
let lastCalledTime;
let fps;
const divs = Array.prototype.slice.call(document.querySelectorAll('.cube__small'));
divs.forEach(d => {
d.oldHeight = 0;
});
const render = () => {
time += 0.1;
window.requestAnimationFrame(render);
if (leave) {
if(Math.cos(time) < -0.99) {
time = 0;
}
mouse = {
x: window.innerWidth / 2 - Math.cos(time) * window.innerWidth / 2,
y: window.innerHeight / 2,
};
}
divs.forEach(d => {
const bounds = d.getBoundingClientRect();
const centerX = bounds.x + bounds.width / 2;
const centerY = bounds.y + bounds.height / 2;
const dist = checkDistance(centerX, centerY);
const height = Math.min(maxHeight, minHeight + maxHeight * dist / maxHeight - dist * radius);
const translate = d.oldHeight + (height - d.oldHeight) * 0.6;
d.style = `--h: ${translate}px;`;
d.oldHeight = translate;
});
/*-----------------------------------
FPS
-----------------------------------*/
if(!lastCalledTime) {
lastCalledTime = Date.now();
fps = 0;
return;
}
delta = (Date.now() - lastCalledTime)/1000;
lastCalledTime = Date.now();
fps = 1/delta;
/*-----------------------------------
Decomment for scene interaction
-----------------------------------*/
//document.querySelector('.scene').style.transform = `rotateX(60deg) rotateZ(${15 + mouse.x / 30}deg)`;
}
render();
window.addEventListener('mousedown', () => { radius = .8 })
window.addEventListener('mouseup', () => { radius = .4 })
View Compiled
This Pen doesn't use any external JavaScript resources.