.profile/templates/palette.html

297 lines
8.3 KiB
HTML

<h1>A colour palette in plain HTML</h1>
<label>
<span>Background Colour:</span>
<input value="#f2f2f3" type="color" id="background-color"></input>
</label>
<section class="box">
A template colour palette written as a self-contained HTML file.
New palettes can be created easily by copying the file and changing a few CSS variables.
</section>
<!-- TODO: Change the base hue and offset here -->
<section style="--base-hue: 280deg; --saturation: 50%; --offset: calc(360deg / 6)">
<h2>Primary</h2>
<!-- Only override values here for slight tweaking -->
<div class="colors" style="--hue: var(--base-hue);">
<button style="--lightness: 05%"></button>
<button style="--lightness: 15%"></button>
<button style="--lightness: 30%"></button>
<button style="--lightness: 40%"></button>
<button style="--lightness: 50%"></button>
<button style="--lightness: 60%"></button>
<button style="--lightness: 70%"></button>
<button style="--lightness: 80%"></button>
<button style="--lightness: 95%"></button>
</div>
<section class="hint box">
Modify as needed by changing the <code>--hue</code> attribute in the inlined CSS.<br>
Usage of a separate color picker tool for this step might be preferable.<br>
</section>
<h2>Secondary</h2>
<div class="colors" style="--hue: calc(var(--base-hue) + var(--offset));">
<button style="--lightness: 05%"></button>
<button style="--lightness: 15%"></button>
<button style="--lightness: 30%"></button>
<button style="--lightness: 40%"></button>
<button style="--lightness: 50%"></button>
<button style="--lightness: 60%"></button>
<button style="--lightness: 70%"></button>
<button style="--lightness: 80%"></button>
<button style="--lightness: 95%"></button>
</div>
<section class="hint box">
You can copy any colour to the clipboard by just clicking on its box.
By default colours are copied as HSLA values.
This can be changed in the script block at the bottom of the document.
</section>
<h2>Tertiary</h2>
<div class="colors" style="--hue: calc(var(--base-hue) - var(--offset));">
<button style="--lightness: 05%"></button>
<button style="--lightness: 15%"></button>
<button style="--lightness: 30%"></button>
<button style="--lightness: 40%"></button>
<button style="--lightness: 50%"></button>
<button style="--lightness: 60%"></button>
<button style="--lightness: 70%"></button>
<button style="--lightness: 80%"></button>
<button style="--lightness: 95%"></button>
</div>
<section class="hint box">
By making use of <code>calc</code> and <code>var</code>, most of the colour palette can be automated.
This makes it easier and quicker to make adjustments.
</section>
<h2>Neutral</h2>
<div class="colors" style="--hue: 210deg; --saturation: 5%;">
<button style="--lightness: 05%"></button>
<button style="--lightness: 15%"></button>
<button style="--lightness: 30%"></button>
<button style="--lightness: 40%"></button>
<button style="--lightness: 50%"></button>
<button style="--lightness: 60%"></button>
<button style="--lightness: 70%"></button>
<button style="--lightness: 80%"></button>
<button style="--lightness: 95%"></button>
</div>
<section class="hint box">
By making use of <code>calc</code> and <code>var</code>, most of the colour palette can be automated.
This makes it easier and quicker to make adjustments.
</section>
</section>
<!-- ======================================== -->
<!-- ===== STYLES AND APPLICATION LOGIC ===== -->
<!-- ======================================== -->
<style>
:root {
font-size: 1em;
color: hsl(220deg, 8%, 20%);
font-family: "Open Sans", sans-serif;
}
body.dark {
color: hsl(220deg, 8%, 80%);
}
* {
box-sizing: border-box;
}
code {
font-family: "Hack", monospace;
}
body {
display: flex;
flex-flow: column nowrap;
align-items: center;
background: hsl(200deg, 5%, 95%);
}
/* The following only does font size shenanigans! */
h1, h2 {
text-align: center;
font-weight: normal;
font-family: "Raleway", "Quicksand", serif;
}
h1 {
font-size: 2.4em;
--border: dotted .08em currentcolor;
border-bottom: var(--border);
border-top: var(---border);
width: calc((3rem + .6rem * 2) * 9);
text-align: center;
padding: .2em 0;
}
h2 {
font-size: 2em;
}
div.colors {
--separation2: .6em; /* Halved separation */
display: flex;
/* padding: var(--separation2); */
}
div.colors button {
--radius: 50%;
all: unset;
margin: var(--separation2);
cursor: pointer;
border-radius: var(--radius);
overflow: hidden;
transition: box-shadow 0.3s;
} div.colors button::before {
content: '';
border-radius: var(--radius);
background: hsl(var(--hue), var(--saturation, 50%), var(--lightness, 50%));
box-shadow: .1em .1em .8em hsla(calc(var(--hue) + 30deg), calc(100% - var(--lightness) - 10%), calc(var(--lightness) - 40%), .4) inset;
width: 3em;
height: 3em;
display: block;
transition: box-shadow 0.3s;
}
div.colors button:hover {
box-shadow: .4em .4em .6em #0004;
}
div.colors button:hover::before {
box-shadow: none;
}
body.dark div.colors button:hover {
box-shadow: .0em .0em .6em hsla(var(--hue), calc(var(--saturation) + 30%), 80%, 60%);
}
/* === Popup notification shenanigans === */
@keyframes fade {
0% { opacity: 0; transform: translate(-50%, -10%)}
20% { opacity: 1;}
50% { opacity: 1;}
100% { opacity: 0; transform: translate(-50%, -150%)}
}
div.notification {
top: 0em;
border: 1px solid currentcolor;
background: hsla(0deg, 0%, 100%, .8);
font-size: 1em;
opacity: 0;
position: fixed;
padding: .4em; 1em;
font-weight: bold;
text-align: center;
}
/* === Info Boxes === */
.box {
--radius: .3em;
width: calc((3rem + .6rem * 2) * 9);
font-style: italic;
border-radius: var(--radius);
background: hsla(200deg, 5%, 92%, 1);
box-shadow: .0em .1em .2em inset hsl(220deg, 8%, 80%);
padding: 1em 2em;
position: relative;
margin: 2em 0em;
}
body.dark .box {
background: hsla(200deg, 5%, 6%, 1);
box-shadow: .0em .1em .2em inset #0006;
}
.hint, .info { --color: hsla(calc( 280deg - calc(360deg / 6)), 50%, 50%, 1) }
.box::after {
display: block;
position: absolute;
left: 0;
top: 0;
height: 100%;
width: .4em;
background-color: var(--color, transparent);
border-radius: var(--radius) 0 0 var(--radius);
content: '';
}
.box.hint::before {
content: "Hint: ";
display: inline-block;
font-weight: bold;
}
/* === Utility === */
[center] { text-align: center; }
</style>
<script type="module">
const showMessage = function(message, color, x, y) {
let box = document.createElement('div');
box.innerHTML = message;
box.classList.add('notification');
if (x) box.style.left = x+"px";
if (y) box.style.top = y+"px";
document.querySelector("body").appendChild(box);
box.style.setProperty('animation', 'fade 1s');
box.style.setProperty('animation-fill-mode', 'forwards');
box.style.setProperty('color', color);
box.addEventListener("animationend", ({box: target}) => box.parentElement.removeChild(box))
}
document.querySelectorAll('div.colors button').forEach(button => {
button.addEventListener('click', event => {
const prop = name => getComputedStyle(button)
.getPropertyValue(name)
.replace(/^ *| *$/g, "")
const colour = `hsl(${prop("--hue")}, ${prop("--saturation")}, ${prop("--lightness")})`
navigator.clipboard.writeText(colour).then(() => {
const box = button.getBoundingClientRect()
showMessage(`Copied to Clipboard:<br>${colour}`, colour, box.x+box.width/2, box.y+box.height/2);
});
});
});
const register = (type, name, initial=undefined) => CSS.registerProperty({
name: `--${name}`,
syntax: `<${type}>`,
inherits: true,
initialValue: initial,
})
register("angle", "hue", "0deg")
register("percentage", "saturation", "100%")
register("percentage", "lightness", "50%")
const backgroundColourButton = document.getElementById("background-color")
backgroundColourButton.addEventListener("input", event => {
const rgb = backgroundColourButton.value
document.body.style.background = rgb
const channels = rgb
.match(/[0-9a-f][0-9a-f]/g)
.map(hex => parseInt(hex, 16))
.map(num => num / 255)
const luminosity = channels.reduce((a,b)=>a+b) / 3
if (luminosity < 0.4) {
document.body.classList.add("dark")
} else {
document.body.classList.remove("dark")
}
})
</script>