const hub = document.getElementById("hub"); const layerCounts = document.getElementById("layercounts"); const layerColors = document.getElementById("layercolors"); const instantButton = document.getElementById("instantbutton"); const txtInput = document.getElementById("txtinput"); const bgInput = document.getElementById("bginput"); const colorArray = document.getElementById("colorarray"); const rowAdder = document.getElementById("addrow"); const rowRemover = document.getElementById("removerow"); const columnAdder = document.getElementById("addcolumn"); const columnRemover = document.getElementById("removecolumn"); const startButton = document.getElementById("startbutton"); const urlParams = new URLSearchParams(window.location.search); const launchP = urlParams.get("lch"); const colorP = urlParams.get("col"); const textP = urlParams.get("txt"); const sampleCell = document.body.querySelector(".samplecell"); const colorless = [0,0,0]; let bgColor; let colors; let text; let instant = true; let levels = [2000, 200, 100, 50, 25, 10]; let firstCell = null; let selectedCell = null; let selectedLayer = 0; let layerLength = 1; function loadPreset(name) { if (name == "suomi") { bgColor = "#120021"; colors = [ [ [[1,1,1], [1,1,1], [0,0,1], [1,1,1], [1,1,1], [1,1,1]], [[1,1,1], [1,1,1], [0,0,1], [1,1,1], [1,1,1], [1,1,1]], [[0,0,1], [0,0,1], [0,0,1], [0,0,1], [0,0,1], [0,0,1]], [[0,0,1], [0,0,1], [0,0,1], [0,0,1], [0,0,1], [0,0,1]], [[1,1,1], [1,1,1], [0,0,1], [1,1,1], [1,1,1], [1,1,1]], [[1,1,1], [1,1,1], [0,0,1], [1,1,1], [1,1,1], [1,1,1]] ] ]; } else if (name == "francais") { bgColor = "#120021"; colors = [ [ [[0,0,1], [1,1,1], [1,0,0]] ] ]; } else if (name == "vareja") { bgColor = "#120021"; colors = [ [ [[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5]], [[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0]], [[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0]], [[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0]], [[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0]], [[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0]], [[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5]], [[0,.5,1],[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1]], [[0,0,1],[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1]], [[.5,0,1],[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1]], [[1,0,1],[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1]], [[1,0,.5],[1,0,0],[1,.5,0],[1,1,0],[.5,1,0],[0,1,0],[0,1,.5],[0,1,1],[0,.5,1],[0,0,1],[.5,0,1],[1,0,1]] ] ]; } else if (name == "mangrove") { bgColor = "#5e4832"; colors = [ [[[160, 124, 89]]], [[[178, 56, 32]]], [[[66, 92, 39]]], [[[94, 140, 46]]], [[[119, 197, 38]]], [[[130, 255, 0]]] ]; } else if (name == "default") { bgColor = "#120021"; colors = [ [[[0,0,1]]], [[[0,0,1]]], [[[0,0,1]]], [[[0,0,1]]], [[[0,0,1]]], [[[1,1,0]]] ]; } else { bgColor = "#120021"; colors = [[[[.3, 0, 1]]]]; } } function textToColor(val, def=null) { const o = []; if (val.includes("#")) { if (val.length != 4 && val.length != 7) return def; for (let i = 0; i < val.slice(1).length; i++) { const charCode = val.toUpperCase().charCodeAt(i+1); if ((charCode < 48 || charCode > 57) && (charCode < 65 || charCode > 90)) return def; } if (val.length == 7) { o.push(parseInt(parseInt(val.slice(1, 3), 16).toString(10))); o.push(parseInt(parseInt(val.slice(3, 5), 16).toString(10))); o.push(parseInt(parseInt(val.slice(5, 7), 16).toString(10))); } else { for (let i = 0; i < 3; i++) { const digit = parseInt(parseInt(val[i+1], 16).toString(10)); o.push(16 * digit + digit); } } } else { const strValues = val.replaceAll(" ", "").split(","); if (strValues.length != 3) return def; for (let i = 0; i < strValues.length; i++) { const value = parseFloat(strValues[i]); if (isNaN(value)) { return def; } o.push(value); } } return o; } function updateLayerCount(textInput, level) { const value = parseInt(textInput.value); levels[level] = (!isNaN(value)) ? value : 0; } function updateLayerInputs() { for (let i = 0; i < 6; i++) { const target = layerCounts.children[i]; target.value = levels[i].toString(); } } function updateLayerButton() { const layers = layerColors.children; const targetColorStr = firstCell.querySelector("input"); const targetColor = textToColor(targetColorStr.value, colorless) const colorMult = (Math.max(...targetColor) > 1) ? 1 : 255; const targetStyle = `rgb(${targetColor[0] * colorMult}, ${targetColor[1] * colorMult}, ${targetColor[2] * colorMult})`; layers[selectedLayer].style.background = targetStyle; if (selectedLayer + 1 != layerLength) return; for (let i = layerLength; i < 6; i++) { layers[i].style.background = targetStyle; } } function updateAllLayers() { const layers = layerColors.children; for (let i = 0; i < 6; i++) { layers[i].classList.remove("currentlayer", "activelayer"); const targetColor = colors[Math.min(i, colors.length - 1)][0][0]; const colorMult = (Math.max(...targetColor) > 1) ? 1 : 255; layers[i].style.background = `rgb(${targetColor[0] * colorMult}, ${targetColor[1] * colorMult}, ${targetColor[2] * colorMult})`; if (i < colors.length) layers[i].classList.add("activelayer"); if (i == selectedLayer) layers[i].classList.add("currentlayer"); } } function updateCSS(textInput) { const cell = textInput.parentNode; const colorValues = textToColor(textInput.value) if (colorValues != null) { const colorMult = (Math.max(...colorValues) > 1) ? 1 : 255; cell.style.background = `rgba(${colorValues[0] * colorMult}, ${colorValues[1] * colorMult}, ${colorValues[2] * colorMult}, ${parseFloat(textInput.getAttribute("bgalpha"))})`; } else { cell.style.background = ""; } updateLayerButton(); } function updateBG() { const targetColor = textToColor(bgInput.value); if (targetColor != null) { const colorMult = (Math.max(...targetColor) > 1) ? 1 : 255; bgInput.style.background = `rgb(${targetColor[0] * colorMult}, ${targetColor[1] * colorMult}, ${targetColor[2] * colorMult})`; } else { bgInput.style.background = ""; } } function updateTXT() { text = txtInput.value; } function updateInstantStyle() { instantButton.style.background = (instant) ? "green" : "black" } function updateInstant() { instant = !instant; updateInstantStyle(); } function focusCell(textInput) { textInput.setAttribute("bgalpha", "1"); updateCSS(textInput); } function blurCell(textInput) { textInput.setAttribute("bgalpha", ".5"); updateCSS(textInput); } function selectCell(cell) { selectedCell = cell; } function pasteCell(cell) { if (selectedCell == null) return; const selectedInput = selectedCell.querySelector("input"); if (textToColor(selectedInput.value) == null) return; const textInput = cell.querySelector("input"); textInput.value = selectedInput.value; updateCSS(textInput); } function resetTable() { while (colorArray.firstElementChild != null) { colorArray.removeChild(colorArray.lastElementChild); } const row = document.createElement("tr"); const cell = sampleCell.cloneNode(true); cell.classList.remove("samplecell"); firstCell = cell; row.appendChild(cell); colorArray.appendChild(row); } function colorsToTable(lvl) { while (colorArray.firstElementChild != null) { colorArray.removeChild(colorArray.lastElementChild); } selectedLayer = lvl; const layer = colors[lvl]; layerLength = colors.length; for (let i = 0; i < layer.length; i++) { const row = document.createElement("tr"); for (let j = 0; j < layer[i].length; j++) { const cell = sampleCell.cloneNode(true); if (i == 0 && j == 0) firstCell = cell; cell.classList.remove("samplecell"); const textInput = cell.querySelector("input"); textInput.value = layer[i][j].toString(); updateCSS(textInput); row.appendChild(cell); } colorArray.appendChild(row); } updateAllLayers(); } function tableToColors() { const rows = colorArray.children; const o = []; for (let i = 0; i < rows.length; i++) { o.push([]); const cells = rows[i].children; for (let j = 0; j < cells.length; j++) { const textInput = cells[j].querySelector("input"); const values = textToColor(textInput.value, colorless); o[i].push(values); } } return o; } function addRow() { const newRow = colorArray.lastElementChild.cloneNode(true); colorArray.appendChild(newRow); } function removeRow() { if (colorArray.children.length > 1) colorArray.lastElementChild.remove(); } function addColumn() { const rows = colorArray.children; for (let i = 0; i < rows.length; i++) { const newCell = rows[i].lastElementChild.cloneNode(true); rows[i].appendChild(newCell); } } function removeColumn() { const rows = colorArray.children; if (rows[0].children.length == 1) return; for (let i = 0; i < rows.length; i++) { rows[i].lastElementChild.remove(); } } function switchLayer(layer) { colors[selectedLayer] = tableToColors(); if (layer >= layerLength) { for (let i = layerLength; i <= layer; i++) { const lastTable = colors[colors.length-1]; colors.push([]); for (let j = 0; j < lastTable.length; j++) { colors[i].push([]) for (let k = 0; k < lastTable[j].length; k++) { colors[i][j].push([]); for (let l = 0; l < 3; l++) { colors[i][j][k].push(lastTable[j][k][l]); } } } // PARDON MY SUPERTERRIBLE CODE HERE :D // Although... Can you prove that its level of non-terribleness doesn't suffice??? } } colorsToTable(layer); } const launch = launchP != null && (launchP == "1" || launchP.toLowerCase() == "true" || launchP.toLowerCase() == "t"); if (!launch) hub.style.display = ""; loadPreset(colorP); colorsToTable(0); txtInput.value = textP; bgInput.value = bgColor; updateLayerInputs(); updateTXT(); updateBG(); updateInstantStyle(); if (launch) start(); function start() { hub.style.display = "none"; colors[selectedLayer] = tableToColors(); const bgValues = textToColor(bgInput.value, colorless); const colorMult = (Math.max(...bgValues) > 1) ? 1 : 255; document.body.style.background = `rgb(${bgValues[0] * colorMult}, ${bgValues[1] * colorMult}, ${bgValues[2] * colorMult})`; for (let i = 0; i < 6; i++) { updateLayerCount(layerCounts.children[i], i); } hub.remove(); const spawnRate = 0; const storage = document.getElementById("storage"); const samples = document.getElementById("samples"); const sampleText = samples.querySelector(".text"); const initTextScale = 0; const textScaleMult = 1; const realisticDiffraction = true; const isText = (text != "" && text != null); let level = 0; let count = 0; if (isText) sampleText.querySelector(".sampletext").textContent = text; if (realisticDiffraction) var diffraction = Math.random() * 360; function color(parent, col, diffrac) { const details = parent.getElementsByClassName("detail"); for (let i = 0; i < details.length; i++) { const colorMult = (Math.max(...col) > 1) ? 1 : 255; const targetCol = `rgba(${col[0] * colorMult + parseInt(details[i].getAttribute("lightness"))}, ${col[1] * colorMult + parseInt(details[i].getAttribute("lightness"))}, ${col[2] * colorMult + parseInt(details[i].getAttribute("lightness"))}, ${details[i].getAttribute("alpha")})`; if (isText) details[i].style.color = targetCol; else details[i].style.backgroundColor = targetCol; if (diffrac && details[i].classList[0] == "diffrac") { const rotation = diffraction - parseInt(parent.style.rotate); details[i].style.transform = `translate(-50%, -50%) rotate(${rotation}deg)`; } } } let running = true; let interval = 0; function main() { while (count >= levels[level] && level < levels.length) { level += 1; count = 0; } if (level < levels.length) { const particle = (isText ? sampleText : samples.querySelector(`.p${level.toString()}`)).cloneNode(true); particle.style.left = `${Math.random()*100}vw`; particle.style.top = `${Math.random()*100}vh`; particle.style.rotate = `${Math.random()*360}deg`; if (isText) particle.style.scale = initTextScale + textScaleMult * (level + 1); color(particle, colorless, diffraction); const layer = colors[Math.min(level, colors.length-1)] for (let floor = 0; floor < layer.length; floor++) { if (parseInt(particle.style.top) >= 100 / layer.length * floor && parseInt(particle.style.top) <= 100 / layer.length * (floor+1)) { const pallette = layer[floor]; for (let i = 0; i < pallette.length; i++) { if (parseInt(particle.style.left) >= 100 / pallette.length * i && parseInt(particle.style.left) <= 100 / pallette.length * (i+1)) { color(particle, pallette[i], diffraction); } } } } storage.appendChild(particle); count += 1; } else { clearInterval(interval); running = false; } } if (instant) { while (running) main(); } else { interval = setInterval(main, spawnRate); } }