JSFiddle - React, Tailwind, and code Playground
by Graham Dixon
HTML
<svg class="hidden">
<defs>
<g id="cube" class="cube-unit">
<rect width="21" height="24" fill="var(--lightColor)" stroke="var(--strokeColor)" transform="skewY(30)" />
<rect width="21" height="24" fill="var(--darkColor)" stroke="var(--strokeColor)" transform="skewY(-30) translate(21 24.3)" />
<rect width="21" height="21" fill="var(--mainColor)" stroke="var(--strokeColor)" transform="scale(1.41,.81) rotate(45) translate(0 -21)" />
</g>
</defs>
</svg>
<svg class="blue-cube" viewBox="0 -64 300 230">
[{x: 0, y: 2}, {x: 0, y:1}, {x: 1, y: 2}, {x: 0, y: 0}, {x: 1, y:0}, {x: 2, y: 0}, {x: 0, y: 1}, {x: 2, y:1}, {x: 2, y: 2}]
<!-- 1, 3
79, (79 + (3 * 21)) = 79 + 63 = 142
79, (79 + (2 * 21)) = 79 + 42 = 121 -->
// 0, 2
// middle 3
<use xlink:href="#cube" x="121" y="48"></use>
<use xlink:href="#cube" x="121" y="24"></use>
<use xlink:href="#cube" x="121" y="0"></use>
// 0, 1
// left 3
100 - 79 = 21
0, 1 + depth 1
<use xlink:href="#cube" x="100" y="60"></use>
<use class="m-left" xlink:href="#cube" x="100" y="36"></use>
<use class="m-left" xlink:href="#cube" x="100" y="12"></use>
// 1, 2
// 1, 2
// 142 - 79 = 63 = 3
// right 3
<use xlink:href="#cube" x="142" y="60"></use>
<use xlink:href="#cube" x="142" y="36"></use>
<use xlink:href="#cube" x="142" y="12"></use>
123 3
456 5 6
789
// 0, 0
// left 1
<g class="m-left">
<use xlink:href="#cube" x="79" y="72"></use>
<use xlink:href="#cube" x="79" y="48"></use>
<use xlink:href="#cube" x="79" y="24"></use>
</g>
// 1, 0
// middle 2
<use xlink:href="#cube" x="121" y="72"></use>
<use xlink:href="#cube" x="121" y="48"></use>
<use xlink:href="#cube" x="121" y="24"></use>
// 2, 0
// right 1
<g class="m-right">
<use xlink:href="#cube" x="163" y="72"></use>
...
CSS
body {
font-family: "Roboto", sans-serif;
margin: 0 auto;
text-align: center;
}
.hidden {
display: none;
}
.cube-unit {
fill-opacity: 0.9;
stroke-miterlimit: 0;
}
.blue-cube {
--mainColor: #009cde;
--strokeColor: #0079ad;
--lightColor: #00affa;
--darkColor: #008bc7;
}
JavaScript
document.addEventListener('DOMContentLoaded', function() {
const cubeSize = 3; // Example for a 3x3x3 Rubik's Cube
generateRubiksCube(cubeSize);
});
function generateRubiksCube(n) {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("viewBox", "0 0 300 230");
svg.classList.add("blue-cube");
// Adjust these values based on the exact layout and perspective desired
const baseX = 79; // Starting x-coordinate for the first cube at the leftmost position
const baseY = 12; // Starting y-coordinate for the lowest cube in the front row
const xIncrement = 21; // Horizontal increment for moving right in the SVG
const yIncrement = 12; // Vertical increment for moving up in the SVG
const depthXOffset = 21; // Additional x offset for each layer deeper into the cube
const depthYOffset = -12; // Y offset for each layer deeper, giving the 3D effect
const cubePositions = generateCubePos(n);
//console.log(cubePositions);
cubePositions.forEach((cube) => {
const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#cube');
use.setAttribute('x', cube.x);
use.setAttribute('y', cube.y);
svg.appendChild(use);
});
document.body.appendChild(svg);
}
const cubeSize = 3; // Example for a 4x4x4 cube
function generateSquareMatrix(n) {
let matrix = [];
let num = 1;
for (let row = 0; row < n; row++) {
let newRow = [];
for (let col = 0; col < n; col++) {
newRow.push(num++);
}
matrix.push(newRow);
}
return matrix;
}
function generateCubePos(n) {
let positions = [];
const baseX = 79, baseY = 48; // Adjust these based on the first cube position
const xIncrement = 21, yIncrement = 24; // Horizontal and vertical increments
const depthX = 21, depthY = 12; // Adjustments for depth to create the 3D...