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-unit {
fill-opacity: 0.9;
stroke-miterlimit: 0;
}
.blue-cube, .blue-cube-generated, .pink-cube > .m-right {
--mainColor: #009cde;
--strokeColor: #0079ad;
--lightColor: #00affa;
--darkColor: #008bc7;
}
.pink-cube, .pink-cube-generated, .m-right, .m-right-right {
--mainColor: #de0063;
--strokeColor: #ad004e;
--lightColor: #fa0070;
--darkColor: #c7005a;
}
.m-left,
.m-left-left,
.m-right,
.m-right-right{
transform: translateX(0px);
}
.m-up,
.m-down {
transform: translateY(0px);
}
.m-left {
--translate: -50px;
}
.m-left-left {
--translate: -100px;
}
.m-right {
--translate: 50px;
}
.m-right-right {
--translate: 100px;
}
svg * {
transition: 0.2s transform;
}
svg:hover .m-left,
svg:hover .m-left-left,
svg:hover .m-right,
svg:hover .m-right-right {
transform: translateX(var(--translate));
}
svg:hover .m-up,
svg:hover .m-down {
transform: translateY(var(--translate));
}
JavaScript
// generate a n*3 cube and seperate into 3 groups [left, middle, right]
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 dimensions and spacing
const cubeWidth = 21;
const cubeHeight = -12;
const horizontalSpacing = 21;
const verticalSpacing = 12;
// define starting position
const startX = 32;
const startY = 64;
// produce the matrix and rotate for layout positions
const cubeMatrix = generateSquareMatrix(n);
const cubePositions = rotateMatrix45Deg(cubeMatrix);
// rotate in the opposite direction to gather groupings
const groupPositions = rotateMatrix45Deg(cubeMatrix, 1);
// create and position cubes
cubePositions.flat().forEach((dets) => {
// extract row/col
const {
x: row,
y: col
} = dets;
// get depth from position in the cubePositions array
const depth = cubePositions.findIndex((rows, indx) => {
return rows.indexOf(dets) !== -1
});
// we set the 3d depth from the one x/y vector using layer
for (let layer = 0; layer < n; layer++) {
// calc the layer offset to simulate depth
const layerOffset = ((layer * ((1 - cubeHeight) + verticalSpacing - 1)));
// calc the x pos using the hoz and width vals
const x = startX + (col * (cubeWidth + horizontalSpacing)) + (depth * horizontalSpacing);
// do the same with the vert and height vals for y but also consider the layers vertical offsets
const y = startY + (row * (cubeHeight + verticalSpacing)) + (depth * verticalSpacing) - layerOffset;
// record the cube
cubes.push({
screenX: x,
screenY: y,
x: row,
y: col,
// record the order for sort order in grouping
order: layer
});
}
});
// adjust allocations...