82 lines
No EOL
2.5 KiB
JavaScript
82 lines
No EOL
2.5 KiB
JavaScript
import {parseRGB, convertRgbToOklch, convertRgbToLab65, mix} from './convert.js';
|
|
|
|
function el(name, attr, content) {
|
|
const element = document.createElement(name);
|
|
if(attr) {
|
|
for(let [k,v] of Object.entries(attr)) {
|
|
element.setAttribute(k, v);
|
|
}
|
|
}
|
|
if(content) {
|
|
element.innerHTML = content;
|
|
}
|
|
return element;
|
|
}
|
|
|
|
const colour_groups = [
|
|
{name: 'background', value: '#ffffff'},
|
|
{name: 'text', value: '#000000'},
|
|
{name: 'main', value: '#a2d1f0'},
|
|
{name: 'primary', value: '#76f2ff'},
|
|
{name: 'link', value: '#0000ee'},
|
|
{name: 'success', value: '#008000'},
|
|
{name: 'info', value: '#0c6dcf'},
|
|
{name: 'warning', value: '#996700'},
|
|
{name: 'danger', value: '#df0000'},
|
|
{name: 'muted', value: '#636363'}
|
|
];
|
|
|
|
const color_picker_form = document.getElementById('color-picker');
|
|
|
|
/*
|
|
Delta Phi Star perceptual lightness contrast by Andrew Somers:
|
|
https://github.com/Myndex/deltaphistar
|
|
*/
|
|
const PHI = (1 + Math.sqrt(5))/2;
|
|
|
|
function dpsContrast(a, b) {
|
|
const dps = Math.abs(Math.pow(convertRgbToLab65(a).l, PHI) - Math.pow(convertRgbToLab65(b).l, PHI));
|
|
const contrast = Math.pow(dps, 1/PHI) * Math.SQRT2 - 40;
|
|
return contrast < 7.5 ? 0 : contrast;
|
|
}
|
|
|
|
function is_dark(col) {
|
|
const black_contrast = dpsContrast(col, {r:0, g:0, b:0});
|
|
const white_contrast = dpsContrast(col, {r:1, g:1, b:1});
|
|
return black_contrast < white_contrast;
|
|
}
|
|
|
|
function text_for(col) {
|
|
return is_dark(col) ? 'white' : 'black';
|
|
}
|
|
|
|
colour_groups.forEach(({name, value}) => {
|
|
const label = el('label',{}, name);
|
|
const picker = el('input', {type: 'color', value});
|
|
label.append(picker);
|
|
color_picker_form.appendChild(label);
|
|
|
|
function update() {
|
|
const col = picker.value;
|
|
const rgb = parseRGB(col);
|
|
const oklch = convertRgbToOklch(rgb);
|
|
console.log(name, col, oklch);
|
|
const root = document.documentElement;
|
|
root.style.setProperty(`--${name}`, col);
|
|
root.style.setProperty(`--${name}-text`, text_for(rgb));
|
|
if(name == 'background') {
|
|
is_dark(rgb) ? root.classList.add('dark-background') : root.classList.remove('dark-background');
|
|
}
|
|
}
|
|
picker.addEventListener('input', update);
|
|
update();
|
|
});
|
|
|
|
['','success','info','warning','danger','muted'].forEach(name => {
|
|
const alertDiv = el('div',{class:`alert ${name}`});
|
|
alertDiv.appendChild(el('h2',{},name));
|
|
alertDiv.appendChild(document.getElementById('plain-text').cloneNode(true));
|
|
document.getElementById('alerts').appendChild(alertDiv);
|
|
});
|
|
|
|
window.parseRGB = parseRGB; |