134 lines
3.8 KiB
JavaScript
134 lines
3.8 KiB
JavaScript
![]() |
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();
|