JSFiddle - React, Tailwind, and code Playground
by Graham Dixon
CSS
body {
font-family: "Roboto", sans-serif;
margin: 0 auto;
text-align: center;
}
.hidden {
display: none;
}
.outer {
display: flex;
width: 100%;
}
.inner {
width: 50%;
flex-direction: column;
}
.cube {
fill-opacity: 0.9;
stroke-miterlimit: 0;
}
.blue-cube, .blue-cube-generated, .pink-cube > .move-right {
--mainColor: #009cde;
--strokeColor: #0079ad;
--lightColor: #00affa;
--darkColor: #008bc7;
}
.pink-cube, .pink-cube-generated, .move-right, .move-right-right {
--mainColor: #de0063;
--strokeColor: #ad004e;
--lightColor: #fa0070;
--darkColor: #c7005a;
}
.green-cube, .move-left-left {
--mainColor: #00de42;
--strokeColor: #00ad34;
--lightColor: #00fa4b;
--darkColor: #00c73c;
}
.orange-cube, .move-left {
--mainColor: #9cde00;
--strokeColor: #79ad00;
--lightColor: #affa00;
--darkColor: #8bc700;
}
.move-left {
--translate: -50px;
}
.move-left-left {
--translate: -100px;
}
.move-right {
--translate: 50px;
}
.move-right-right {
--translate: 100px;
}
svg * {
transition: 0.2s transform;
}
.cube {
transform: translateX(0px);
}
svg:hover .cube,
svg.isIntersecting .cube {
transform: translateX(var(--translate));
}
JavaScript
// Credit to Mariana Beldi for the base implementation (https://codepen.io/marianab/pen/KKKYdxE)
// example...
generateCube(8, [1, 20, 10, 5, 5], "blue-cube");
generateCube(6, [1000, 200, 2000, 100], "blue-cube");
generateCube(3, [1000, 1, 1000], "pink-cube");
generateCube(3, [1, 20, 1], "blue-cube");
// generate a n*3 cube and seperate into groups (eg, [left, middle, right] upto a max of 5)
function generateCube(n, values = [1, 1, 1], className = "blue-cube") {
// fill with cubes before printing to screen
const cubes = [];
// end early on too many values
if (values.length > 5) {
throw new Error("Too many values provided, max of 5.");
}
// define starting position
const startX = 32;
const startY = 64;
// define dimensions and spacing
const cubeHeight = 12;
const cubeWidth = 21;
const verticalSpacing = 12;
const horizontalSpacing = 21;
// produce the matrix and rotate for layout positions
const cubeMatrix = generateSquareMatrix(n);
const cubePositions = rotateMatrix45Deg(cubeMatrix);
// create and position cubes
cubePositions.flat().forEach((cube) => {
// extract row/col
const {
x: col,
y: row
} = cube;
// the true x/col pos is taken from the diagonal in the cubePos, we need to know its depth to use in the cols place
const depth = cubePositions.findIndex((cubes, indx) => (
cubes.indexOf(cube) !== -1
));
// we set the 3d depth for each x/y vector using layer (column at a time)
for (let layer = 0; layer < n; layer++) {
// calc the x pos using the hoz and width vals for the col and depth for hoz offsets
const x = startX + (depth * horizontalSpacing) + (row * (cubeWidth + horizontalSpacing));
// vert position is taken from the diagonal depth spacing with shift based on layer to simulate 3d depth
const y = startY + (depth * verticalSpacing) - ((layer * (cubeHeight + verticalSpacing)));
// record the cube
cubes.push({
screenX:...