UNPKG

@scidian/osui

Version:

Lightweight JavaScript UI library.

1,057 lines (1,047 loc) 378 kB
/** * @description Osui * @about Lightweight JavaScript UI library. * @author Stephens Nunnally <@stevinz> * @license MIT - Copyright (c) 2021 Stephens Nunnally * @source https://github.com/scidian/osui * @version v0.1.19 */ var img$3 = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3c!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg width='100%25' height='100%25' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve' xmlns:serif='http://www.serif.com/' style='fill-rule:evenodd%3bclip-rule:evenodd%3bstroke-linejoin:round%3bstroke-miterlimit:2%3b'%3e%3cpath d='M373.189%2c648.684c-0%2c-0 -237.09%2c-138.996 -258.087%2c-117.999c-20.997%2c20.997 212.331%2c288.419 212.331%2c288.419c1.975%2c3.009 4.284%2c5.857 6.926%2c8.499c10.698%2c10.698 24.796%2c15.945 38.83%2c15.71c14.035%2c0.235 28.132%2c-5.012 38.831%2c-15.71c2.641%2c-2.642 4.95%2c-5.49 6.926%2c-8.499c-0%2c-0 423.255%2c-489.7 496.91%2c-611.246c9.004%2c-14.859 -15.991%2c-40.415 -34.446%2c-27.458c-108.024%2c75.837 -508.221%2c468.284 -508.221%2c468.284Z' style='fill:%23ebebeb%3b'/%3e%3c/svg%3e"; var img$2 = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3c!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg width='100%25' height='100%25' viewBox='0 0 512 512' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve' xmlns:serif='http://www.serif.com/' style='fill-rule:evenodd%3bclip-rule:evenodd%3bstroke-linejoin:round%3bstroke-miterlimit:2%3b'%3e%3cpath d='M386.576%2c386.574c-12.567%2c12.568 -33.514%2c12.568 -46.08%2c0.002l-84.496%2c-84.498l-84.497%2c84.498c-12.566%2c12.566 -33.512%2c12.566 -46.079%2c-0c-12.566%2c-12.568 -12.566%2c-33.513 0%2c-46.079l84.497%2c-84.496l-84.497%2c-84.498c-12.566%2c-12.566 -12.566%2c-33.511 0%2c-46.079c12.567%2c-12.565 33.513%2c-12.565 46.079%2c-0l84.496%2c84.498l84.497%2c-84.498c12.566%2c-12.565 33.512%2c-12.565 46.079%2c-0c12.566%2c12.568 12.566%2c33.513 0%2c46.079l-84.497%2c84.496l84.498%2c84.498c12.565%2c12.566 12.565%2c33.51 0%2c46.077Z' style='fill:white%3b'/%3e%3c/svg%3e"; var img$1 = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3c!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg width='100%25' height='100%25' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve' xmlns:serif='http://www.serif.com/' style='fill-rule:evenodd%3bclip-rule:evenodd%3bstroke-linejoin:round%3bstroke-miterlimit:2%3b'%3e%3c/svg%3e"; var img = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3c!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3e%3csvg width='100%25' height='100%25' viewBox='0 0 512 512' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve' xmlns:serif='http://www.serif.com/' style='fill-rule:evenodd%3bclip-rule:evenodd%3bstroke-linejoin:round%3bstroke-miterlimit:2%3b'%3e%3cpath d='M202.677%2c396c-6.857%2c0 -13.038%2c-4.13 -15.662%2c-10.465c-2.624%2c-6.335 -1.174%2c-13.626 3.674%2c-18.474c44.911%2c-44.911 130.904%2c-130.904 176.025%2c-176.025c4.906%2c-4.906 12.285%2c-6.374 18.696%2c-3.719c6.41%2c2.656 10.59%2c8.911 10.59%2c15.85c0%2c45.295 0%2c117.022 0%2c159.048c0%2c18.659 -15.126%2c33.785 -33.785%2c33.785l-159.538%2c0Z' style='fill:white%3b'/%3e%3cpath d='M303.059%2c116c6.881%2c-0 13.084%2c4.145 15.717%2c10.502c2.634%2c6.357 1.178%2c13.674 -3.687%2c18.54c-43.748%2c43.748 -126.088%2c126.087 -169.914%2c169.913c-4.888%2c4.888 -12.239%2c6.35 -18.625%2c3.705c-6.386%2c-2.645 -10.55%2c-8.877 -10.55%2c-15.789c-0%2c-43.783 -0%2c-112.154 -0%2c-152.928c-0%2c-18.746 15.197%2c-33.943 33.943%2c-33.943l153.116%2c-0Z' style='fill:white%3b'/%3e%3c/svg%3e"; const IMAGE_CHECK = img$3; const IMAGE_CLOSE = img$2; const IMAGE_EMPTY = img$1; const IMAGE_EXPAND = img; const GRID_SIZE = 25; const TOOLTIP_Y_OFFSET = '0.3em'; const BACKGROUNDS = { DARK: 0, MID: 1, LIGHT: 2, FADED: 3, }; const TRAIT = { SHADOW: 'shadow', DARKNESS: 'darkness', BACKGROUND_DARK: 'background-dark', BACKGROUND_LIGHT: 'background-light', BUTTON_DARK: 'button-dark', BUTTON_LIGHT: 'button-light', BLACKLIGHT: 'blacklight', DARKLIGHT: 'darklight', MIDLIGHT: 'midlight', HIGHLIGHT: 'highlight', TEXT_DARK: 'text-dark', TEXT: 'text', TEXT_LIGHT: 'text-light', ICON_DARK: 'icon-dark', ICON: 'icon', ICON_LIGHT: 'icon-light', COMPLEMENT: 'complement', TRIADIC1: 'triadic1', TRIADIC2: 'triadic2', TRIADIC3: 'triadic3', TRIADIC4: 'triadic4', }; const RESIZERS = { TOP: 'top', BOTTOM: 'bottom', LEFT: 'left', RIGHT: 'right', TOP_LEFT: 'top-left', TOP_RIGHT: 'top-right', BOTTOM_LEFT: 'bottom-left', BOTTOM_RIGHT: 'bottom-right', }; const GRAPH_LINE_TYPES = { STRAIGHT: 'straight', CURVE: 'curve', ZIGZAG: 'zigzag', }; const GRAPH_GRID_TYPES = { LINES: 'lines', DOTS: 'dots', }; const NODE_TYPES = { INPUT: 'input', OUTPUT: 'output', }; class Css { static getVariable(variable, element) { variable = String(variable); if (!variable.startsWith('--')) variable = '--' + variable; if (element && element.isElement) element = element.dom; if (!element || !(element instanceof HTMLElement)) { element = document.querySelector(':root'); } return getComputedStyle(element).getPropertyValue(variable); } static setVariable(variable, valueAsString, element) { variable = String(variable); if (!variable.startsWith('--')) variable = '--' + variable; if (element && element.isElement) element = element.dom; if (!element || !(element instanceof HTMLElement)) { element = document.querySelector(':root'); } element.style.setProperty(variable, valueAsString); } static baseSize() { return parseFloat(getComputedStyle(document.querySelector(':root')).fontSize); } static fontSize(element = document.body) { return parseFloat(getComputedStyle(element).fontSize); } static guiScale(element = document.body) { return Css.fontSize(element) / Css.baseSize(); } static getTextWidth(text, font) { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); ctx.font = font; return ctx.measureText(text).width; } static getFontCssFromElement(element = document.body) { const fontWeight = getComputedStyle(element).fontWeight || 'normal'; const fontSize = getComputedStyle(element).fontSize || '16px'; const fontFamily = getComputedStyle(element).fontFamily || 'Arial'; return `${fontWeight} ${fontSize} ${fontFamily}`; } static parentElementWithCSS(element, cssKey, cssValueOrArrayOfPossibleValues) { const values = (Array.isArray(cssValueOrArrayOfPossibleValues)) ? cssValueOrArrayOfPossibleValues : [ cssValueOrArrayOfPossibleValues ]; cssKey = cssKey.replace(/([A-Z])/g, "-$1").toLowerCase(); if (element.isElement && element.dom) element = element.dom; let parent = element.parentElement; while (parent) { const defaultView = (parent.ownerDocument || document).defaultView; const computed = defaultView.getComputedStyle(parent, null); const property = computed.getPropertyValue(cssKey); if (property) { for (let i = 0; i < values.length; i++) { const cssValue = values[i]; if (property == cssValue) return parent; } } parent = parent.parentElement; } return undefined; } static parseSize(size) { if (typeof size === 'string') { if (size.includes('%') || size.includes('px') || size.includes('em') || size.includes('rem') || size.includes('ch') || size.includes('ex') || size.includes('cap') || size.includes('vw') || size.includes('vh') || size.includes('vmin') || size.includes('vmax')) { return size; } else { return parseInt(size) + 'px'; } } else { return parseInt(size) + 'px'; } } static toEm(pixels, element = document.body) { const parsedSize = Css.parseSize(pixels); if (parsedSize.includes('px')) { return ((parseFloat(parsedSize) / 10.0) / Css.guiScale(element)) + 'em'; } else if (parsedSize.includes('em')) { return parsedSize; } console.warn(`Css.toEm: Could not convert to em, unit passed in: ${pixels}`); return size; } static toPx(size, element = document.body, dimension = 'w' ) { const parsedSize = Css.parseSize(size); if (parsedSize.includes('%')) { if (element) { const parent = Css.parentElementWithCSS(element, 'position', [ 'relative', 'absolute' ]); if (parent) { if (dimension === 'w') return (parseFloat(size) * 0.01 * parent.offsetWidth) + 'px'; else return (parseFloat(size) * 0.01 * parent.offsetHeight) + 'px'; } } } else if (parsedSize.includes('px')) { return parsedSize; } else if (parsedSize.includes('rem')) { return parseInt((parseFloat(size) * 10.0)) + 'px'; } else if (parsedSize.includes('em')) { return parseInt((parseFloat(size) * 10.0 * Css.guiScale(element))) + 'px'; } console.warn(`Css.toPx: Could not convert to pixels, unit passed in: ${size}`); return parseInt(parsedSize) + 'px'; } } const EDGE_SPACE = 4; const ALIGN = { LEFT: 'left', CENTER: 'center', MIDDLE: 'center', RIGHT: 'right', }; const OVERFLOW = { LEFT: 'left', RIGHT: 'right', }; const POSITION = { OVER: 'over', UNDER: 'under', }; class Popper { static getLeft(dom) { return dom.getBoundingClientRect().left; } static getTop(dom) { return dom.getBoundingClientRect().top; } static getWidth(dom) { return dom.offsetWidth; } static getHeight(dom) { return dom.offsetHeight; } static popOver(dom, parent, align = ALIGN.LEFT, offsetX = 0, offsetY = 0, overflow = OVERFLOW.RIGHT) { return Popper.popOverUnder(dom, parent, POSITION.OVER, align, offsetX, offsetY, overflow); } static popUnder(dom, parent, align = ALIGN.LEFT, offsetX = 0, offsetY = 0, overflow = OVERFLOW.RIGHT) { return Popper.popOverUnder(dom, parent, POSITION.UNDER, align, offsetX, offsetY, overflow); } static popOverUnder(dom, parent, overUnder = POSITION.UNDER, align = ALIGN.LEFT, offsetX = 0, offsetY = 0, overflow = OVERFLOW.RIGHT) { let maxRight = window.innerWidth - EDGE_SPACE; let maxBottom = window.innerHeight - EDGE_SPACE; offsetX = (offsetX) ? parseInt(Css.toPx(offsetX), 10) : 0; offsetY = (offsetY) ? parseInt(Css.toPx(offsetY), 10) : 0; let desiredLeft = Popper.getLeft(parent) + offsetX; if (align === ALIGN.CENTER) { let offset = Popper.getLeft(parent) + ((Popper.getWidth(parent) - Popper.getWidth(dom)) / 2.0); desiredLeft = offset + offsetX; } else if (align === ALIGN.RIGHT) { let offset = Popper.getLeft(parent) + (Popper.getWidth(parent) - Popper.getWidth(dom)); desiredLeft = offset + offsetX; } if (overflow === OVERFLOW.LEFT) { maxRight = Popper.getLeft(parent) + Popper.getWidth(parent); } let rightSide = desiredLeft + Popper.getWidth(dom); if (rightSide > maxRight) desiredLeft -= (rightSide - maxRight); if (desiredLeft < EDGE_SPACE) desiredLeft = EDGE_SPACE; let underTop = Popper.getTop(parent) + Popper.getHeight(parent) + offsetY; let overTop = Popper.getTop(parent) - Popper.getHeight(dom) - offsetY; let bottomSide = underTop + Popper.getHeight(dom); if (bottomSide > maxBottom) overUnder = POSITION.OVER; if (overTop < EDGE_SPACE) overUnder = POSITION.UNDER; let desiredTop = (overUnder === POSITION.UNDER) ? underTop : overTop; if (overUnder === POSITION.UNDER) { bottomSide = desiredTop + Popper.getHeight(dom); if (bottomSide > maxBottom) { desiredTop = maxBottom - Popper.getHeight(dom); if (desiredTop < EDGE_SPACE) desiredTop = EDGE_SPACE; } } dom.style.left = Css.toPx(desiredLeft); dom.style.top = Css.toPx(desiredTop); return overUnder; } } class Iris { static get NAMES() { return COLOR_KEYWORDS; } constructor(r = 0xffffff, g, b, format = '') { this.isColor = true; this.isIris = true; this.type = 'Color'; this.r = 1; this.g = 1; this.b = 1; this.set(r, g, b, format); } copy(colorObject) { return this.set(colorObject); } clone() { return new this.constructor(this.r, this.g, this.b); } set(r = 0, g, b, format = '') { if (arguments.length === 0) { return this.set(0); } else if (r === undefined || r === null || Number.isNaN(r)) { if (g || b) console.warn(`Iris: Passed some valid arguments, however 'r' was ${r}`); } else if (g === undefined && b === undefined) { let value = r; if (typeof value === 'number' || value === 0) { return this.setHex(value); } else if (value && isRGB(value)) { return this.setRGBF(value.r, value.g, value.b); } else if (value && isHSL(value)) { return this.setHSL(value.h * 360, value.s, value.l); } else if (value && isRYB(value)) { return this.setRYB(value.r * 255, value.y * 255, value.b * 255); } else if (Array.isArray(value) && value.length > 2) { const offset = (g != null && ! Number.isNaN(g) && g > 0) ? g : 0; return this.setRGBF(value[offset], value[offset + 1], value[offset + 2]) } else if (typeof value === 'string') { return this.setStyle(value); } } else { switch (format) { case 'rgb': return this.setRGB(r, g, b); case 'hsl': return this.setHSL(r, g, b); case 'ryb': return this.setRYB(r, g, b); default: return this.setRGBF(r, g, b); } } return this; } setColorName(style) { const hex = COLOR_KEYWORDS[ style.toLowerCase() ]; if (hex) return this.setHex(hex); console.warn(`Iris: Unknown color ${style}`); return this; } setHex(hexColor) { hexColor = Math.floor(hexColor); if (hexColor > 0xffffff || hexColor < 0) { console.warn(`Iris: Given decimal outside of range, value was ${hexColor}`); hexColor = clamp(hexColor, 0, 0xffffff); } const r = (hexColor & 0xff0000) >> 16; const g = (hexColor & 0x00ff00) >> 8; const b = (hexColor & 0x0000ff); return this.setRGB(r, g, b); } setHSL(h, s, l) { h = keepInRange(h, 0, 360); s = clamp(s, 0, 1); l = clamp(l, 0, 1); let c = (1 - Math.abs(2 * l - 1)) * s; let x = c * (1 - Math.abs((h / 60) % 2 - 1)); let m = l - (c / 2); let r = 0, g = 0, b = 0; if (h < 60) { r = c; g = x; b = 0; } else if ( 60 <= h && h < 120) { r = x; g = c; b = 0; } else if (120 <= h && h < 180) { r = 0; g = c; b = x; } else if (180 <= h && h < 240) { r = 0; g = x; b = c; } else if (240 <= h && h < 300) { r = x; g = 0; b = c; } else if (300 <= h) { r = c; g = 0; b = x; } this.setRGBF(r + m, g + m, b + m); return this; } setRandom() { return this.setRGBF(Math.random(), Math.random(), Math.random()); }; setRGB(r, g, b) { return this.setRGBF(r / 255, g / 255, b / 255); } setRGBF(r, g, b) { this.r = clamp(r, 0, 1); this.g = clamp(g, 0, 1); this.b = clamp(b, 0, 1); return this; } setRYB(r, y, b) { const hexColor = cubicInterpolation(clamp(r, 0, 255), clamp(y, 0, 255), clamp(b, 0, 255), 255, CUBE.RYB_TO_RGB); return this.setHex(hexColor); } setScalar(scalar) { return this.setRGB(scalar, scalar, scalar); } setScalarF(scalar) { return this.setRGBF(scalar, scalar, scalar); } setStyle(style) { let m; if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) { let color; const name = m[1]; const components = m[2]; switch (name) { case 'rgb': case 'rgba': if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { const r = Math.min(255, parseInt(color[1], 10)); const g = Math.min(255, parseInt(color[2], 10)); const b = Math.min(255, parseInt(color[3], 10)); return this.setRGB(r, g, b); } if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { const r = (Math.min(100, parseInt(color[1], 10)) / 100); const g = (Math.min(100, parseInt(color[2], 10)) / 100); const b = (Math.min(100, parseInt(color[3], 10)) / 100); return this.setRGBF(r, g, b); } break; case 'hsl': case 'hsla': if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { const h = parseFloat(color[1]); const s = parseInt(color[2], 10) / 100; const l = parseInt(color[3], 10) / 100; return this.setHSL(h, s, l); } break; } } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) { const hex = m[1]; const size = hex.length; if (size === 3) { const r = parseInt(hex.charAt(0) + hex.charAt(0), 16); const g = parseInt(hex.charAt(1) + hex.charAt(1), 16); const b = parseInt(hex.charAt(2) + hex.charAt(2), 16); return this.setRGB(r, g, b); } else if (size === 6) { const r = parseInt(hex.charAt(0) + hex.charAt(1), 16); const g = parseInt(hex.charAt(2) + hex.charAt(3), 16); const b = parseInt(hex.charAt(4) + hex.charAt(5), 16); return this.setRGB(r, g, b); } } if (style && style.length > 0) { return this.setColorName(style); } return this; } cssString(alpha ) { return ('rgb(' + this.rgbString(alpha) + ')'); } hex() { return ((this.red() << 16) + (this.green() << 8) + this.blue()); } hexString(inputColorData ){ if (inputColorData) this.set(inputColorData); return Iris.hexString(this.hex()); } static hexString(inputColorData = 0x000000){ _temp.set(inputColorData); return '#' + ('000000' + ((_temp.hex()) >>> 0).toString(16)).slice(-6); } static randomHex() { return _random.setRandom().hex(); } rgbString(alpha) { const rgb = this.red() + ', ' + this.green() + ', ' + this.blue(); return ((alpha !== undefined && alpha !== null) ? String(rgb + ', ' + alpha) : rgb); } toJSON() { return this.hex(); } getHSL(target) { if (target && isHSL(target)) { target.h = hueF(this.hex()); target.s = saturation(this.hex()); target.l = lightness(this.hex()); } else { return { h: hueF(this.hex()), s: saturation(this.hex()), l: lightness(this.hex()) }; } } getRGB(target) { if (target && isHSL(target)) { target.r = this.r; target.g = this.g; target.b = this.b; } else { return { r: this.r, g: this.g, b: this.b }; } } getRYB(target) { let rybAsHex = cubicInterpolation(this.r, this.g, this.b, 1.0, CUBE.RGB_TO_RYB); if (target && isRYB(target)) { target.r = redF(rybAsHex); target.y = greenF(rybAsHex); target.b = blueF(rybAsHex); return target; } return { r: redF(rybAsHex), y: greenF(rybAsHex), b: blueF(rybAsHex) }; } toArray(array = [], offset = 0) { array[offset] = this.r; array[offset + 1] = this.g; array[offset + 2] = this.b; return array; } red() { return clamp(Math.floor(this.r * 255), 0, 255); } green() { return clamp(Math.floor(this.g * 255), 0, 255); } blue() { return clamp(Math.floor(this.b * 255), 0, 255); } redF() { return this.r; } greenF() { return this.g; } blueF() { return this.b; } hue() { return hue(this.hex()); } saturation() { return saturation(this.hex()); } lightness() { return lightness(this.hex()); } hueF() { return hueF(this.hex()); } hueRYB() { for (let i = 1; i < RYB_OFFSET.length; i++) { if (RYB_OFFSET[i] > this.hue()) return i - 2; } } add(color) { if (! color.isColor) console.warn(`Iris: add() was not called with a 'Color' object`); return this.setRGBF(this.r + color.r, this.g + color.g, this.b + color.b); } addScalar(scalar) { return this.setRGB(this.red() + scalar, this.green() + scalar, this.blue() + scalar); } addScalarF(scalar) { return this.setRGBF(this.r + scalar, this.g + scalar, this.b + scalar); } brighten(amount = 0.5 ) { let h = hue(this.hex()); let s = saturation(this.hex()); let l = lightness(this.hex()); l = l + ((1.0 - l) * amount); this.setHSL(h, s, l); return this; } darken(amount = 0.5 ) { let h = hue(this.hex()); let s = saturation(this.hex()); let l = lightness(this.hex()) * amount; return this.setHSL(h, s, l); } greyscale(percent = 1.0, format = 'luminosity') { return this.grayscale(percent, format) } grayscale(percent = 1.0, format = 'luminosity') { let gray = 0; switch (format) { case 'luminosity': gray = (this.r * 0.21) + (this.g * 0.72) + (this.b * 0.07); case 'average': default: gray = (this.r + this.g + this.b) / 3; } percent = clamp(percent, 0, 1); const r = (this.r * (1.0 - percent)) + (percent * gray); const g = (this.g * (1.0 - percent)) + (percent * gray); const b = (this.b * (1.0 - percent)) + (percent * gray); return this.setRGBF(r, g, b); } hslOffset(h, s, l) { return this.setHSL(this.hue() + h, this.saturation() + s, this.lightness() + l); } mix(color, percent = 0.5) { if (! color.isColor) console.warn(`Iris: mix() was not called with a 'Color' object`); percent = clamp(percent, 0, 1); const r = (this.r * (1.0 - percent)) + (percent * color.r); const g = (this.g * (1.0 - percent)) + (percent * color.g); const b = (this.b * (1.0 - percent)) + (percent * color.b); return this.setRGBF(r, g, b); } multiply(color) { if (! color.isColor) console.warn(`Iris: multiply() was not called with a 'Color' object`); return this.setRGBF(this.r * color.r, this.g * color.g, this.b * color.b); } multiplyScalar(scalar) { return this.setRGBF(this.r * scalar, this.g * scalar, this.b * scalar); } rgbComplementary() { return this.rgbRotateHue(180); } rgbRotateHue(degrees = 90) { const newHue = keepInRange(this.hue() + degrees); return this.setHSL(newHue, this.saturation(), this.lightness()); } rybAdjust() { return this.setHSL(hue(matchSpectrum(this.hue(), SPECTRUM.RYB)), this.saturation(), this.lightness()); } rybComplementary() { return this.rybRotateHue(180); } rybRotateHue(degrees = 90) { const newHue = keepInRange(this.hueRYB() + degrees); return this.setHSL(hue(matchSpectrum(newHue, SPECTRUM.RYB)), this.saturation(), this.lightness()); } subtract(color) { if (! color.isColor) console.warn(`Iris: subtract() was not called with a 'Color' object`); return this.setRGBF(this.r - color.r, this.g - color.g, this.b - color.b); } equals(color) { if (! color.isColor) console.warn(`Iris: equals() was not called with a 'Color' object`); return (fuzzy(this.r, color.r) && fuzzy(this.g, color.g) && fuzzy(this.b, color.b)); } isEqual(color) { return this.equals(color); } isDark() { const h = this.hue(); const l = this.lightness(); return ((l < 0.60 && (h >= 210 || h <= 27)) || (l <= 0.32)); } isLight() { return (! this.isDark()); } } function isRGB(object) { return (object.r !== undefined && object.g !== undefined && object.b !== undefined); } function isHSL(object) { return (object.h !== undefined && object.s !== undefined && object.l !== undefined); } function isRYB(object) { return (object.r !== undefined && object.y !== undefined && object.b !== undefined); } function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); } function red(hexColor) { return clamp((hexColor & 0xff0000) >> 16, 0, 255); } function green(hexColor) { return clamp((hexColor & 0x00ff00) >> 8, 0, 255); } function blue(hexColor) { return clamp((hexColor & 0x0000ff), 0, 255); } function redF(hexColor) { return red(hexColor) / 255.0; } function greenF(hexColor) { return green(hexColor) / 255.0; } function blueF(hexColor) { return blue(hexColor) / 255.0; } function hue(hexColor) { return hsl(hexColor, 'h'); } function hueF(hexColor) { return hue(hexColor) / 360; } function saturation(hexColor) { return hsl(hexColor, 's'); } function lightness(hexColor) { return hsl(hexColor, 'l'); } function fuzzy(a, b, tolerance = 0.0015) { return ((a < (b + tolerance)) && (a > (b - tolerance))); } function keepInRange(value, min = 0, max = 360) { while (value >= max) value -= (max - min); while (value < min) value += (max - min); return value; } let _hslHex, _hslH, _hslS, _hslL; function hsl(hexColor, channel = 'h') { if (hexColor !== _hslHex) { if (hexColor === undefined || hexColor === null) return 0; const r = redF(hexColor), g = greenF(hexColor), b = blueF(hexColor); const max = Math.max(r, g, b), min = Math.min(r, g, b); const delta = max - min; _hslL = (max + min) / 2; if (delta === 0) { _hslH = _hslS = 0; } else { _hslS = (_hslL <= 0.5) ? (delta / (max + min)) : (delta / (2 - max - min)); switch (max) { case r: _hslH = (g - b) / delta + (g < b ? 6 : 0); break; case g: _hslH = (b - r) / delta + 2; break; case b: _hslH = (r - g) / delta + 4; break; } _hslH = Math.round(_hslH * 60); if (_hslH < 0) _hslH += 360; } _hslHex = hexColor; } switch (channel) { case 'h': return _hslH; case 's': return _hslS; case 'l': return _hslL; default: console.warn(`Iris: Unknown channel (${channel}) requested in hsl()`); } return 0; } const _interpolate = new Iris(); const _mix1 = new Iris(); const _mix2 = new Iris(); const _random = new Iris(); const _temp = new Iris(); function matchSpectrum(matchHue, spectrum = SPECTRUM.RYB) { let colorDegrees = 360 / spectrum.length; let degreeCount = colorDegrees; let stopCount = 0; for (let i = 0; i < spectrum.length; i++) { if (matchHue < degreeCount) { let percent = (degreeCount - matchHue) / colorDegrees; _mix1.set(spectrum[stopCount + 1]); return _mix1.mix(_mix2.set(spectrum[stopCount]), percent).hex(); } else { degreeCount = degreeCount + colorDegrees; stopCount = stopCount + 1; } } } function cubicInterpolation(v1, v2, v3, scale = 255, table = CUBE.RYB_TO_RGB) { v1 = clamp(v1 / scale, 0, 1); v2 = clamp(v2 / scale, 0, 1); v3 = clamp(v3 / scale, 0, 1); const f0 = table[0], f1 = table[1], f2 = table[2], f3 = table[3]; const f4 = table[4], f5 = table[5], f6 = table[6], f7 = table[7]; const i1 = 1.0 - v1; const i2 = 1.0 - v2; const i3 = 1.0 - v3; const c0 = i1 * i2 * i3; const c1 = i1 * i2 * v3; const c2 = i1 * v2 * i3; const c3 = v1 * i2 * i3; const c4 = i1 * v2 * v3; const c5 = v1 * i2 * v3; const c6 = v1 * v2 * i3; const v7 = v1 * v2 * v3; const o1 = c0*f0[0] + c1*f1[0] + c2*f2[0] + c3*f3[0] + c4*f4[0] + c5*f5[0] + c6*f6[0] + v7*f7[0]; const o2 = c0*f0[1] + c1*f1[1] + c2*f2[1] + c3*f3[1] + c4*f4[1] + c5*f5[1] + c6*f6[1] + v7*f7[1]; const o3 = c0*f0[2] + c1*f1[2] + c2*f2[2] + c3*f3[2] + c4*f4[2] + c5*f5[2] + c6*f6[2] + v7*f7[2]; return _interpolate.set(o1, o2, o3, 'gl').hex(); } const CUBE = { RYB_TO_RGB: [ [ 1.000, 1.000, 1.000 ], [ 0.163, 0.373, 0.600 ], [ 1.000, 1.000, 0.000 ], [ 1.000, 0.000, 0.000 ], [ 0.000, 0.660, 0.200 ], [ 0.500, 0.000, 0.500 ], [ 1.000, 0.500, 0.000 ], [ 0.000, 0.000, 0.000 ] ], RGB_TO_RYB: [ [ 1.000, 1.000, 1.000 ], [ 0.000, 0.000, 1.000 ], [ 0.000, 1.000, 0.483 ], [ 1.000, 0.000, 0.000 ], [ 0.000, 0.053, 0.210 ], [ 0.309, 0.000, 0.469 ], [ 0.000, 1.000, 0.000 ], [ 0.000, 0.000, 0.000 ] ] }; const SPECTRUM = { RYB: [ 0xFF0000, 0xFF4900, 0xFF7400, 0xFF9200, 0xFFAA00, 0xFFBF00, 0xFFD300, 0xFFE800, 0xFFFF00, 0xCCF600, 0x9FEE00, 0x67E300, 0x00CC00, 0x00AF64, 0x009999, 0x0B61A4, 0x1240AB, 0x1B1BB3, 0x3914AF, 0x530FAD, 0x7109AA, 0xA600A6, 0xCD0074, 0xE40045, 0xFF0000 ] }; const RYB_OFFSET = [ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 32, 33, 33, 34, 34, 35, 35, 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 59, 59, 59, 60, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 68, 68, 69, 70, 70, 71, 72, 72, 73, 73, 74, 75, 75, 76, 77, 77, 78, 79, 79, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, 88, 89, 90, 91, 92, 93, 95, 96, 98, 100, 102, 104, 105, 107, 109, 111, 113, 115, 116, 118, 120, 122, 125, 127, 129, 131, 134, 136, 138, 141, 143, 145, 147, 150, 152, 154, 156, 158, 159, 161, 163, 165, 166, 168, 170, 171, 173, 175, 177, 178, 180, 182, 184, 185, 187, 189, 191, 192, 194, 196, 198, 199, 201, 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 228, 229, 230, 232, 233, 234, 235, 236, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 251, 252, 253, 254, 255, 256, 257, 257, 258, 259, 260, 260, 261, 262, 263, 264, 264, 265, 266, 267, 268, 268, 269, 270, 271, 272, 273, 274, 274, 275, 276, 277, 278, 279, 280, 282, 283, 284, 286, 287, 289, 290, 292, 293, 294, 296, 297, 299, 300, 302, 303, 305, 307, 309, 310, 312, 314, 316, 317, 319, 321, 323, 324, 326, 327, 328, 329, 330, 331, 332, 333, 334, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 347, 348, 349, 350, 352, 353, 354, 355, 356, 358, 359, 999 ]; const COLOR_KEYWORDS = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, 'transparent': 0x000000, 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; const _clr$2 = new Iris(); const _icon = new Iris(); const _icon_light = new Iris(); const _icon_dark = new Iris(); const _complement = new Iris(); const _triadic1 = new Iris(); const _triadic2 = new Iris(); const _triadic3 = new Iris(); const _triadic4 = new Iris(); let _background = BACKGROUNDS.DARK; let _color$3 = 0x00b4af; let _tint = 0.0; let _saturation = 0.0; class ColorScheme { static changeBackground(background) { if (background === undefined || background === null) return; _background = background; ColorScheme.updateCSS(); } static changeColor(color, tint, saturation) { if (color === undefined || color === null) return; _color$3 = _clr$2.set(color).hex(); _tint = (tint !== undefined) ? tint : _tint; _saturation = (saturation !== undefined) ? saturation : _saturation; _icon.set(color); _icon_light.copy(_icon).brighten(); _icon_dark.copy(_icon).darken(); _complement.copy(_icon).rybRotateHue(180).brighten(0.2); _triadic1.copy(_icon).rybRotateHue(120).brighten(0.2); _triadic2.copy(_complement).rybRotateHue(120).brighten(0.2); _triadic3.copy(_icon).rybRotateHue(90).brighten(0.2); _triadic4.copy(_complement).rybRotateHue(90).brighten(0.2); ColorScheme.updateCSS(); } static updateCSS() { Css.setVariable('--shadow', _clr$2.set(ColorScheme.color(TRAIT.SHADOW)).rgbString()); Css.setVariable('--darkness', _clr$2.set(ColorScheme.color(TRAIT.DARKNESS)).rgbString()); Css.setVariable('--background-dark', _clr$2.set(ColorScheme.color(TRAIT.BACKGROUND_DARK)).rgbString()); Css.setVariable('--background-light', _clr$2.set(ColorScheme.color(TRAIT.BACKGROUND_LIGHT)).rgbString()); Css.setVariable('--button-dark', _clr$2.set(ColorScheme.color(TRAIT.BUTTON_DARK)).rgbString()); Css.setVariable('--button-light', _clr$2.set(ColorScheme.color(TRAIT.BUTTON_LIGHT)).rgbString()); Css.setVariable('--text-dark', _clr$2.set(ColorScheme.color(TRAIT.TEXT_DARK)).rgbString()); Css.setVariable('--text', _clr$2.set(ColorScheme.color(TRAIT.TEXT)).rgbString()); Css.setVariable('--text-light', _clr$2.set(ColorScheme.color(TRAIT.TEXT_LIGHT)).rgbString()); Css.setVariable('--blacklight', _clr$2.set(ColorScheme.color(TRAIT.BLACKLIGHT)).rgbString()); Css.setVariable('--darklight', _clr$2.set(ColorScheme.color(TRAIT.DARKLIGHT)).rgbString()); Css.setVariable('--midlight', _clr$2.set(ColorScheme.color(TRAIT.MIDLIGHT)).rgbString()); Css.setVariable('--highlight', _clr$2.set(ColorScheme.color(TRAIT.HIGHLIGHT)).rgbString()); Css.setVariable('--icon-dark', _clr$2.set(ColorScheme.color(TRAIT.ICON_DARK)).rgbString()); Css.setVariable('--icon', _clr$2.set(ColorScheme.color(TRAIT.ICON)).rgbString()); Css.setVariable('--icon-light', _clr$2.set(ColorScheme.color(TRAIT.ICON_LIGHT)).rgbString()); Css.setVariable('--complement', _clr$2.set(ColorScheme.color(TRAIT.COMPLEMENT)).rgbString()); Css.setVariable('--triadic1', _clr$2.set(ColorScheme.color(TRAIT.TRIADIC1)).rgbString()); Css.setVariable('--triadic2', _clr$2.set(ColorScheme.color(TRAIT.TRIADIC2)).rgbString()); Css.setVariable('--triadic3', _clr$2.set(ColorScheme.color(TRAIT.TRIADIC3)).rgbString()); Css.setVariable('--triadic4', _clr$2.set(ColorScheme.color(TRAIT.TRIADIC4)).rgbString()); Css.setVariable('--bright', (_background == BACKGROUNDS.LIGHT) ? '0' : '1'); const startHue = _clr$2.set(0x00b4af).hue(); const newHue = _clr$2.set(ColorScheme.color(TRAIT.ICON, true )).hue(); const diffHue = `${newHue - startHue}deg`; Css.setVariable('--rotate-hue', diffHue); } static color(guiColor, ignoreSaturation = false) { _clr$2.set(0); let tint = _tint; let saturation = _saturation; let darkness = 0; let lightness = 0; switch (_background) { case BACKGROUNDS.DARK: break; case BACKGROUNDS.MID: tint *= 0.2; lightness = 0.2; break; case BACKGROUNDS.LIGHT: break; case BACKGROUNDS.FADED: tint *= 0.1; lightness = 0.4; break; } if (_background == BACKGROUNDS.LIGHT) { switch (guiColor) { case TRAIT.SHADOW: _clr$2.set(140, 140, 140, 'rgb'); break; case TRAIT.BACKGROUND_DARK: _clr$2.set(180, 180, 180, 'rgb'); break; case TRAIT.BACKGROUND_LIGHT: _clr$2.set(190, 190, 190, 'rgb'); break; case TRAIT.BUTTON_DARK: _clr$2.set(200, 200, 200, 'rgb'); break; case TRAIT.BUTTON_LIGHT: _clr$2.set(210, 210, 210, 'rgb'); break; case TRAIT.TEXT_DARK: _clr$2.set( 80, 80, 80, 'rgb'); break; case TRAIT.TEXT: _clr$2.set( 50, 50, 50, 'rgb'); break; case TRAIT.TEXT_LIGHT: _clr$2.set( 25, 25, 25, 'rgb'); break; case TRAIT.BLACKLIGHT: _clr$2.set(255, 255, 255, 'rgb'); break; case TRAIT.DARKLIGHT: _clr$2.set(200, 200, 200, 'rgb'); break; case TRAIT.MIDLIGHT: _clr$2.set(220, 220, 220, 'rgb'); break; case TRAIT.HIGHLIGHT: _clr$2.set( 0, 0, 0, 'rgb'); break; } } else { switch (guiColor) { case TRAIT.SHADOW: _clr$2.set( 0, 0, 0, 'rgb'); tint = 0; break; case TRAIT.BACKGROUND_DARK: _clr$2.set( 24, 24, 24, 'rgb'); break; case TRAIT.BACKGROUND_LIGHT: _clr$2.set( 32, 32, 32, 'rgb'); break; case TRAIT.BUTTON_DARK: _clr$2.set( 40, 40, 40, 'rgb'); break; case TRAIT.BUTTON_LIGHT: _clr$2.set( 60, 60, 60, 'rgb'); break; case TRAIT.TEXT_DARK: _clr$2.set(100, 100, 100, 'rgb'); break; case TRAIT.TEXT: _clr$2.set(190, 190, 190, 'rgb'); break; case TRAIT.TEXT_LIGHT: _clr$2.set(225, 225, 225, 'rgb'); break; case TRAIT.BLACKLIGHT: _clr$2.set( 0, 0, 0, 'rgb'); lightness = 0; break; case TRAIT.DARKLIGHT: _clr$2.set( 8, 8, 8, 'rgb'); lightness = 0; break; case TRAIT.MIDLIGHT: _clr$2.set( 85, 85, 85, 'rgb'); break; case TRAIT.HIGHLIGHT: _clr$2.set(255, 255, 255, 'rgb'); break; } if (_background == BACKGROUNDS.MID && guiColor == TRAIT.DARKLIGHT) { _clr$2.set( 64, 64, 64, 'rgb'); } } if (guiColor === TRAIT.DARKNESS) { switch (_background) { case BACKGROUNDS.DARK: _clr$2.set( 0, 0, 0, 'rgb'); break; case BACKGROUNDS.MID: _clr$2.set( 64, 64, 64, 'rgb'); break; case BACKGROUNDS.LIGHT: _clr$2.set(128, 128, 128, 'rgb'); break; case BACKGROUNDS.FADED: _clr$2.set( 0, 0, 0, 'rgb'); break; } } switch (guiColor) { case TRAIT.ICON_DARK: _clr$2.copy(_icon_dark); break; case TRAIT.ICON: _clr$2.copy(_icon); break; case TRAIT.ICON_LIGHT: _clr$2.copy(_icon_light); break; case TRAIT.COMPLEMENT: _clr$2.copy(_complement); break; case TRAIT.TRIADIC1: _clr$2.copy(_triadic1); break; case TRAIT.TRIADIC2: _clr$2.copy(_triadic2); break; case TRAIT.TRIADIC3: _clr$2.copy(_triadic3); break; case TRAIT.TRIADIC4: _clr$2.copy(_triadic4); break; } switch (guiColor) { case TRAIT.COMPLEMENT: case TRAIT.TRIADIC1: case TRAIT.TRIADIC2: case TRAIT.TRIADIC3: case TRAIT.TRIADIC4: saturation = 0.0; case TRAIT.ICON_DARK: case TRAIT.ICON: case TRAIT.ICON_LIGHT: tint = 0; lightness = 0; break; } if (tint !== 0) _clr$2.mix(_icon, tint); if (lightness !== 0) _clr$2.brighten(lightness); if (darkness !== 0) _clr$2.darken(darkness); if (saturation !== 0 && !ignoreSaturation) _clr$2.hslOffset(0, saturation, 0); return _clr$2.hex(); } } class Element { constructor(dom) { const self = this; this.isElement = true; this.dom = dom; this.name = undefined; this.contents = function() { return self; }; this.children = []; this.parent = undefined; } destroy() { clearChildren(this, true ); return this; } add() { for (let i = 0; i < arguments.length; i++) { const element = arguments[i]; addToParent(this.contents(), element); } return this; } addToSelf() { for (let i = 0; i < arguments.length; i++) { const element = arguments[i]; addToParent(this, element); } return this; } clearContents() { clearChildren(this.contents(), false ); return this; } remove() { for (let i = 0; i < arguments.length; i++) { const element = arguments[i]; let removed = removeFromParent(this.contents(), element); if (!removed) removed = removeFromParent(this, element); if (!removed) { } } return this; } setClass(className) { this.dom.className = className; return this; } addClass() { for (let i = 0; i < arguments.length; i ++) { const argument = arguments[i]; this.dom.classList.add(argument); } return this; } hasClass(className) { return this.dom.classList.contains(className); } hasClassWithString(substring) { substring = String(substring).toLowerCase(); const classArray = [...this.dom.classList]; for (let i = 0; i < classArray.length; i++) { const className = classArray[i]; if (className.toLowerCase().includes(substring)) return true; } return false; } removeClass() { for (let i = 0; i < arguments.length; i ++) { const argument = arguments[i]; this.dom.classList.remove(argument); } return this; } setId(id) { this.dom.id = id; if (this.name === undefined) this.name = id; return this; } getId() { return this.dom.id; } setName(name) { this.name = name; return this; } getName() { return (this.name === undefined) ? 'No name' : this.name; } setAttribute(attrib, value) { this.dom.setAttribute(attrib, value); } setDisabled(value = true) { if (value) { this.addClass('osui-disabled'); } else { this.removeClass('osui-disabled'); } this.dom.disabled = value; return this; } selectable(allowSelection) { if (allowSelection) { this.removeClass('osui-unselectable'); } else { this.addClass('osui-unselectable'); } return this; } hide(event = true) { this.setStyle('display', 'none'); if (event) this.dom.dispatchEvent(new Event('hidden')); } display(event = true) { this.setStyle('display', ''); if (event) this.dom.dispatchEvent(new Event('displayed')); } isDisplayed() { return getComputedStyle(this.dom).display != 'none'; } isHidden() { return getComputedStyle(this.dom).display == 'none'; } allowFocus() { this.dom.tabIndex = 0; } focus() { this.dom.focus(); } blur() { this.dom.blur(); } setTextContent(value) { if (value != undefined) this.contents().dom.textContent = value; return this; } getTextContent() { return this.contents().dom.textContent; } setInnerHtml(value) { if (value === undefined || value === null) value = ''; if (typeof this.contents().dom.setHTML === 'function') { this.contents().dom.setHTML(value); } else { this.contents().dom.innerHTML = value; } return this; } getInnerHtml() { return this.contents().dom.innerHTML; } setStyle() { for (let i = 0, l = arguments.length; i < l; i += 2) { const style = arguments[i]; const value = arguments[i + 1]; this.dom.style[style] = value; } return this; } setContentsStyle() {