automatic-colour-scheme/script.js

134 lines
3.8 KiB
JavaScript
Raw Normal View History

2025-02-09 20:19:13 +00:00
import {calcAPCA} from './apca-w3.js';
import { wcagContrast, formatHex} from './culori.mjs';
import * as culori from './culori.mjs';
import {name_colour, nearestNamedColors} from './color-picker.js';
import {find_contrast} from './auto_contrast.js';
import * as plain_converters from './convert.js';
window.plain_converters = plain_converters;
window.culori = culori;
const color_a_input = document.getElementById('color-a');
const color_b_input = document.getElementById('color-b');
export class PaletteInfoElement extends HTMLElement {
static observedAttributes = ['text', 'bg'];
constructor() {
super();
let template = document.getElementById("palette-info-template");
let templateContent = template.content;
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
:root {
--col-a: black;
--col-b: white;
}
#container {
display: grid;
grid-gap: 0.5em;
grid-template-columns: 1fr auto;
}
#preview .block {
padding: 0.5em;
color: var(--col-a);
background: var(--col-b);
}
#preview p {
padding: 1em;
}
#preview #inline-white-bg {
color: black;
background: white;
}
#preview #inline-black-bg {
color: white;
background: black;
}
#preview .inline {
color: var(--col-a);
}
p {
margin: 0 0 0.5em 0;
}
`);
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(templateContent.cloneNode(true));
shadowRoot.adoptedStyleSheets = [sheet];
this.set_colours();
}
attributeChangedCallback(name, oldValue, newValue) {
this.set_colours();
}
set_colours() {
const col_a = this.getAttribute('text');
const col_b = this.getAttribute('bg');
const hex_a = formatHex(col_a);
const hex_b = formatHex(col_b);
const apca_contrast = Math.abs(calcAPCA(hex_a, hex_b));
this.shadowRoot.getElementById('apca-contrast').textContent = apca_contrast.toFixed(0);
const wcag_contrast = wcagContrast(col_a, col_b);
this.shadowRoot.getElementById('wcag-contrast').textContent = wcag_contrast.toFixed(2);
const preview = this.shadowRoot.getElementById('preview');
preview.style.setProperty('--col-a',hex_a);
preview.style.setProperty('--col-b',hex_b);
}
}
customElements.define('palette-info', PaletteInfoElement);
class ColorPaletteApp {
constructor() {
Array.from(document.querySelectorAll('color-picker')).forEach(i => i.addEventListener('input', () => this.update()));
this.current_palette = document.querySelector('palette-info');
document.getElementById('fiddle-text').addEventListener('click', () => this.fiddle_text());
document.getElementById('fiddle-bg').addEventListener('click', () => this.fiddle_bg());
}
update() {
const col_a = color_a_input.value;
const col_b = color_b_input.value;
const hex_a = formatHex(col_a);
const hex_b = formatHex(col_b);
this.current_palette.setAttribute('text',hex_a);
this.current_palette.setAttribute('bg',hex_b);
}
get target_contrast() {
return document.getElementById('target-contrast').valueAsNumber;
}
get num_close_colours() {
return document.getElementById('num-close-colours').valueAsNumber;
}
fiddle_text() {
const col_a = culori.oklab(color_a_input.value);
const col_b = culori.oklab(color_b_input.value);
color_a_input.value = formatHex(find_contrast(col_b, col_a, this.target_contrast, this.num_close_colours));
}
fiddle_bg() {
const col_a = culori.oklab(color_a_input.value);
const col_b = culori.oklab(color_b_input.value);
color_b_input.value = formatHex(find_contrast(col_a, col_b, this.target_contrast, this.num_close_colours));
}
}
const app = new ColorPaletteApp();
window.culori = culori;
app.update();