const Frame = function (duration) { this.layers = []; this.duration = duration; } const FrameFactory = function (width, depth, height) { this.width = width; this.depth = depth; this.height = height; this.getFrame = function (duration) { const frame = new Frame(duration); for (let z = 0; z < this.height; z++) { const layer = []; for (let led = 0; led < this.width * this.depth; led++) { layer.push(false); } frame.layers.push(layer); } return frame; } } const Cube = function (width, depth, height) { this.width = width; this.depth = depth; this.height = height; this.html = document.getElementById('cube'); this.frames = []; this.currentFrame = 0; this.setup = function () { this._setupHtml(); } this.setCurrentFrame = function (frameIndex) { this.currentFrame = frameIndex; this._loadFrame(frameIndex); } this.switchLed = function (layerIndex, ledIndex) { console.log(layerIndex); this.frames[this.currentFrame].layers[layerIndex][ledIndex] = !this.frames[this.currentFrame].layers[layerIndex][ledIndex]; } this.setLayer = function (layerIndex, state) { for (let index = 0; index < this.width * this.depth; index++) { this.frames[this.currentFrame].layers[layerIndex][index] = state; } for (const row of this.html.children[this.height - layerIndex - 1].children) { for (const led of row.children) { this._setLed(led, state); } } } this._loadFrame = function (frameIndex) { for (let layer = 0; layer < this.frames[frameIndex].layers.length; layer++) { for (let row = 0; row < this.depth; row++) { for (let led = 0; led < this.width; led++) { const state = this.frames[frameIndex].layers[layer][row * this.depth + led]; this._setLed(this.html.children[layer].children[row].children[led], state); } } } } this._setupHtml = function () { for (let z = 0; z < this.height; z++) { const layerElement = document.createElement('div'); layerElement.classList.add('layer'); for (let y = 0; y < this.depth; y++) { const row = document.createElement('div'); row.classList.add('row'); for (let x = 0; x < this.width; x++) { const led = document.createElement('div'); led.classList.add('led', 'led-off'); led.addEventListener( 'click', (event) => { const index = y * this.depth + x; const layer = this.height - z - 1; this.switchLed(layer, index); this._setLed(event.target, this.frames[this.currentFrame].layers[layer][index]); } ); row.appendChild(led); } layerElement.appendChild(row); } this.html.appendChild(layerElement); } } this._setLed = function (ledHtml, state) { if (state) { ledHtml.classList.remove('led-off'); } else { ledHtml.classList.add('led-off'); } } } const WIDTH = 4; const DEPTH = 4; const HEIGHT = 4; const cube = new Cube(WIDTH, DEPTH, HEIGHT); cube.setup(); console.log(cube.html.children); const frameFactory = new FrameFactory(WIDTH, DEPTH, HEIGHT); cube.frames.push(frameFactory.getFrame(100)); cube.setCurrentFrame(0); cube.setLayer(2, true);