ngx-input-color
Version:
Angular color input component and color picker (with HSL, HSV, RGB, CMYK, HEX, alpha, eye-dropper, etc)
1,141 lines (1,131 loc) • 180 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, forwardRef, HostListener, ViewChild, Output, Input, ChangeDetectionStrategy, Component, Pipe, ElementRef, Inject, Directive, NgModule } from '@angular/core';
import * as i1$1 from '@angular/forms';
import { FormControl, Validators, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule } from '@angular/forms';
import * as i1 from '@angular/common';
import { CommonModule, DOCUMENT } from '@angular/common';
var ColorFormats;
(function (ColorFormats) {
ColorFormats[ColorFormats["HEX"] = 0] = "HEX";
ColorFormats[ColorFormats["RGBA"] = 1] = "RGBA";
ColorFormats[ColorFormats["HSLA"] = 2] = "HSLA";
ColorFormats[ColorFormats["HSVA"] = 3] = "HSVA";
ColorFormats[ColorFormats["CMYK"] = 4] = "CMYK";
})(ColorFormats || (ColorFormats = {}));
function hexToRgb(hex) {
let h = hex.replace(/^#/, '');
if (h.length === 3)
h = h
.split('')
.map((x) => x + x)
.join('');
if (h.length === 6)
h += 'ff';
if (h.length === 8) {
const r = parseInt(h.slice(0, 2), 16);
const g = parseInt(h.slice(2, 4), 16);
const b = parseInt(h.slice(4, 6), 16);
const a = parseInt(h.slice(6, 8), 16) / 255;
return { r, g, b, a: a };
}
throw new Error('Invalid hex color');
}
function parseRgbString(str) {
const m = str.match(/rgba?\(([^)]+)\)/);
if (!m)
throw new Error('Invalid rgb string');
const parts = m[1].split(',').map((x) => +x.trim());
return {
r: parts[0],
g: parts[1],
b: parts[2],
a: parts[3] !== undefined ? parts[3] : 1,
};
}
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
function parseHslString(str) {
const m = str.match(/hsla?\(([^)]+)\)/i);
if (!m)
throw new Error('Invalid hsl/hsla string');
const parts = m[1].split(',').map((x) => x.trim());
const h = clamp(parseFloat(parts[0]), 0, 360);
const s = clamp(parseFloat(parts[1]), 0, 100);
const l = clamp(parseFloat(parts[2]), 0, 100);
const a = parts[3] !== undefined ? clamp(parseFloat(parts[3]), 0, 1) : 1;
return { h, s, l, a };
}
function parseHsvString(str) {
const m = str.match(/hsva?\(([^)]+)\)/i);
if (!m)
throw new Error('Invalid hsv(a) string');
const parts = m[1].split(',').map((x) => x.trim());
const h = clamp(parseFloat(parts[0]), 0, 360);
const s = clamp(parseFloat(parts[1]), 0, 100);
const v = clamp(parseFloat(parts[2]), 0, 100);
const a = parts[3] !== undefined ? clamp(parseFloat(parts[3]), 0, 1) : 1;
return { h, s, v, a };
}
function parseCmykString(str) {
const m = str.match(/cmyk\(([^)]+)\)/i);
if (!m)
throw new Error('Invalid cmyk string');
const parts = m[1].split(',').map((x) => x.trim());
return {
c: clamp(parseFloat(parts[0]), 0, 100),
m: clamp(parseFloat(parts[1]), 0, 100),
y: clamp(parseFloat(parts[2]), 0, 100),
k: clamp(parseFloat(parts[3]), 0, 100),
};
}
/**
* Take input from [0, n] and return it as [0, 1]
* @hidden
*/
function bound01(n, max) {
if (isOnePointZero(n)) {
n = '100%';
}
const isPercent = isPercentage(n);
n = max === 360 ? n : Math.min(max, Math.max(0, parseFloat(n)));
// Automatically convert percentage into number
if (isPercent) {
n = parseInt(String(n * max), 10) / 100;
}
// Handle floating point rounding errors
if (Math.abs(n - max) < 0.000001) {
return 1;
}
// Convert into [0, 1] range if it isn't already
if (max === 360) {
// If n is a hue given in degrees,
// wrap around out-of-range values into [0, 360] range
// then convert into [0, 1].
n = (n < 0 ? (n % max) + max : n % max) / parseFloat(String(max));
}
else {
// If n not a hue given in degrees
// Convert into [0, 1] range if it isn't already.
n = (n % max) / parseFloat(String(max));
}
return n;
}
/**
* Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
* <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
* @hidden
*/
function isOnePointZero(n) {
return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1;
}
/**
* Check to see if string passed in is a percentage
* @hidden
*/
function isPercentage(n) {
return typeof n === 'string' && n.indexOf('%') !== -1;
}
/**
* Replace a decimal with it's percentage value
* @hidden
*/
function convertToPercentage(n) {
if (Number(n) <= 1) {
return `${Number(n) * 100}%`;
}
return n;
}
/**
* Force a hex value to have 2 characters
* @hidden
*/
function pad2(c) {
return c.length === 1 ? '0' + c : String(c);
}
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
/**
* Handle bounds / percentage checking to conform to CSS color spec
* <http://www.w3.org/TR/css3-color/>
* *Assumes:* r, g, b in [0, 255] or [0, 1]
* *Returns:* { r, g, b } in [0, 255]
*/
function rgbToRgb(r, g, b) {
return {
r: bound01(r, 255) * 255,
g: bound01(g, 255) * 255,
b: bound01(b, 255) * 255,
};
}
/**
* Converts an RGB color value to HSL.
* *Assumes:* r, g, and b are contained in [0, 255]
* *Returns:* { h: 0-360, s: 0-100, l: 0-100 }
*/
function rgbToHsl(r, g, b) {
r = r / 255;
g = g / 255;
b = b / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
let s = 0;
const l = (max + min) / 2;
if (max === min) {
s = 0;
h = 0;
}
else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
h = (h * 360) % 360;
if (h < 0)
h += 360;
return {
h: max === min ? 0 : h,
s: l === 0 || l === 1 ? 0 : s * 100,
l: l * 100,
};
}
/**
* Converts an HSL color value to RGB.
* *Assumes:* h in [0, 360], s and l in [0, 100]
* *Returns:* { r, g, b } in [0, 255]
*/
function hslToRgba(h, s, l, a = 1) {
h = +h;
s = +s;
l = +l;
h = ((h % 360) + 360) % 360;
s = Math.max(0, Math.min(100, s));
l = Math.max(0, Math.min(100, l));
h = h / 360;
s = s / 100;
l = l / 100;
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
}
else {
const hue2rgb = (p, q, t) => {
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t < 1 / 6)
return p + (q - p) * 6 * t;
if (t < 1 / 2)
return q;
if (t < 2 / 3)
return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255),
a: Math.max(0, Math.min(1, a)),
};
}
/**
* Converts an RGB color value to HSV
* *Assumes:* r, g, and b are contained in [0, 255]
* *Returns:* { h: 0-360, s: 0-100, v: 0-100 }
*/
function rgbToHsv(r, g, b) {
r = r / 255;
g = g / 255;
b = b / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
let s = 0;
const v = max;
const d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0;
}
else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
h = (h * 360) % 360;
if (h < 0)
h += 360;
return {
h: max === min ? 0 : h,
s: max === 0 ? 0 : s * 100,
v: v * 100,
};
}
/**
* Converts an HSV color value to RGB.
* *Assumes:* h in [0, 360], s and v in [0, 100]
* *Returns:* { r, g, b } in [0, 255]
*/
function hsvToRgb(h, s, v) {
h = +h;
s = +s;
v = +v;
h = ((h % 360) + 360) % 360;
s = Math.max(0, Math.min(100, s));
v = Math.max(0, Math.min(100, v));
s = s / 100;
v = v / 100;
let r = 0, g = 0, b = 0;
const hi = Math.floor(h / 60) % 6;
const f = h / 60 - Math.floor(h / 60);
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
switch (hi) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
return {
r: Math.max(0, Math.min(255, Math.round(r * 255))),
g: Math.max(0, Math.min(255, Math.round(g * 255))),
b: Math.max(0, Math.min(255, Math.round(b * 255))),
};
}
/**
* Converts an RGB/RGBA color to hex
*/
function rgbaToHex(r, g, b, a = 1, allowAlpha = true, allow3Char = false) {
const toHex = (n) => n.toString(16).padStart(2, '0');
const rHex = toHex(Math.round(r));
const gHex = toHex(Math.round(g));
const bHex = toHex(Math.round(b));
const aHex = toHex(Math.round(a * 255));
// Try compressing to #rgb or #rgba if allowed and all characters are duplicated
if (allow3Char && (!allowAlpha || aHex === 'ff')) {
const canShorten = rHex[0] === rHex[1] && gHex[0] === gHex[1] && bHex[0] === bHex[1] && (!allowAlpha || aHex[0] === aHex[1]);
if (canShorten) {
return '#' + rHex[0] + gHex[0] + bHex[0] + (allowAlpha && aHex !== 'ff' ? aHex[0] : '');
}
}
return '#' + rHex + gHex + bHex + (allowAlpha && aHex !== 'ff' ? aHex : '');
}
/**
* Converts an RGBA color to an ARGB Hex8 string
* Rarely used, but required for "toFilter()"
*
* *Assumes:* r, g, b are contained in the set [0, 255] and a in [0, 1]
* *Returns:* a 8 character argb hex
*/
function rgbaToArgbHex(r, g, b, a) {
const hex = [
pad2(convertDecimalToHex(a)),
pad2(Math.round(r).toString(16)),
pad2(Math.round(g).toString(16)),
pad2(Math.round(b).toString(16)),
];
return hex.join('');
}
/**
* Converts CMYK to RBG
* Assumes c, m, y, k are in the set [0, 100]
*/
function cmykToRgb(c, m, y, k) {
const cConv = c / 100;
const mConv = m / 100;
const yConv = y / 100;
const kConv = k / 100;
const r = 255 * (1 - cConv) * (1 - kConv);
const g = 255 * (1 - mConv) * (1 - kConv);
const b = 255 * (1 - yConv) * (1 - kConv);
return { r, g, b };
}
function rgbToCmyk(r, g, b) {
let c = 1 - r / 255;
let m = 1 - g / 255;
let y = 1 - b / 255;
let k = Math.min(c, m, y);
if (k === 1) {
c = 0;
m = 0;
y = 0;
}
else {
c = ((c - k) / (1 - k)) * 100;
m = ((m - k) / (1 - k)) * 100;
y = ((y - k) / (1 - k)) * 100;
}
k *= 100;
return {
c: Math.round(c),
m: Math.round(m),
y: Math.round(y),
k: Math.round(k),
};
}
/** Converts a decimal to a hex value */
function convertDecimalToHex(d) {
return Math.round(parseFloat(d) * 255).toString(16);
}
/** Converts a hex value to a decimal */
function convertHexToDecimal(h) {
return parseIntFromHex(h) / 255;
}
/** Parse a base-16 hex value into a base-10 integer */
function parseIntFromHex(val) {
return parseInt(val, 16);
}
function numberInputToObject(color) {
return {
r: color >> 16,
g: (color & 0xff00) >> 8,
b: color & 0xff,
};
}
function rgbToHslaString(r, g, b, a = 1) {
const { h, s, l } = rgbToHsl(r, g, b);
return `hsla(${Math.round(h)}, ${Math.round(s)}%, ${Math.round(l)}%, ${+a.toFixed(2)})`;
}
function rgbToHsvString(r, g, b, a = 1) {
const { h, s, v } = rgbToHsv(r, g, b);
return `hsva(${Math.round(h)}, ${Math.round(s)}%, ${Math.round(v)}%, ${+a.toFixed(2)})`;
}
function rgbToCmykString(r, g, b) {
const { c, m, y, k } = rgbToCmyk(r, g, b);
return `cmyk(${Math.round(c)}%, ${Math.round(m)}%, ${Math.round(y)}%, ${Math.round(k)}%)`;
}
// List of all CSS color names and their hex values (W3C + extended)
const colorNames = {
aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#00ffff', aquamarine: '#7fffd4', azure: '#f0ffff',
beige: '#f5f5dc', bisque: '#ffe4c4', black: '#000000', blanchedalmond: '#ffebcd', blue: '#0000ff',
blueviolet: '#8a2be2', brown: '#a52a2a', burlywood: '#deb887', cadetblue: '#5f9ea0', chartreuse: '#7fff00',
chocolate: '#d2691e', coral: '#ff7f50', cornflowerblue: '#6495ed', cornsilk: '#fff8dc', crimson: '#dc143c',
cyan: '#00ffff', darkblue: '#00008b', darkcyan: '#008b8b', darkgoldenrod: '#b8860b', darkgray: '#a9a9a9',
darkgreen: '#006400', darkgrey: '#a9a9a9', darkkhaki: '#bdb76b', darkmagenta: '#8b008b', darkolivegreen: '#556b2f',
darkorange: '#ff8c00', darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a', darkseagreen: '#8fbc8f',
darkslateblue: '#483d8b', darkslategray: '#2f4f4f', darkslategrey: '#2f4f4f', darkturquoise: '#00ced1',
darkviolet: '#9400d3', deeppink: '#ff1493', deepskyblue: '#00bfff', dimgray: '#696969', dimgrey: '#696969',
dodgerblue: '#1e90ff', firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22', fuchsia: '#ff00ff',
gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff', gold: '#ffd700', goldenrod: '#daa520', gray: '#808080',
green: '#008000', greenyellow: '#adff2f', grey: '#808080', honeydew: '#f0fff0', hotpink: '#ff69b4',
indianred: '#cd5c5c', indigo: '#4b0082', ivory: '#fffff0', khaki: '#f0e68c', lavender: '#e6e6fa',
lavenderblush: '#fff0f5', lawngreen: '#7cfc00', lemonchiffon: '#fffacd', lightblue: '#add8e6', lightcoral: '#f08080',
lightcyan: '#e0ffff', lightgoldenrodyellow: '#fafad2', lightgray: '#d3d3d3', lightgreen: '#90ee90', lightgrey: '#d3d3d3',
lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa', lightskyblue: '#87cefa', lightslategray: '#778899',
lightslategrey: '#778899', lightsteelblue: '#b0c4de', lightyellow: '#ffffe0', lime: '#00ff00', limegreen: '#32cd32',
linen: '#faf0e6', magenta: '#ff00ff', maroon: '#800000', mediumaquamarine: '#66cdaa', mediumblue: '#0000cd',
mediumorchid: '#ba55d3', mediumpurple: '#9370db', mediumseagreen: '#3cb371', mediumslateblue: '#7b68ee',
mediumspringgreen: '#00fa9a', mediumturquoise: '#48d1cc', mediumvioletred: '#c71585', midnightblue: '#191970',
mintcream: '#f5fffa', mistyrose: '#ffe4e1', moccasin: '#ffe4b5', navajowhite: '#ffdead', navy: '#000080',
oldlace: '#fdf5e6', olive: '#808000', olivedrab: '#6b8e23', orange: '#ffa500', orangered: '#ff4500',
orchid: '#da70d6', palegoldenrod: '#eee8aa', palegreen: '#98fb98', paleturquoise: '#afeeee', palevioletred: '#db7093',
papayawhip: '#ffefd5', peachpuff: '#ffdab9', peru: '#cd853f', pink: '#ffc0cb', plum: '#dda0dd', powderblue: '#b0e0e6',
purple: '#800080', rebeccapurple: '#663399', red: '#ff0000', rosybrown: '#bc8f8f', royalblue: '#4169e1',
saddlebrown: '#8b4513', salmon: '#fa8072', sandybrown: '#f4a460', seagreen: '#2e8b57', seashell: '#fff5ee',
sienna: '#a0522d', silver: '#c0c0c0', skyblue: '#87ceeb', slateblue: '#6a5acd', slategray: '#708090',
slategrey: '#708090', snow: '#fffafa', springgreen: '#00ff7f', steelblue: '#4682b4', tan: '#d2b48c',
teal: '#008080', thistle: '#d8bfd8', tomato: '#ff6347', turquoise: '#40e0d0', violet: '#ee82ee', wheat: '#f5deb3',
white: '#ffffff', whitesmoke: '#f5f5f5', yellow: '#ffff00', yellowgreen: '#9acd32'
};
class NgxColor {
constructor(input) {
this._rgb = { r: 0, g: 0, b: 0, a: 1 };
this._name = '';
if (!input)
return;
if (input instanceof NgxColor) {
this._rgb = { ...input._rgb };
this._name = input._name;
return;
}
if (typeof input === 'object') {
if ('r' in input && 'g' in input && 'b' in input) {
this._rgb = { r: +input.r, g: +input.g, b: +input.b, a: input.a !== undefined ? +input.a : 1 };
return;
}
if ('h' in input && 's' in input && 'l' in input) {
this._rgb = NgxColor.hslaToRgba(input);
return;
}
if ('h' in input && 's' in input && 'v' in input) {
this._rgb = NgxColor.hsvaToRgba(input);
return;
}
if ('c' in input && 'm' in input && 'y' in input && 'k' in input) {
this._rgb = NgxColor.cmykToRgba(input);
return;
}
}
if (typeof input === 'string') {
const name = input.trim().toLowerCase();
if (colorNames[name]) {
this._rgb = hexToRgb(colorNames[name]);
this._name = name;
return;
}
else if (/^#?[0-9a-f]{3,8}$/i.test(name)) {
this._rgb = hexToRgb(name);
return;
}
if (name.includes('rgb')) {
this._rgb = parseRgbString(name);
return;
}
if (name.includes('hsl')) {
this._rgb = NgxColor.hslaToRgba(parseHslString(name));
return;
}
if (name.includes('hsv')) {
this._rgb = NgxColor.hsvaToRgba(parseHsvString(name));
return;
}
if (name.includes('cmyk')) {
this._rgb = NgxColor.cmykToRgba(parseCmykString(name));
return;
}
throw new Error('Unknown color string: ' + input);
}
}
get isValid() {
return (typeof this._rgb.r === 'number' &&
typeof this._rgb.g === 'number' &&
typeof this._rgb.b === 'number' &&
!isNaN(this._rgb.r) &&
!isNaN(this._rgb.g) &&
!isNaN(this._rgb.b));
}
async name() {
if (this._name)
return this._name;
const hex = this.toHexString();
for (const [n, h] of Object.entries(colorNames)) {
if (h.toLowerCase() === hex.toLowerCase())
return n;
}
return '';
}
toRgb() {
return this._rgb;
}
toRgbString() {
const { r, g, b, a } = this.toRgb();
return a === 1
? `rgb(${Math.round(r)},${Math.round(g)},${Math.round(b)})`
: `rgba(${Math.round(r)},${Math.round(g)},${Math.round(b)},${+a.toFixed(3)})`;
}
toHexString(allowAlpha = true) {
const { r, g, b, a } = this.toRgb();
return rgbaToHex(r, g, b, a, allowAlpha && a < 1);
}
toHsl() {
return NgxColor.rgbToHsla(this.toRgb());
}
toHsv() {
return NgxColor.rgbToHsva(this.toRgb());
}
toCmyk() {
return NgxColor.rgbToCmyk(this.toRgb());
}
static cmykToRgba(cmyk) {
const { c, m, y, k } = cmyk;
return { ...cmykToRgb(c, m, y, k), a: cmyk.a !== undefined ? +cmyk.a : 1 };
}
static rgbToCmyk(rgba) {
const { r, g, b } = rgba;
return rgbToCmyk(r, g, b);
}
static rgbToHsla(rgba) {
const { r, g, b, a } = rgba;
return { ...rgbToHsl(r, g, b), a };
}
static rgbToHsva(rgba) {
const { r, g, b, a } = rgba;
return { ...rgbToHsv(r, g, b), a };
}
static hsvaToRgba(hsva) {
const { h, s, v, a } = hsva;
return { ...hsvToRgb(h, s, v), a: a !== undefined ? a : 1 };
}
static hslaToRgba(hsla) {
const { h, s, l, a } = hsla;
return { ...hslToRgba(h, s, l), a: a !== undefined ? a : 1 };
}
equals(other) {
if (!other)
return false;
return this.toHexString().toLowerCase() === other.toHexString().toLowerCase();
}
isDark() {
const { r, g, b, a } = this.toRgb();
return a < 0.5 ? false : 0.299 * r + 0.587 * g + 0.114 * b < 128;
}
isLight() {
return !this.isDark();
}
async getOutputResult(outputType) {
const { r, g, b, a } = this._rgb;
switch (outputType) {
case 'CMYK':
return rgbToCmykString(r, g, b);
case 'HSL':
return rgbToHslaString(r, g, b, a);
case 'HSV':
return rgbToHsvString(r, g, b, a);
case 'RGB':
return a < 1 ? `rgba(${r}, ${g}, ${b}, ${+a.toFixed(2)})` : `rgb(${r}, ${g}, ${b})`;
case 'HEX':
return this.toHexString(true);
default:
let name = await this.name();
return name ?? this.toHexString(true);
}
}
}
var ColorInspector;
(function (ColorInspector) {
ColorInspector[ColorInspector["Picker"] = 0] = "Picker";
ColorInspector[ColorInspector["RGB"] = 1] = "RGB";
ColorInspector[ColorInspector["HSL"] = 2] = "HSL";
ColorInspector[ColorInspector["CMYK"] = 3] = "CMYK";
})(ColorInspector || (ColorInspector = {}));
function getOffsetPosition(evt, parent) {
let position = {
x: 0,
y: 0,
};
if (evt instanceof MouseEvent) {
position.x = evt.pageX;
position.y = evt.pageY;
}
else if (evt.touches && evt.touches.length > 0) {
position.x = evt.touches[0].pageX;
position.y = evt.touches[0].pageY;
}
// Adjust for the parent's offset
let parentRect = parent.getBoundingClientRect();
position.x -= parentRect.left + window.scrollX;
position.y -= parentRect.top + window.scrollY;
return position;
}
class SliderComponent {
constructor() {
this.step = 1;
this.min = 0;
this.max = 100;
this.isBgTransparent = false;
this.change = new EventEmitter();
this.isDragging = false;
this.x = 0;
this.myControl = new FormControl(null);
this.isDisabled = false;
this._onChange = (value) => { };
this._onTouched = () => { };
this._validatorOnChange = () => { };
}
ngOnInit() {
this.myControl.setValidators([Validators.min(this.min), Validators.max(this.max)]);
}
updateRects() {
this.sliderRect = this.slider.nativeElement.getBoundingClientRect();
this.thumbRect = this.thumb.nativeElement.getBoundingClientRect();
}
writeValue(val) {
let value = 0;
if (!val)
value = 0;
else if (+val < +this.min)
value = +this.min;
else if (+val > +this.max)
value = +this.max;
else
value = +val;
this.myControl.setValue(value, { emitEvent: false });
this.updateRects();
const sliderRec = this.sliderRect;
const thumbRec = this.thumbRect;
this.x = ((value - this.min) * (sliderRec.width - thumbRec.width)) / (this.max - this.min);
if (val !== value) {
this.valueChanged(value);
}
}
validate(control) {
return this.myControl.errors;
}
registerOnValidatorChange(fn) {
this._validatorOnChange = fn;
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
setDisabledState(disabled) {
this.isDisabled = disabled;
if (disabled)
this.myControl.disable();
else
this.myControl.enable();
}
dragStart(ev) {
ev.stopPropagation();
ev.preventDefault();
this.isDragging = true;
this.updateRects();
this.updatePosition(ev);
}
onDrag(ev) {
if (!this.isDragging)
return;
this.updatePosition(ev);
}
onResize() {
this.writeValue(this.myControl.value);
}
updatePosition(ev) {
if (!this.isDragging)
return;
if (!this.sliderRect || !this.thumbRect)
this.updateRects();
let position = getOffsetPosition(ev, this.slider.nativeElement);
let thumbRec = this.thumbRect;
position.x -= thumbRec.width / 2;
let sliderRec = this.sliderRect;
if (position.x < 0) {
this.x = 0;
}
else if (position.x > sliderRec.width - thumbRec.width) {
this.x = sliderRec.width - thumbRec.width;
}
else {
this.x = position.x;
}
this.setValueByPosition(thumbRec, sliderRec);
}
setValueByPosition(thumbRec, sliderRec) {
const percentage = this.x / (sliderRec.width - thumbRec.width);
let newValue = this.min + percentage * (this.max - this.min);
const stepDecimalPlaces = (this.step.toString().split('.')[1] || '').length;
newValue = parseFloat((Math.round(newValue / this.step) * this.step).toFixed(stepDecimalPlaces));
let value = Math.min(Math.max(newValue, this.min), this.max);
if (this.myControl.value !== value) {
this.valueChanged(value);
}
}
onDragEnd(ev) {
this.isDragging = false;
}
valueChanged(value) {
this.myControl.setValue(value, { emitEvent: false });
this._onChange(value);
this.change.emit(value);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SliderComponent, isStandalone: true, selector: "slider", inputs: { step: "step", min: "min", max: "max", background: "background", isBgTransparent: "isBgTransparent" }, outputs: { change: "change" }, host: { listeners: { "document:mousemove": "onDrag($event)", "document:touchmove": "onDrag($event)", "window:resize": "onResize($event)", "document:mouseup": "onDragEnd($event)", "document:touchend": "onDragEnd($event)" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SliderComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => SliderComponent),
multi: true,
},
], viewQueries: [{ propertyName: "slider", first: true, predicate: ["slider"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"slider-container\">\r\n <ng-content></ng-content>\r\n <div\r\n #slider\r\n class=\"slider\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\"\r\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\r\n [class.bg-transparent]=\"isBgTransparent\">\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [title]=\"myControl.value\"></div>\r\n </div>\r\n</div>\r\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;background:var(--ngx-slider-bg, rgb(140, 51, 250));height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SliderComponent, decorators: [{
type: Component,
args: [{ selector: 'slider', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SliderComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => SliderComponent),
multi: true,
},
], template: "<div class=\"slider-container\">\r\n <ng-content></ng-content>\r\n <div\r\n #slider\r\n class=\"slider\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\"\r\n [ngStyle]=\"{ '--ngx-slider-bg': background }\"\r\n [class.bg-transparent]=\"isBgTransparent\">\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [title]=\"myControl.value\"></div>\r\n </div>\r\n</div>\r\n", styles: [".slider-container{max-width:100%;padding:1px 0}.slider-container .slider{position:relative;box-shadow:inset #00000013 0 0 0 1px;border-radius:10px;height:12px;width:100%;background:var(--ngx-slider-bg, rgb(140, 51, 250));margin:10px 0}.slider-container .slider.bg-transparent{background:transparent}.slider-container .slider.bg-transparent:before,.slider-container .slider.bg-transparent:after{position:absolute;inset:1px;border-radius:9px}.slider-container .slider.bg-transparent:before{content:\" \";background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:16px 16px;background-position:0 0,0 8px,8px -8px,-8px 0px}.slider-container .slider.bg-transparent:after{content:\" \";background:var(--ngx-slider-bg)}.slider-container .thumb{box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px,inset #fff 0 0 0 6px;background:var(--ngx-slider-bg, rgb(140, 51, 250));height:var(--ngx-thumb-size, 30px);width:var(--ngx-thumb-size, 30px);display:block;border-radius:100%;top:calc(6px - var(--ngx-thumb-size, 30px) / 2);position:absolute;cursor:grab;z-index:100}\n"] }]
}], ctorParameters: () => [], propDecorators: { step: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}], background: [{
type: Input
}], isBgTransparent: [{
type: Input
}], change: [{
type: Output
}], slider: [{
type: ViewChild,
args: ['slider', { static: true }]
}], thumb: [{
type: ViewChild,
args: ['thumb', { static: true }]
}], onDrag: [{
type: HostListener,
args: ['document:mousemove', ['$event']]
}, {
type: HostListener,
args: ['document:touchmove', ['$event']]
}], onResize: [{
type: HostListener,
args: ['window:resize', ['$event']]
}], onDragEnd: [{
type: HostListener,
args: ['document:mouseup', ['$event']]
}, {
type: HostListener,
args: ['document:touchend', ['$event']]
}] } });
class SaturationComponent {
constructor() {
this.color = 'red';
this.step = 1;
this.min = { x: 0, y: 0 };
this.max = { x: 100, y: 100 };
this.change = new EventEmitter();
this.isDragging = false;
this.x = 0;
this.y = 0;
this.myControl = new FormControl(null);
this.isDisabled = false;
this._onChange = (value) => { };
this._onTouched = () => { };
this._validatorOnChange = () => { };
}
updateRects() {
this.saturationRect = this.saturation.nativeElement.getBoundingClientRect();
this.thumbRect = this.thumb.nativeElement.getBoundingClientRect();
}
writeValue(val) {
if (!val)
val = { x: 0, y: 0 };
let value = val;
this.myControl.setValue(value, { emitEvent: false });
this.updateRects();
const saturationRec = this.saturationRect;
const thumbRec = this.thumbRect;
this.x = ((value.x - this.min.x) * (saturationRec.width - thumbRec.width / 2)) / (this.max.x - this.min.x);
this.y = ((value.y - this.min.y) * (saturationRec.height - thumbRec.height / 2)) / (this.max.y - this.min.y);
if (val !== value) {
this.valueChanged(value);
}
}
validate(control) {
return this.myControl.errors;
}
registerOnValidatorChange(fn) {
this._validatorOnChange = fn;
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
setDisabledState(disabled) {
this.isDisabled = disabled;
if (disabled)
this.myControl.disable();
else
this.myControl.enable();
}
dragStart(ev) {
ev.stopPropagation();
ev.preventDefault();
this.isDragging = true;
this.updateRects();
this.updatePosition(ev);
}
onResize() {
this.writeValue(this.myControl.value);
}
onDrag(ev) {
if (!this.isDragging)
return;
this.updatePosition(ev);
}
updatePosition(ev) {
if (!this.isDragging)
return;
if (!this.saturationRect || !this.thumbRect)
this.updateRects();
let position = getOffsetPosition(ev, this.saturation.nativeElement);
let thumbRec = this.thumbRect;
let saturationRec = this.saturationRect;
if (position.x < 0) {
this.x = 0;
}
else if (position.x > saturationRec.width - (thumbRec.width / 2 - 3)) {
this.x = saturationRec.width - (thumbRec.width / 2 - 3);
}
else {
this.x = position.x;
}
// this.x = this.x - thumbRec.width / 2;
if (position.y < 0) {
this.y = 0;
}
else if (position.y > saturationRec.height - (thumbRec.height / 2 - 3)) {
this.y = saturationRec.height - (thumbRec.height / 2 - 3);
}
else {
this.y = position.y;
}
// this.y = this.y - thumbRec.height / 2;
this.setValueByPosition(thumbRec, saturationRec);
}
onDragEnd(ev) {
this.isDragging = false;
}
setValueByPosition(thumbRec, saturationRec) {
const percentageX = this.x / (saturationRec.width - thumbRec.width);
let newValueX = this.min.x + percentageX * (this.max.x - this.min.x);
newValueX = Math.round(newValueX / this.step) * this.step;
let valueX = Math.min(Math.max(newValueX, this.min.x), this.max.x);
//-----------------------------
const percentageY = this.y / (saturationRec.height - thumbRec.height);
let newValueY = this.min.y + percentageY * (this.max.y - this.min.y);
newValueY = Math.round(newValueY / this.step) * this.step;
let valueY = Math.min(Math.max(newValueY, this.min.y), this.max.y);
const newValue = { x: valueX, y: valueY };
if (!this.myControl.value || this.myControl.value.x !== valueX || this.myControl.value.y !== valueY) {
this.valueChanged(newValue);
}
}
valueChanged(value) {
this.myControl.setValue(value, { emitEvent: false });
this._onChange(value);
this.change.emit(value);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SaturationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SaturationComponent, isStandalone: true, selector: "saturation", inputs: { width: "width", height: "height", color: "color", step: "step", min: "min", max: "max" }, outputs: { change: "change" }, host: { listeners: { "window:resize": "onResize($event)", "document:mousemove": "onDrag($event)", "document:touchmove": "onDrag($event)", "document:mouseup": "onDragEnd($event)", "document:touchend": "onDragEnd($event)" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SaturationComponent),
multi: true,
},
], viewQueries: [{ propertyName: "saturation", first: true, predicate: ["saturation"], descendants: true, static: true }, { propertyName: "thumb", first: true, predicate: ["thumb"], descendants: true, static: true }], ngImport: i0, template: "<div\r\n class=\"saturation-container\"\r\n [style.width.px]=\"width\"\r\n [style.height.px]=\"height\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\">\r\n <div class=\"saturation\" #saturation>\r\n <div class=\"s-bg\" [style.background]=\"color\"></div>\r\n <div class=\"s-white\"></div>\r\n <div class=\"s-black\"></div>\r\n </div>\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [style.top.px]=\"y\"></div>\r\n</div>\r\n", styles: [".saturation-container{position:relative;width:100%;height:200px}.saturation-container .thumb{border:3px #000000 solid;box-shadow:inset 0 0 0 2px #fff;width:12px;height:12px;display:block;border-radius:10px;position:absolute;pointer-events:none;cursor:pointer}.saturation{position:absolute;inset:6px;border-radius:4px;overflow:hidden}.saturation .s-white,.saturation .s-black,.saturation .s-bg{position:absolute;inset:0}.saturation .s-white{background:linear-gradient(to right,#fff,#fff0)}.saturation .s-black{background:linear-gradient(to bottom,#0000,#000)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SaturationComponent, decorators: [{
type: Component,
args: [{ selector: 'saturation', standalone: true, imports: [CommonModule], providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SaturationComponent),
multi: true,
},
], template: "<div\r\n class=\"saturation-container\"\r\n [style.width.px]=\"width\"\r\n [style.height.px]=\"height\"\r\n (mousedown)=\"dragStart($event)\"\r\n (touchstart)=\"dragStart($event)\">\r\n <div class=\"saturation\" #saturation>\r\n <div class=\"s-bg\" [style.background]=\"color\"></div>\r\n <div class=\"s-white\"></div>\r\n <div class=\"s-black\"></div>\r\n </div>\r\n <div class=\"thumb\" #thumb [style.left.px]=\"x\" [style.top.px]=\"y\"></div>\r\n</div>\r\n", styles: [".saturation-container{position:relative;width:100%;height:200px}.saturation-container .thumb{border:3px #000000 solid;box-shadow:inset 0 0 0 2px #fff;width:12px;height:12px;display:block;border-radius:10px;position:absolute;pointer-events:none;cursor:pointer}.saturation{position:absolute;inset:6px;border-radius:4px;overflow:hidden}.saturation .s-white,.saturation .s-black,.saturation .s-bg{position:absolute;inset:0}.saturation .s-white{background:linear-gradient(to right,#fff,#fff0)}.saturation .s-black{background:linear-gradient(to bottom,#0000,#000)}\n"] }]
}], ctorParameters: () => [], propDecorators: { width: [{
type: Input
}], height: [{
type: Input
}], color: [{
type: Input
}], step: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}], change: [{
type: Output
}], saturation: [{
type: ViewChild,
args: ['saturation', { static: true }]
}], thumb: [{
type: ViewChild,
args: ['thumb', { static: true }]
}], onResize: [{
type: HostListener,
args: ['window:resize', ['$event']]
}], onDrag: [{
type: HostListener,
args: ['document:mousemove', ['$event']]
}, {
type: HostListener,
args: ['document:touchmove', ['$event']]
}], onDragEnd: [{
type: HostListener,
args: ['document:mouseup', ['$event']]
}, {
type: HostListener,
args: ['document:touchend', ['$event']]
}] } });
class PickerComponent {
set color(c) {
if (c.equals(this.inputColor))
return;
this.inputColor = c;
const shva = c.toHsv();
this.hue = shva.h;
this.board = { x: shva.s, y: 100 - shva.v };
this.alpha = shva.a ?? 1;
const pureColor = new NgxColor({ h: this.hue, s: 100, v: 100, a: 1 });
this.baseColor = pureColor.toHexString(false);
this.alphaBgColor = this.inputColor.toHexString(false);
}
constructor() {
this.hue = 300;
this.baseColor = 'rgb(0,0,0)';
this.alphaBgColor = '#000';
this.board = { x: 1, y: 0 };
this.alpha = 1;
this.simpleMode = false;
this.colorChange = new EventEmitter();
}
ngOnInit() { }
generateColor() {
try {
const hsva = { h: this.hue, s: this.board.x, v: 100 - this.board.y, a: this.alpha };
const color = new NgxColor(hsva);
const pureColor = new NgxColor({ h: this.hue, s: 100, v: 100, a: 1 });
this.baseColor = pureColor.toHexString(false);
this.alphaBgColor = color.toHexString(false);
if (color.equals(this.inputColor) == false) {
this.inputColor = color;
this.colorChange.emit(color);
}
}
catch (error) {
this.colorChange.emit(undefined);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: PickerComponent, selector: "app-picker", inputs: { simpleMode: "simpleMode", color: "color" }, outputs: { colorChange: "colorChange" }, ngImport: i0, template: "<saturation\r\n [height]=\"simpleMode ? 150 : 160\"\r\n [(ngModel)]=\"board\"\r\n [min]=\"{ x: 0, y: 0 }\"\r\n [max]=\"{ x: 100, y: 100 }\"\r\n [step]=\"1\"\r\n [color]=\"baseColor\"\r\n (change)=\"generateColor()\"></saturation>\r\n<slider\r\n [(ngModel)]=\"hue\"\r\n [min]=\"0\"\r\n [max]=\"360\"\r\n [step]=\"1\"\r\n (change)=\"generateColor()\"\r\n background=\"linear-gradient(to right,red 0%,#ff0 17%,lime 33%,cyan 50%,blue 66%,#f0f 83%,red 100%)\"></slider>\r\n<slider\r\n [(ngModel)]=\"alpha\"\r\n [min]=\"0\"\r\n [max]=\"1\"\r\n [step]=\"0.1\"\r\n (change)=\"generateColor()\"\r\n [isBgTransparent]=\"true\"\r\n [background]=\"'linear-gradient(to right,transparent,' + alphaBgColor + ')'\"></slider>\r\n", styles: [".color-sliders{display:flex;gap:5px}.color-sliders .sliders{flex:1}\n"], dependencies: [{ kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SliderComponent, selector: "slider", inputs: ["step", "min", "max", "background", "isBgTransparent"], outputs: ["change"] }, { kind: "component", type: SaturationComponent, selector: "saturation", inputs: ["width", "height", "color", "step", "min", "max"], outputs: ["change"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PickerComponent, decorators: [{
type: Component,
args: [{ selector: 'app-picker', template: "<saturation\r\n [height]=\"simpleMode ? 150 : 160\"\r\n [(ngModel)]=\"board\"\r\n [min]=\"{ x: 0, y: 0 }\"\r\n [max]=\"{ x: 100, y: 100 }\"\r\n [step]=\"1\"\r\n [color]=\"baseColor\"\r\n (change)=\"generateColor()\"></saturation>\r\n<slider\r\n [(ngModel)]=\"hue\"\r\n [min]=\"0\"\r\n [max]=\"360\"\r\n [step]=\"1\"\r\n (change)=\"generateColor()\"\r\n background=\"linear-gradient(to right,red 0%,#ff0 17%,lime 33%,cyan 50%,blue 66%,#f0f 83%,red 100%)\"></slider>\r\n<slider\r\n [(ngModel)]=\"alpha\"\r\n [min]=\"0\"\r\n [max]=\"1\"\r\n [step]=\"0.1\"\r\n (change)=\"generateColor()\"\r\n [isBgTransparent]=\"true\"\r\n [background]=\"'linear-gradient(to right,transparent,' + alphaBgColor + ')'\"></slider>\r\n", styles: [".color-sliders{display:flex;gap:5px}.color-sliders .sliders{flex:1}\n"] }]
}], ctorParameters: () => [], propDecorators: { simpleMode: [{
type: Input
}], color: [{
type: Input
}], colorChange: [{
type: Output
}] } });
class CmykComponent {
set color(c) {
if (c.equals(this.inputColor))
return;
this.inputColor = c;
const cmyk = c.toCmyk();
this.cyan = cmyk.c;
this.magenta = cmyk.m;
this.yellow = cmyk.y;
this.key = cmyk.k;
this.updateSliderBackgrounds(cmyk);
}
constructor() {
this.cyanSliderBackground = '';
this.magentaSliderBackground = '';
this.yellowSliderBackground = '';
this.keySliderBackground = '';
this.cyan = 0;
this.magenta = 0;
this.yellow = 0;
this.key = 0;
this.colorChange = new EventEmitter();
}
ngOnInit() { }
generateColor() {
try {
const cmyk = { c: this.cyan, m: this.magenta, y: this.yellow, k: this.key };
const color = new NgxColor(cmyk);
this.updateSliderBackgrounds(cmyk);
if (color.equals(this.inputColor) == false) {
this.inputColor = color;
this.colorChange.emit(color);
}
}
catch (error) {
this.colorChange.emit(undefined);
}
}
updateSliderBackgrounds(cmyk) {
this.cyanSliderBackground = this.getChannelGradient('c', cmyk);
this.magentaSliderBackground = this.getChannelGradient('m', cmyk);
this.yellowSliderBackground = this.getChannelGradient('y', cmyk);
this.keySliderBackground = this.getChannelGradient('k', cmyk);
}
getChannelGradient(channel, cmyk) {
let baseColor = this.cloneColor(cmyk);
baseColor[channel] = channel == 'k' ? 1 : 0;
let startColor = NgxColor.cmykToRgba(baseColor);
let s = `rgb(${startColor.r}, ${startColor.g}, ${startColor.b})`;
baseColor[channel] = 100;
let endColor = NgxColor.cmykToRgba(baseColor);
let e = `rgb(${endColor.r}, ${endColor.g}, ${endColor.b})`;
return `linear-gradient(to right, ${s},${e})`;
}
isCmykEqual(a, b) {
if (!a || !b)
return false;
return a.c === b.c && a.m === b.m && a.y === b.y && a.k === b.k;
}
cloneColor(cmyk) {
return JSON.parse(JSON.stringify(cmyk));
// return Object.assign({}, cmyk);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CmykComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CmykComponent, selector: "app-cmyk", inputs: { color: "color" }, outputs: { colorChange: "colorChange" }, ngImport: i0, template: "<slider\r\n [(ngModel)]=\"cyan\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n [step]=\"1\"\r\n (change)=\"generateColor()\"\r\n [background]=\"cyanSliderBackground\">\r\n <div class=\"slider-title\">\r\n <span>Cyan</span>\r\n <input type=\"number\" [(ngModel)]=\"cyan\" min=\"0\" max=\"100\" step=\"1\" />\r\n </div>\r\n</slider>\r\n<slider\r\n [(ngModel)]=\"magenta\"\r\n [min]=\"0\"\r\n [max]=\"100\"\r\n [step]=\"1\"\r\n (change)=\"generateC