<main id="canvas"></main>
<fieldset id="app">
<legend>Settings</legend>
<label>MinMax<input type="range" min="1" max="12" value="4" name="--w" data-unit="cqi"></label>
<label>Nodes<input type="range" min="5" max="200" value="100" name="nodes"></label>
<label>Light Start<input type="range" max="100" value="0" name="lightStart"></label>
<label>Light Stop<input type="range" max="100" value="100" name="lightStop"></label>
<label>Chroma Start<input type="range" max="0.5" value="0" step="0.01" name="chromaStart"></label>
<label>Chroma Stop<input type="range" max="0.5" value="0.5" step="0.01" name="chromaStop"></label>
<label>Hue Start<input type="range" max="360" value="0" name="hueStart"></label>
<label>Hue Stop<input type="range" max="360" value="360" name="hueStop"></label>
<label>Canvas Color<input type="color" name="--bgc" value="#F2EEE7"></label>
<label>Frame Color<input type="color" name="--fc" value="#050505" list="frame"></label>
<datalist id="frame">
<option value="#050505"></option>
<option value="#6B412E"></option>
<option value="#7F5F50"></option>
<option value="#D39E85"></option>
<option value="#F2EEE7"></option>
<option value="#FEFEFE"></option>
</datalist>
</fieldset>
<!-- https://heredragonsabound.blogspot.com/2020/02/creating-pencil-effect-in-svg.html -->
<svg style="width:0;height:0;overflow:hidden;position:absolute;">
<defs>
<filter x="0%" y="0%" width="100%" height="100%" filterUnits="objectBoundingBox" id="roughPaper">
<feTurbulence type="fractalNoise" baseFrequency="128" numOctaves="1" result="noise">
</feTurbulence>
<feDiffuseLighting in="noise" lighting-color="white" surfaceScale="1" result="diffLight">
<feDistantLight azimuth="45" elevation="55">
</feDistantLight>
</feDiffuseLighting>
<feGaussianBlur in="diffLight" stdDeviation="0.75" result="dlblur">
</feGaussianBlur>
<feComposite operator="arithmetic" k1="1.2" k2="0" k3="0" k4="0" in="dlblur" in2="SourceGraphic" result="out">
</feComposite>
</filter>
<filter x="-2%" y="-2%" width="104%" height="104%" filterUnits="objectBoundingBox" id="PencilTexture">
<feTurbulence type="fractalNoise" baseFrequency="1.2" numOctaves="3" result="noise">
</feTurbulence>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="3" in="SourceGraphic" result="newSource">
</feDisplacementMap>
</filter>
<filter x="0%" y="0%" width="100%" height="100%" filterUnits="objectBoundingBox" id="pencilTexture2">
<feTurbulence type="fractalNoise" baseFrequency="2" numOctaves="5" stitchTiles="stitch" result="f1">
</feTurbulence>
<feColorMatrix type="matrix" values="0 0 0 0 0, 0 0 0 0 0, 0 0 0 0 0, 0 0 0 -1.5 1.5" result="f2">
</feColorMatrix>
<feComposite operator="in" in2="f2" in="SourceGraphic" result="f3">
</feComposite>
</filter>
<filter x="0%" y="0%" width="100%" height="100%" filterUnits="objectBoundingBox" id="pencilTexture3">
<feTurbulence type="fractalNoise" baseFrequency="0.5" numOctaves="5" stitchTiles="stitch" result="f1">
</feTurbulence>
<feColorMatrix type="matrix" values="0 0 0 0 0, 0 0 0 0 0, 0 0 0 0 0, 0 0 0 -1.5 1.5" result="f2">
</feColorMatrix>
<feComposite operator="in" in2="f2b" in="SourceGraphic" result="f3">
</feComposite>
<feTurbulence type="fractalNoise" baseFrequency="1.2" numOctaves="3" result="noise">
</feTurbulence>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="2.5" in="f3" result="f4">
</feDisplacementMap>
</filter>
<filter x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox" id="pencilTexture4">
<feTurbulence type="fractalNoise" baseFrequency="0.03" numOctaves="3" seed="1" result="f1">
</feTurbulence>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="5" in="SourceGraphic" in2="f1" result="f4">
</feDisplacementMap>
<feTurbulence type="fractalNoise" baseFrequency="0.03" numOctaves="3" seed="10" result="f2">
</feTurbulence>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="5" in="SourceGraphic" in2="f2" result="f5">
</feDisplacementMap>
<feTurbulence type="fractalNoise" baseFrequency="1.2" numOctaves="2" seed="100" result="f3">
</feTurbulence>
<feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="3" in="SourceGraphic" in2="f3" result="f6">
</feDisplacementMap>
<feBlend mode="multiply" in2="f4" in="f5" result="out1">
</feBlend>
<feBlend mode="multiply" in="out1" in2="f6" result="out2">
</feBlend>
</filter>
</defs>
</svg>
*, *::before, *::after {
box-sizing: border-box;
}
body {
background-color: oklch(var(--l) var(--c) var(--h) / 0.25);
display: grid;
font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
gap: 1rem;
margin: 0 auto;
padding: 1rem;
max-width: 1000px;
}
b {
background: oklch(var(--l) var(--c) var(--h) / var(--a));
filter: var(--url) blur(.02em);
grid-column: span var(--gc);
grid-row: span var(--gr, 1);
/* mix-blend-mode: color-burn; */
rotate: var(--r);
scale: var(--s);
}
main {
aspect-ratio: 1.25 / 1;
background-color: var(--bgc, #F2EEE7);
border: 1cqi ridge var(--fc, #050505);
container-type: inline-size;
display: grid;
filter: url(#roughPaper);
gap: .25cqi;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill, minmax(var(--w, 4cqi), 1fr));
overflow: hidden;
}
fieldset {
background: #FFF;
border: 1px solid oklch(75% 0 0);
border-radius: .5cqi;
display: grid;
font-size: x-small;
gap: 1cqi;
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
padding: 1rem;
}
label {
align-items: center;
display: grid;
grid-template-columns: 1fr 2fr;
}
[type="color"] {
border: 1px solid oklch(75% 0 0);
border-radius: .5cqi;
padding: 0;
width: 100%;
&::color-swatch {
border: 0;
}
&::color-swatch-wrapper {
padding: 0;
}
}
const app = document.getElementById("app")
const canvas = document.getElementById("canvas")
const random = (min, max) =>
Math.random() * (max - min) + min
const color = () => `--l:${
random(app.elements.lightStart.valueAsNumber, app.elements.lightStop.valueAsNumber)}%;--c:${
random(app.elements.chromaStart.valueAsNumber, app.elements.chromaStop.valueAsNumber)};--h:${
random(app.elements.hueStart.valueAsNumber, app.elements.hueStop.valueAsNumber)};--a:${
random(0.2, 1)};`
const column = () => `--gc:${Math.floor(random(0, 4))};`
const filter = () =>
`--url:url(#${
[
"pencilTexture",
"pencilTexture2",
"pencilTexture3",
"pencilTexture4",
][Math.floor(random(0, 4))]
});`
const render = () => {
canvas.innerHTML = Array.from({length: app.elements.nodes.valueAsNumber}, (_, index) => `<b style="
${color()}
${column()}
${filter()}
${row()}
${transform()}
"></b>`).join('')
}
const row = () => `--gr:${Math.floor(random(0, 3))};`
const transform = () => `--r:${random(-2, 3)}deg;--s:${random(0.8, 1.2)};`
/* Add event listeners */
app.addEventListener("input", (event) => {
const node = event.target
if (node.name.startsWith('--')) {
canvas.style.setProperty(node.name, node.value+(node.dataset.unit||''))
}
else {
render()
}
})
/* Init event */
app.elements.nodes.dispatchEvent(new Event('input', {bubbles: true}))
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.