JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]> <html class="no-js"> <!--<![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Divisions</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/dev/divisions/style.css">
</head>
<body>
<div class="inputs">
<label for="prompt">Prompt</label>
<textarea name="prompt" id="prompt">((ultra-detailed)), ((illustration)), 2girls
AND ((ultra-detailed)), ((illustration)), 2girls, black hair
AND ((ultra-detailed)), ((illustration)), 2girls, blonde hair</textarea>
<output></output>
<label for="width">Width</label>
<input type="range" min="64" max="1024" name="width" id="width" oninput="this.nextElementSibling.value = this.value + 'px'" value="512" step="8">
<output>512px</output>
<label for="height">Height</label>
<input type="range" min="64" max="1024" name="height" id="height" oninput="this.nextElementSibling.value = this.value + 'px'" value="512" step="8">
<output>512px</output>
<label for="divisions">Divisions</label>
<input type="text" name="divisions" id="divisions" value="1:1,1:2,1:2">
<output></output>
<label for="positions">Positions</label>
<input type="text" name="positions" id="positions" value="0:0,0:0,0:1">
<output></output>
<label for="weights">Weights</label>
<input type="text" name="weights" id="weights" value="0.2,0.8,0.8">
<output></output>
<label for="divisionDisplay">Divisions to display (zero indexed)</label>
<input type="text" name="divisionDisplay" id="divisionDisplay" value="">
<output></output>
</div>
<div class="container">
<div class="box1" style="width: 512px;...
CSS
body {
background-color: white;
font-family: Arial, Helvetica, sans-serif;
}
div.inputs {
margin-bottom: 32px;
display: grid;
grid-template-columns: repeat(3, minmax(0, 256px));
grid-gap:16px;
}
textarea#prompt {
min-width: 256px;
min-height: 128px;
}
div.inp label {
text-align:right;
}
div.container {
border: 4px solid black;
position: relative;
}
div[class^="box-"] {
position: absolute;
margin: 0;
padding: 0;
display: inline-block;
}
div[class^="box-"]:nth-child(4n+1) {
outline: 2px solid red;
background-color: rgba(255,0,0,0.2);
}
div[class^="box-"]:nth-child(4n+2) {
outline: 2px solid green;
background-color: rgba(0,255,0,0.2);
}
div[class^="box-"]:nth-child(4n+3) {
outline: 2px solid blue;
background-color: rgba(0,0,255,0.2);
}
div[class^="box-"]:nth-child(4n+4) {
outline: 2px solid purple;
background-color: rgba(128,0,128,0.2);
}
div[class^="box"] span {
padding: 4px;
display: block;
color: black;
text-shadow: 0px 0px 4px white;
}
JavaScript
const container = document.querySelector('div.container');
const promptInput = document.querySelector('textarea#prompt');
const widthInput = document.querySelector('input#width');
const heightInput = document.querySelector('input#height');
const divisionsInput = document.querySelector('input#divisions');
const positionsInput = document.querySelector('input#positions');
const weightsInput = document.querySelector('input#weights');
const divisionDisplayInput = document.querySelector('input#divisionDisplay');
function rawSplit(str, colon=true) {
let tmp = [];
for (const s of str.split(',')) {
if (colon) {
let split = s.split(':');
tmp.push([Number(split[0]), Number(split[1])]);
} else {
tmp.push(Number(s))
}
}
return tmp;
}
function createBox(prompt, i, w, h, x, y) {
const box = document.createElement('div');
const promptSpan = document.createElement('span');
box.classList.add(`box-${i}`);
box.style.width = `${w}px`;
box.style.height = `${h}px`;
box.style.left = `${x}px`;
box.style.top = `${y}px`;
promptSpan.textContent = prompt;
box.appendChild(promptSpan);
return box;
}
function handleChange() {
let prompts = promptInput.value.split('AND').map(x => x.trimStart());
let divisions = rawSplit(divisionsInput.value);
let positions = rawSplit(positionsInput.value);
let weights = rawSplit(weightsInput.value, false);
let divisionDisplay = rawSplit(divisionDisplayInput.value, false);
if (divisionDisplayInput.value.trim() == '') {
divisionDisplay = [];
}
const equal = [prompts, divisions, positions, weights].every((val, _, arr) => val.length === arr[0].length);
if (equal) {
container.innerHTML = '';
container.style.width = `${widthInput.value}px`;
container.style.height = `${heightInput.value}px`;
for (const [i, p] of prompts.entries()) {
if (divisionDisplay.length > 0 && divisionDisplay.indexOf(i) == -1) {
continue;
}
const w = parseInt(widthInput.value / divisions[i][1]);
const h =...