color-util-helpers 1.0.2 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -4
- package/color-util-helpers-1.0.6.tgz +0 -0
- package/esm2022/lib/color-grab.directive.mjs +185 -0
- package/esm2022/lib/color-lighten-darken.service.mjs +79 -0
- package/esm2022/lib/color-pallette.service.mjs +24 -9
- package/esm2022/lib/color-scheme.service.mjs +113 -0
- package/esm2022/lib/color-utilities-demo/color-utilities-demo.component.mjs +41 -0
- package/esm2022/lib/color-utils.module.mjs +38 -0
- package/esm2022/lib/text-color.service.mjs +32 -11
- package/esm2022/public-api.mjs +6 -1
- package/fesm2022/color-util-helpers.mjs +528 -55
- package/fesm2022/color-util-helpers.mjs.map +1 -1
- package/lib/color-grab.directive.d.ts +31 -0
- package/lib/color-lighten-darken.service.d.ts +10 -0
- package/lib/color-pallette.service.d.ts +18 -0
- package/lib/color-scheme.service.d.ts +45 -0
- package/lib/color-utilities-demo/color-utilities-demo.component.d.ts +34 -0
- package/lib/color-utils.module.d.ts +12 -0
- package/lib/text-color.service.d.ts +3 -0
- package/package.json +1 -1
- package/public-api.d.ts +5 -0
- package/color-util-helpers-1.0.2.tgz +0 -0
|
@@ -1,7 +1,195 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable,
|
|
2
|
+
import { Directive, Input, Injectable, inject, Component, EventEmitter, Output, HostListener, NgModule } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
6
|
+
import * as i2 from '@angular/material/divider';
|
|
7
|
+
import { MatDividerModule } from '@angular/material/divider';
|
|
3
8
|
import { BehaviorSubject } from 'rxjs';
|
|
4
9
|
|
|
10
|
+
class ColorGrabberDirective {
|
|
11
|
+
constructor(el) {
|
|
12
|
+
this.el = el;
|
|
13
|
+
}
|
|
14
|
+
ngOnInit() {
|
|
15
|
+
const canvas = document.createElement('canvas');
|
|
16
|
+
canvas.width = 1;
|
|
17
|
+
canvas.height = 1;
|
|
18
|
+
this.ctx = canvas.getContext('2d');
|
|
19
|
+
const img = new Image();
|
|
20
|
+
img.src = this.imageUrl || '';
|
|
21
|
+
img.setAttribute('crossOrigin', '');
|
|
22
|
+
img.onload = () => {
|
|
23
|
+
this.ctx?.drawImage(img, 0, 0, 1, 1);
|
|
24
|
+
const imageData = this.ctx?.getImageData(0, 0, 1, 1);
|
|
25
|
+
if (imageData && imageData.data) {
|
|
26
|
+
const i = imageData.data;
|
|
27
|
+
const rgbColor = `rgba(${i[0]},${i[1]},${i[2]},${i[3]})`;
|
|
28
|
+
const hexColor = "#" + ((1 << 24) + (i[0] << 16) + (i[1] << 8) + i[2]).toString(16).slice(1);
|
|
29
|
+
const textColor = this.textColorBasedOnBgColor(hexColor, this.light, this.dark);
|
|
30
|
+
const hsv = this.RGB2HSV({ r: i[0], g: i[1], b: i[2] });
|
|
31
|
+
hsv.hue = this.HueShift(hsv.hue, 135.0);
|
|
32
|
+
const secondaryColor = this.HSV2RGB(hsv);
|
|
33
|
+
const highlightColor = this.lightenDarkenColor(secondaryColor.hex, 50);
|
|
34
|
+
this.el.nativeElement.style.backgroundColor = rgbColor;
|
|
35
|
+
this.el.nativeElement.style.color = textColor;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.error("Failed to get image data.");
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
textColorBasedOnBgColor(bgColor, lightColor = '#FFFFFF', darkColor = '#000000') {
|
|
43
|
+
const color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
|
|
44
|
+
const r = parseInt(color.substring(0, 2), 16); // hexToR
|
|
45
|
+
const g = parseInt(color.substring(2, 4), 16); // hexToG
|
|
46
|
+
const b = parseInt(color.substring(4, 6), 16); // hexToB
|
|
47
|
+
const uicolors = [r / 255, g / 255, b / 255];
|
|
48
|
+
const c = uicolors.map((col) => {
|
|
49
|
+
if (col <= 0.03928)
|
|
50
|
+
return col / 12.92;
|
|
51
|
+
return Math.pow((col + 0.055) / 1.055, 2.4);
|
|
52
|
+
});
|
|
53
|
+
const L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
|
|
54
|
+
return (L > 0.179) ? darkColor : lightColor;
|
|
55
|
+
}
|
|
56
|
+
RGB2HSV(rgb) {
|
|
57
|
+
const hsv = { saturation: 0, hue: 0, value: 0 };
|
|
58
|
+
const max = this.max3(rgb.r, rgb.g, rgb.b);
|
|
59
|
+
const dif = max - this.min3(rgb.r, rgb.g, rgb.b);
|
|
60
|
+
hsv.saturation = (max == 0.0) ? 0 : (100 * dif / max);
|
|
61
|
+
if (hsv.saturation == 0) {
|
|
62
|
+
hsv.hue = 0;
|
|
63
|
+
}
|
|
64
|
+
else if (rgb.r == max) {
|
|
65
|
+
hsv.hue = 60.0 * (rgb.g - rgb.b) / dif;
|
|
66
|
+
}
|
|
67
|
+
else if (rgb.g == max) {
|
|
68
|
+
hsv.hue = 120.0 + 60.0 * (rgb.b - rgb.r) / dif;
|
|
69
|
+
}
|
|
70
|
+
else if (rgb.b == max) {
|
|
71
|
+
hsv.hue = 240.0 + 60.0 * (rgb.r - rgb.g) / dif;
|
|
72
|
+
}
|
|
73
|
+
if (hsv.hue < 0.0)
|
|
74
|
+
hsv.hue += 360.0;
|
|
75
|
+
hsv.value = Math.round(max * 100 / 255);
|
|
76
|
+
hsv.hue = Math.round(hsv.hue);
|
|
77
|
+
hsv.saturation = Math.round(hsv.saturation);
|
|
78
|
+
return hsv;
|
|
79
|
+
}
|
|
80
|
+
HSV2RGB(hsv) {
|
|
81
|
+
const rgb = { r: 0, g: 0, b: 0 };
|
|
82
|
+
if (hsv.saturation == 0) {
|
|
83
|
+
rgb.r = rgb.g = rgb.b = Math.round(hsv.value * 2.55);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
hsv.hue /= 60;
|
|
87
|
+
hsv.saturation /= 100;
|
|
88
|
+
hsv.value /= 100;
|
|
89
|
+
const i = Math.floor(hsv.hue);
|
|
90
|
+
const f = hsv.hue - i;
|
|
91
|
+
const p = hsv.value * (1 - hsv.saturation);
|
|
92
|
+
const q = hsv.value * (1 - hsv.saturation * f);
|
|
93
|
+
const t = hsv.value * (1 - hsv.saturation * (1 - f));
|
|
94
|
+
switch (i) {
|
|
95
|
+
case 0:
|
|
96
|
+
rgb.r = hsv.value;
|
|
97
|
+
rgb.g = t;
|
|
98
|
+
rgb.b = p;
|
|
99
|
+
break;
|
|
100
|
+
case 1:
|
|
101
|
+
rgb.r = q;
|
|
102
|
+
rgb.g = hsv.value;
|
|
103
|
+
rgb.b = p;
|
|
104
|
+
break;
|
|
105
|
+
case 2:
|
|
106
|
+
rgb.r = p;
|
|
107
|
+
rgb.g = hsv.value;
|
|
108
|
+
rgb.b = t;
|
|
109
|
+
break;
|
|
110
|
+
case 3:
|
|
111
|
+
rgb.r = p;
|
|
112
|
+
rgb.g = q;
|
|
113
|
+
rgb.b = hsv.value;
|
|
114
|
+
break;
|
|
115
|
+
case 4:
|
|
116
|
+
rgb.r = t;
|
|
117
|
+
rgb.g = p;
|
|
118
|
+
rgb.b = hsv.value;
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
rgb.r = hsv.value;
|
|
122
|
+
rgb.g = p;
|
|
123
|
+
rgb.b = q;
|
|
124
|
+
}
|
|
125
|
+
rgb.r = Math.round(rgb.r * 255);
|
|
126
|
+
rgb.g = Math.round(rgb.g * 255);
|
|
127
|
+
rgb.b = Math.round(rgb.b * 255);
|
|
128
|
+
}
|
|
129
|
+
const rgbColor = `rgba(${rgb.r},${rgb.g},${rgb.b},${1})`;
|
|
130
|
+
const hexColor = "#" + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).toString(16).slice(1);
|
|
131
|
+
return { rgb: rgbColor, hex: hexColor };
|
|
132
|
+
}
|
|
133
|
+
HueShift(h, s) {
|
|
134
|
+
h += s;
|
|
135
|
+
while (h >= 360.0)
|
|
136
|
+
h -= 360.0;
|
|
137
|
+
while (h < 0.0)
|
|
138
|
+
h += 360.0;
|
|
139
|
+
return h;
|
|
140
|
+
}
|
|
141
|
+
min3(a, b, c) {
|
|
142
|
+
return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
|
|
143
|
+
}
|
|
144
|
+
max3(a, b, c) {
|
|
145
|
+
return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
|
|
146
|
+
}
|
|
147
|
+
lightenDarkenColor(colorCode, amount) {
|
|
148
|
+
var usePound = false;
|
|
149
|
+
if (colorCode[0] == "#") {
|
|
150
|
+
colorCode = colorCode.slice(1);
|
|
151
|
+
usePound = true;
|
|
152
|
+
}
|
|
153
|
+
var num = parseInt(colorCode, 16);
|
|
154
|
+
var r = (num >> 16) + amount;
|
|
155
|
+
if (r > 255) {
|
|
156
|
+
r = 255;
|
|
157
|
+
}
|
|
158
|
+
else if (r < 0) {
|
|
159
|
+
r = 0;
|
|
160
|
+
}
|
|
161
|
+
var b = ((num >> 8) & 0x00FF) + amount;
|
|
162
|
+
if (b > 255) {
|
|
163
|
+
b = 255;
|
|
164
|
+
}
|
|
165
|
+
else if (b < 0) {
|
|
166
|
+
b = 0;
|
|
167
|
+
}
|
|
168
|
+
var g = (num & 0x0000FF) + amount;
|
|
169
|
+
if (g > 255) {
|
|
170
|
+
g = 255;
|
|
171
|
+
}
|
|
172
|
+
else if (g < 0) {
|
|
173
|
+
g = 0;
|
|
174
|
+
}
|
|
175
|
+
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16);
|
|
176
|
+
}
|
|
177
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorGrabberDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
178
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColorGrabberDirective, selector: "[colorGrabber]", inputs: { imageUrl: "imageUrl", light: "light", dark: "dark" }, ngImport: i0 }); }
|
|
179
|
+
}
|
|
180
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorGrabberDirective, decorators: [{
|
|
181
|
+
type: Directive,
|
|
182
|
+
args: [{
|
|
183
|
+
selector: '[colorGrabber]'
|
|
184
|
+
}]
|
|
185
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { imageUrl: [{
|
|
186
|
+
type: Input
|
|
187
|
+
}], light: [{
|
|
188
|
+
type: Input
|
|
189
|
+
}], dark: [{
|
|
190
|
+
type: Input
|
|
191
|
+
}] } });
|
|
192
|
+
|
|
5
193
|
class ColorConversionService {
|
|
6
194
|
constructor() {
|
|
7
195
|
this.componentToHex = (c) => {
|
|
@@ -39,41 +227,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
39
227
|
}]
|
|
40
228
|
}] });
|
|
41
229
|
|
|
42
|
-
class ColorExtractorDirective {
|
|
43
|
-
constructor(elementRef, renderer) {
|
|
44
|
-
this.elementRef = elementRef;
|
|
45
|
-
this.renderer = renderer;
|
|
46
|
-
this.colorValue = new EventEmitter();
|
|
47
|
-
}
|
|
48
|
-
get currentElement() {
|
|
49
|
-
return window.getComputedStyle(this.elementRef.nativeElement);
|
|
50
|
-
}
|
|
51
|
-
onMouseEnter() {
|
|
52
|
-
// console.log('ENTER', this.currentElement)
|
|
53
|
-
this.colorValue.emit(this.currentElement.getPropertyValue('background-color'));
|
|
54
|
-
}
|
|
55
|
-
onMouseLeave() {
|
|
56
|
-
// console.log('LEAVE', this.currentElement.getPropertyValue('background-color'))
|
|
57
|
-
this.colorValue.emit('white');
|
|
58
|
-
}
|
|
59
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorExtractorDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
60
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColorExtractorDirective, selector: "[getColor]", outputs: { colorValue: "colorValue" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, ngImport: i0 }); }
|
|
61
|
-
}
|
|
62
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorExtractorDirective, decorators: [{
|
|
63
|
-
type: Directive,
|
|
64
|
-
args: [{
|
|
65
|
-
selector: '[getColor]'
|
|
66
|
-
}]
|
|
67
|
-
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { colorValue: [{
|
|
68
|
-
type: Output
|
|
69
|
-
}], onMouseEnter: [{
|
|
70
|
-
type: HostListener,
|
|
71
|
-
args: ['mouseenter']
|
|
72
|
-
}], onMouseLeave: [{
|
|
73
|
-
type: HostListener,
|
|
74
|
-
args: ['mouseleave']
|
|
75
|
-
}] } });
|
|
76
|
-
|
|
77
230
|
class ColorPalletteService {
|
|
78
231
|
constructor(colorConversionService) {
|
|
79
232
|
this.colorConversionService = colorConversionService;
|
|
@@ -112,7 +265,15 @@ class ColorPalletteService {
|
|
|
112
265
|
// justify-content: center;
|
|
113
266
|
// }
|
|
114
267
|
this.palette = new BehaviorSubject([]);
|
|
268
|
+
this.palette$ = this.palette.asObservable();
|
|
115
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Retrieves a color palette from an image at the specified path.
|
|
272
|
+
*
|
|
273
|
+
* @param imagePath - The path to the image to extract the color palette from.
|
|
274
|
+
* @param colors - The number of colors to include in the palette (default is 3).
|
|
275
|
+
* @returns An observable that emits the generated color palette.
|
|
276
|
+
*/
|
|
116
277
|
getColorsFromImage(imagePath, colors = 3) {
|
|
117
278
|
const image = new Image();
|
|
118
279
|
image.src = imagePath;
|
|
@@ -121,10 +282,17 @@ class ColorPalletteService {
|
|
|
121
282
|
this.palette.next(data);
|
|
122
283
|
};
|
|
123
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Generates a color palette from an image.
|
|
287
|
+
*
|
|
288
|
+
* @param image - The HTML image element to extract the color palette from.
|
|
289
|
+
* @param colorCount - The number of colors to include in the palette (default is 6).
|
|
290
|
+
* @returns An array of color objects, each with a hex color and a complementary hex color.
|
|
291
|
+
*/
|
|
124
292
|
generateColorPalette(image, colorCount = 6) {
|
|
125
|
-
const canvas = document.createElement(
|
|
126
|
-
const context = canvas.getContext(
|
|
127
|
-
if (!context
|
|
293
|
+
const canvas = document.createElement("canvas");
|
|
294
|
+
const context = canvas.getContext("2d");
|
|
295
|
+
if (!context)
|
|
128
296
|
return;
|
|
129
297
|
canvas.width = image.width;
|
|
130
298
|
canvas.height = image.height;
|
|
@@ -150,8 +318,8 @@ class ColorPalletteService {
|
|
|
150
318
|
const luminance2 = this.getLuminance(color2);
|
|
151
319
|
return luminance2 - luminance1;
|
|
152
320
|
});
|
|
153
|
-
const palette = quantizedColors.map(color => {
|
|
154
|
-
const complementaryColor = color.map(component => 255 - component);
|
|
321
|
+
const palette = quantizedColors.map((color) => {
|
|
322
|
+
const complementaryColor = color.map((component) => 255 - component);
|
|
155
323
|
const hexColor = this.colorConversionService.rgbToHex(color);
|
|
156
324
|
const hexComplementaryColor = this.colorConversionService.rgbToHex(complementaryColor);
|
|
157
325
|
return { color: hexColor, complementaryColor: hexComplementaryColor };
|
|
@@ -186,12 +354,12 @@ class ColorPalletteService {
|
|
|
186
354
|
return [meanR, meanG, meanB];
|
|
187
355
|
}
|
|
188
356
|
kMeansColorQuantization(colors, k) {
|
|
189
|
-
|
|
357
|
+
let clusterCenters = [];
|
|
190
358
|
for (let i = 0; i < k; i++) {
|
|
191
359
|
const randomColor = colors[Math.floor(Math.random() * colors.length)];
|
|
192
360
|
clusterCenters.push(randomColor);
|
|
193
361
|
}
|
|
194
|
-
|
|
362
|
+
let clusters = [];
|
|
195
363
|
for (let i = 0; i < colors.length; i++) {
|
|
196
364
|
const color = colors[i];
|
|
197
365
|
let minDistance = Infinity;
|
|
@@ -206,7 +374,7 @@ class ColorPalletteService {
|
|
|
206
374
|
}
|
|
207
375
|
clusters.push({ color, center: nearestCenter });
|
|
208
376
|
}
|
|
209
|
-
|
|
377
|
+
let updatedCenters = [];
|
|
210
378
|
for (let i = 0; i < clusterCenters.length; i++) {
|
|
211
379
|
const center = clusterCenters[i];
|
|
212
380
|
const clusterColors = clusters.filter(c => c.center === center).map(c => c.color);
|
|
@@ -239,14 +407,14 @@ class TextColorService {
|
|
|
239
407
|
return ((r * 0.299 + g * 0.587 + b * 0.114) > 149) ? darkColor : lightColor;
|
|
240
408
|
}
|
|
241
409
|
darkerColor(color1, color2) {
|
|
242
|
-
return
|
|
410
|
+
return this.isColorDarker(color1, color2) ? color1 : color2;
|
|
243
411
|
}
|
|
244
412
|
isColorDarker(color1, color2) {
|
|
245
413
|
const newColor1 = this.fixColor(color1);
|
|
246
414
|
const newColor2 = this.fixColor(color2);
|
|
247
415
|
const luminance1 = this.calculateLuminance(newColor1[0], newColor1[1], newColor1[2]);
|
|
248
416
|
const luminance2 = this.calculateLuminance(newColor2[0], newColor2[1], newColor2[2]);
|
|
249
|
-
return
|
|
417
|
+
return luminance1 < luminance2;
|
|
250
418
|
}
|
|
251
419
|
lighterColor(color1, color2) {
|
|
252
420
|
return (this.isColorLighter(color1, color2)) ? color1 : color2;
|
|
@@ -262,15 +430,36 @@ class TextColorService {
|
|
|
262
430
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
263
431
|
}
|
|
264
432
|
fixColor(color) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
433
|
+
// Remove leading hash if present
|
|
434
|
+
const sanitizedColor = color.startsWith('#') ? color.slice(1) : color;
|
|
435
|
+
// Validate if the color is a valid hex (3 or 6 characters)
|
|
436
|
+
if (!this.isValidHex(sanitizedColor)) {
|
|
437
|
+
return this.parseRgb(sanitizedColor); // If not hex, attempt to parse as RGB
|
|
269
438
|
}
|
|
270
|
-
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
439
|
+
// Convert hex to RGB
|
|
440
|
+
const rgb = this.hexToRgb(sanitizedColor);
|
|
441
|
+
return rgb;
|
|
442
|
+
}
|
|
443
|
+
// Helper function to validate if a string is a valid 3 or 6 digit hex code
|
|
444
|
+
isValidHex(color) {
|
|
445
|
+
const hexRegex = /^[A-Fa-f0-9]{3}$|^[A-Fa-f0-9]{6}$/i;
|
|
446
|
+
return hexRegex.test(color);
|
|
447
|
+
}
|
|
448
|
+
// Helper function to convert a 3 or 6 digit hex color to RGB
|
|
449
|
+
hexToRgb(hex) {
|
|
450
|
+
if (hex.length === 3) {
|
|
451
|
+
hex = hex.split('').map(c => c + c).join(''); // Expand shorthand hex to full
|
|
452
|
+
}
|
|
453
|
+
return [
|
|
454
|
+
parseInt(hex.slice(0, 2), 16),
|
|
455
|
+
parseInt(hex.slice(2, 4), 16),
|
|
456
|
+
parseInt(hex.slice(4, 6), 16),
|
|
457
|
+
];
|
|
458
|
+
}
|
|
459
|
+
// Helper function to parse an RGB string (e.g., rgb(255, 0, 0)) into an array
|
|
460
|
+
parseRgb(rgb) {
|
|
461
|
+
const match = rgb.match(/\d+/g);
|
|
462
|
+
return match ? match.map(num => parseInt(num)) : [];
|
|
274
463
|
}
|
|
275
464
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TextColorService, deps: [{ token: ColorConversionService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
276
465
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TextColorService, providedIn: 'root' }); }
|
|
@@ -282,6 +471,290 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
282
471
|
}]
|
|
283
472
|
}], ctorParameters: function () { return [{ type: ColorConversionService }]; } });
|
|
284
473
|
|
|
474
|
+
class ColorLightenDarkenService {
|
|
475
|
+
// const color = '#3498db'; // Your color
|
|
476
|
+
// const lighterColor = lighten(color, 0.2); // 20% lighter
|
|
477
|
+
// const darkerColor = darken(color, 0.2); // 20% darker
|
|
478
|
+
// console.log(lighterColor, darkerColor);
|
|
479
|
+
constructor() {
|
|
480
|
+
this.colors = inject(TextColorService);
|
|
481
|
+
}
|
|
482
|
+
lighten(color, amount) {
|
|
483
|
+
const rgb = this.colors.fixColor(color);
|
|
484
|
+
// const rgb = color.match(/\w\w/g)?.map((x) => parseInt(x, 16)) || [];
|
|
485
|
+
// Convert RGB to HSL
|
|
486
|
+
let [r, g, b] = rgb.map((c) => c / 255);
|
|
487
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b);
|
|
488
|
+
let h = 0, s = 0, l = (max + min) / 2;
|
|
489
|
+
if (max !== min) {
|
|
490
|
+
const d = max - min;
|
|
491
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
492
|
+
switch (max) {
|
|
493
|
+
case r:
|
|
494
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
495
|
+
break;
|
|
496
|
+
case g:
|
|
497
|
+
h = (b - r) / d + 2;
|
|
498
|
+
break;
|
|
499
|
+
case b:
|
|
500
|
+
h = (r - g) / d + 4;
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
h /= 6;
|
|
504
|
+
}
|
|
505
|
+
// Modify the lightness and clamp it to [0, 1]
|
|
506
|
+
l = Math.min(1, l + amount);
|
|
507
|
+
// Convert HSL back to RGB
|
|
508
|
+
if (s === 0) {
|
|
509
|
+
r = g = b = l; // achromatic
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
const hue2rgb = (p, q, t) => {
|
|
513
|
+
if (t < 0)
|
|
514
|
+
t += 1;
|
|
515
|
+
if (t > 1)
|
|
516
|
+
t -= 1;
|
|
517
|
+
if (t < 1 / 6)
|
|
518
|
+
return p + (q - p) * 6 * t;
|
|
519
|
+
if (t < 1 / 2)
|
|
520
|
+
return q;
|
|
521
|
+
if (t < 2 / 3)
|
|
522
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
523
|
+
return p;
|
|
524
|
+
};
|
|
525
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
526
|
+
const p = 2 * l - q;
|
|
527
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
528
|
+
g = hue2rgb(p, q, h);
|
|
529
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
530
|
+
}
|
|
531
|
+
// Convert RGB back to hexadecimal color
|
|
532
|
+
const toHex = (x) => Math.round(x * 255)
|
|
533
|
+
.toString(16)
|
|
534
|
+
.padStart(2, '0');
|
|
535
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
536
|
+
}
|
|
537
|
+
darken(color, amount) {
|
|
538
|
+
return this.lighten(color, -amount);
|
|
539
|
+
}
|
|
540
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorLightenDarkenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
541
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorLightenDarkenService, providedIn: 'root' }); }
|
|
542
|
+
}
|
|
543
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorLightenDarkenService, decorators: [{
|
|
544
|
+
type: Injectable,
|
|
545
|
+
args: [{
|
|
546
|
+
providedIn: 'root'
|
|
547
|
+
}]
|
|
548
|
+
}], ctorParameters: function () { return []; } });
|
|
549
|
+
|
|
550
|
+
class ColorSchemeService {
|
|
551
|
+
constructor() { }
|
|
552
|
+
/**
|
|
553
|
+
* Generates a random hexadecimal color code.
|
|
554
|
+
*
|
|
555
|
+
* This function generates a random hue value between 0 and 360 degrees, and random saturation and lightness values between 50% and 100%. It then converts the HSL values to RGB values using the `hslToRgb` function, and finally converts the RGB values to a hexadecimal color code using the `rgbToHex` function.
|
|
556
|
+
*
|
|
557
|
+
* @returns A hexadecimal color code in the format "#RRGGBB".
|
|
558
|
+
*/
|
|
559
|
+
generateRandomColor() {
|
|
560
|
+
// Generate a random hue between 0 and 360 (representing degrees on the color wheel)
|
|
561
|
+
const hue = Math.floor(Math.random() * 360);
|
|
562
|
+
// Generate random saturation and lightness values between 50% and 100%
|
|
563
|
+
const saturation = Math.floor(Math.random() * 51) + 50;
|
|
564
|
+
const lightness = Math.floor(Math.random() * 51) + 50;
|
|
565
|
+
// Convert HSL values to RGB values
|
|
566
|
+
const rgbColor = this.hslToRgb(hue, saturation, lightness);
|
|
567
|
+
// Convert RGB values to hexadecimal color code
|
|
568
|
+
const hexColor = this.rgbToHex(rgbColor.r, rgbColor.g, rgbColor.b);
|
|
569
|
+
return hexColor;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Converts HSL (Hue, Saturation, Lightness) color values to RGB (Red, Green, Blue) color values.
|
|
573
|
+
*
|
|
574
|
+
* @param h - The hue value, ranging from 0 to 360 degrees.
|
|
575
|
+
* @param s - The saturation value, ranging from 0 to 100 percent.
|
|
576
|
+
* @param l - The lightness value, ranging from 0 to 100 percent.
|
|
577
|
+
* @returns An object with the RGB color values, where each value is between 0 and 255.
|
|
578
|
+
*/
|
|
579
|
+
hslToRgb(h, s, l) {
|
|
580
|
+
h /= 360;
|
|
581
|
+
s /= 100;
|
|
582
|
+
l /= 100;
|
|
583
|
+
let r, g, b;
|
|
584
|
+
if (s === 0) {
|
|
585
|
+
r = g = b = l; // Achromatic color (gray)
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
const hueToRgb = (p, q, t) => {
|
|
589
|
+
if (t < 0)
|
|
590
|
+
t += 1;
|
|
591
|
+
if (t > 1)
|
|
592
|
+
t -= 1;
|
|
593
|
+
if (t < 1 / 6)
|
|
594
|
+
return p + (q - p) * 6 * t;
|
|
595
|
+
if (t < 1 / 2)
|
|
596
|
+
return q;
|
|
597
|
+
if (t < 2 / 3)
|
|
598
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
599
|
+
return p;
|
|
600
|
+
};
|
|
601
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
602
|
+
const p = 2 * l - q;
|
|
603
|
+
r = Math.round(hueToRgb(p, q, h + 1 / 3) * 255);
|
|
604
|
+
g = Math.round(hueToRgb(p, q, h) * 255);
|
|
605
|
+
b = Math.round(hueToRgb(p, q, h - 1 / 3) * 255);
|
|
606
|
+
}
|
|
607
|
+
return { r, g, b };
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Converts RGB color values to a hexadecimal color string.
|
|
611
|
+
*
|
|
612
|
+
* @param r - The red color value, between 0 and 255.
|
|
613
|
+
* @param g - The green color value, between 0 and 255.
|
|
614
|
+
* @param b - The blue color value, between 0 and 255.
|
|
615
|
+
* @returns A hexadecimal color string in the format "#RRGGBB".
|
|
616
|
+
*/
|
|
617
|
+
rgbToHex(r, g, b) {
|
|
618
|
+
const componentToHex = (c) => {
|
|
619
|
+
const hex = c.toString(16);
|
|
620
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
621
|
+
};
|
|
622
|
+
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Adjusts a hexadecimal color value by a given percentage.
|
|
626
|
+
*
|
|
627
|
+
* @param hexColor - The hexadecimal color value to adjust.
|
|
628
|
+
* @param percentage - The percentage to adjust the color by, ranging from -100 to 100.
|
|
629
|
+
* @returns The adjusted hexadecimal color value.
|
|
630
|
+
*/
|
|
631
|
+
adjustHexColor(hexColor, percentage) {
|
|
632
|
+
// Remove the "#" symbol if present
|
|
633
|
+
hexColor = hexColor.replace("#", "");
|
|
634
|
+
// Convert the hex color to RGB values
|
|
635
|
+
const red = parseInt(hexColor.substring(0, 2), 16);
|
|
636
|
+
const green = parseInt(hexColor.substring(2, 4), 16);
|
|
637
|
+
const blue = parseInt(hexColor.substring(4, 6), 16);
|
|
638
|
+
// Calculate the adjustment amount based on the percentage
|
|
639
|
+
const adjustAmount = Math.round(255 * (percentage / 100));
|
|
640
|
+
// Adjust the RGB values
|
|
641
|
+
const adjustedRed = this.clamp(red + adjustAmount);
|
|
642
|
+
const adjustedGreen = this.clamp(green + adjustAmount);
|
|
643
|
+
const adjustedBlue = this.clamp(blue + adjustAmount);
|
|
644
|
+
// Convert the adjusted RGB values back to hex
|
|
645
|
+
const adjustedHexColor = `#${(adjustedRed).toString(16).padStart(2, '0')}${(adjustedGreen).toString(16).padStart(2, '0')}${(adjustedBlue).toString(16).padStart(2, '0')}`;
|
|
646
|
+
return adjustedHexColor;
|
|
647
|
+
}
|
|
648
|
+
clamp(value) {
|
|
649
|
+
return Math.max(0, Math.min(value, 255));
|
|
650
|
+
}
|
|
651
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorSchemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
652
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorSchemeService, providedIn: 'root' }); }
|
|
653
|
+
}
|
|
654
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorSchemeService, decorators: [{
|
|
655
|
+
type: Injectable,
|
|
656
|
+
args: [{
|
|
657
|
+
providedIn: 'root'
|
|
658
|
+
}]
|
|
659
|
+
}], ctorParameters: function () { return []; } });
|
|
660
|
+
|
|
661
|
+
class ColorUtilitiesDemoComponent {
|
|
662
|
+
constructor() {
|
|
663
|
+
this.colorConversionService = inject(ColorConversionService);
|
|
664
|
+
this.colorLightenDarkenService = inject(ColorLightenDarkenService);
|
|
665
|
+
this.colorPalletteService = inject(ColorPalletteService);
|
|
666
|
+
this.textColorService = inject(TextColorService);
|
|
667
|
+
this.colorSchemeService = inject(ColorSchemeService);
|
|
668
|
+
this.HEX = this.colorConversionService.rgbToHex([12, 56, 128]);
|
|
669
|
+
this.RGB = `rgb(${this.colorConversionService.hexToRgb('#AA11BB')})`;
|
|
670
|
+
this.lighten = this.colorLightenDarkenService.lighten('#AA11BB', .25);
|
|
671
|
+
this.darken = this.colorLightenDarkenService.darken('#AA11BB', .25);
|
|
672
|
+
this.colorIsDarker = this.textColorService.isColorDarker(this.lighten, this.darken);
|
|
673
|
+
this.darkBk = this.textColorService.textColorForBgColor(this.HEX, this.lighten, this.darken);
|
|
674
|
+
this.lightBk = this.textColorService.textColorForBgColor('whitesmoke', this.lighten, this.darken);
|
|
675
|
+
this.colors$ = this.colorPalletteService.palette$;
|
|
676
|
+
this.colorPick = this.colorSchemeService.generateRandomColor();
|
|
677
|
+
this.colorPickDarker = this.colorSchemeService.adjustHexColor(this.colorPick, -25);
|
|
678
|
+
this.colorPickLighter = this.colorSchemeService.adjustHexColor(this.colorPick, 25);
|
|
679
|
+
}
|
|
680
|
+
ngOnInit() {
|
|
681
|
+
// define image path
|
|
682
|
+
this.img = '/assets/images/HD.png';
|
|
683
|
+
this.colorPalletteService.getColorsFromImage(this.img, 8);
|
|
684
|
+
}
|
|
685
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorUtilitiesDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
686
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColorUtilitiesDemoComponent, selector: "app-color-utilities-demo", ngImport: i0, template: "<div style=\"margin: 2rem;\">\n\n <h1>Color Conversion Service</h1>\n <div style=\"display: flex; flex-direction: column; gap: 1rem;\">\n <div style=\"display: flex\">\n <div style=\"padding-top: .5rem; margin-right: .5rem;\">rgbToHex: {{ HEX }}</div>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"HEX\"></div>\n </div>\n\n <div style=\"display: flex\">\n <div style=\"padding-top: .5rem; margin-right: .5rem;\"> hexToRgb: {{ RGB }} </div>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"RGB\"></div>\n </div>\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h1>Color Light/Darken Service</h1>\n\n <div style=\"display: flex; flex-direction: column; gap: 1rem;\">\n\n <div style=\"display: flex; gap: 1rem\">\n Original Color: #AA11BB<br>\n <div style=\"width: 32px; height: 32px; background-color: #AA11BB;\"></div>\n Lighten (25%): {{ lighten }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"lighten\"></div>\n Darken (25%): {{ darken }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"darken\"></div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h1>Text Color Utility Services</h1>\n\n <div style=\"display: flex; gap: 1rem; flex-direction: column;\">\n <div style=\"display: flex; gap: 1rem\">\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"darken\"></div>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"lighten\"></div>\n is Darker : {{ colorIsDarker }}\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorIsDarker\"></div>\n </div>\n \n <div style=\"display: flex; gap: 1rem; flex-direction: column;\">\n \n <div>\n Use: {{ lightBk }} for '{{ HEX }}' background-color<br>\n <div style=\"padding: 1rem;\" [style.backgroundColor]=\"HEX\" [style.color]=\"darkBk\">\n Sample Text Color\n </div>\n </div>\n\n <div>\n Use: {{ lightBk }} for 'whitesmoke' background-color<br>\n <div style=\"padding: 1rem; background-color: whitesmoke;\" [style.color]=\"lightBk\">\n Sample Text Color\n </div>\n </div>\n </div>\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n \n <h1>Color Schema Services</h1>\n\n <div style=\"display: flex; gap: 1rem\">\n Pick Color: {{ colorPick }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorPick\"></div>\n Lighter Version: {{ colorPickLighter }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorPickLighter\"></div>\n DarkerVersion: {{ colorPickDarker }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorPickDarker\"></div>\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h1>Color Pallette Service</h1>\n Creates Pallette from Image\n <div style=\"display: flex; gap: 2rem;\">\n <div>\n <img [src]=\"img\" height=\"180\">\n </div>\n\n <div style=\"display: flex; gap: .5rem; width: 120px; border: 1px solid black; flex-wrap: wrap; padding: .5rem;\">\n <div>Color Pick</div>\n <ng-container *ngFor=\"let color of (colors$ | async)\">\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"color.color\"></div>\n </ng-container>\n </div>\n \n <div style=\"display: flex; gap: .5rem; width: 120px; border: 1px solid black; flex-wrap: wrap; padding: .5rem;\">\n <div>Complementary</div>\n <ng-container *ngFor=\"let color of (colors$ | async)\">\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"color.complementaryColor\"></div>\n </ng-container>\n </div>\n </div>\n\n</div>\n\n", styles: [".box{width:100px;height:100px;border:solid thin black;color:#000;margin:4px;padding:16px;display:flex;flex-wrap:wrap;align-content:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] }); }
|
|
687
|
+
}
|
|
688
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorUtilitiesDemoComponent, decorators: [{
|
|
689
|
+
type: Component,
|
|
690
|
+
args: [{ selector: 'app-color-utilities-demo', template: "<div style=\"margin: 2rem;\">\n\n <h1>Color Conversion Service</h1>\n <div style=\"display: flex; flex-direction: column; gap: 1rem;\">\n <div style=\"display: flex\">\n <div style=\"padding-top: .5rem; margin-right: .5rem;\">rgbToHex: {{ HEX }}</div>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"HEX\"></div>\n </div>\n\n <div style=\"display: flex\">\n <div style=\"padding-top: .5rem; margin-right: .5rem;\"> hexToRgb: {{ RGB }} </div>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"RGB\"></div>\n </div>\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h1>Color Light/Darken Service</h1>\n\n <div style=\"display: flex; flex-direction: column; gap: 1rem;\">\n\n <div style=\"display: flex; gap: 1rem\">\n Original Color: #AA11BB<br>\n <div style=\"width: 32px; height: 32px; background-color: #AA11BB;\"></div>\n Lighten (25%): {{ lighten }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"lighten\"></div>\n Darken (25%): {{ darken }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"darken\"></div>\n </div>\n\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h1>Text Color Utility Services</h1>\n\n <div style=\"display: flex; gap: 1rem; flex-direction: column;\">\n <div style=\"display: flex; gap: 1rem\">\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"darken\"></div>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"lighten\"></div>\n is Darker : {{ colorIsDarker }}\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorIsDarker\"></div>\n </div>\n \n <div style=\"display: flex; gap: 1rem; flex-direction: column;\">\n \n <div>\n Use: {{ lightBk }} for '{{ HEX }}' background-color<br>\n <div style=\"padding: 1rem;\" [style.backgroundColor]=\"HEX\" [style.color]=\"darkBk\">\n Sample Text Color\n </div>\n </div>\n\n <div>\n Use: {{ lightBk }} for 'whitesmoke' background-color<br>\n <div style=\"padding: 1rem; background-color: whitesmoke;\" [style.color]=\"lightBk\">\n Sample Text Color\n </div>\n </div>\n </div>\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n \n <h1>Color Schema Services</h1>\n\n <div style=\"display: flex; gap: 1rem\">\n Pick Color: {{ colorPick }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorPick\"></div>\n Lighter Version: {{ colorPickLighter }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorPickLighter\"></div>\n DarkerVersion: {{ colorPickDarker }}<br>\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"colorPickDarker\"></div>\n </div>\n\n <div style=\"margin-top: 1rem; margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h1>Color Pallette Service</h1>\n Creates Pallette from Image\n <div style=\"display: flex; gap: 2rem;\">\n <div>\n <img [src]=\"img\" height=\"180\">\n </div>\n\n <div style=\"display: flex; gap: .5rem; width: 120px; border: 1px solid black; flex-wrap: wrap; padding: .5rem;\">\n <div>Color Pick</div>\n <ng-container *ngFor=\"let color of (colors$ | async)\">\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"color.color\"></div>\n </ng-container>\n </div>\n \n <div style=\"display: flex; gap: .5rem; width: 120px; border: 1px solid black; flex-wrap: wrap; padding: .5rem;\">\n <div>Complementary</div>\n <ng-container *ngFor=\"let color of (colors$ | async)\">\n <div style=\"width: 32px; height: 32px;\" [style.backgroundColor]=\"color.complementaryColor\"></div>\n </ng-container>\n </div>\n </div>\n\n</div>\n\n", styles: [".box{width:100px;height:100px;border:solid thin black;color:#000;margin:4px;padding:16px;display:flex;flex-wrap:wrap;align-content:center;justify-content:center}\n"] }]
|
|
691
|
+
}], ctorParameters: function () { return []; } });
|
|
692
|
+
|
|
693
|
+
class ColorExtractorDirective {
|
|
694
|
+
constructor(elementRef, renderer) {
|
|
695
|
+
this.elementRef = elementRef;
|
|
696
|
+
this.renderer = renderer;
|
|
697
|
+
this.colorValue = new EventEmitter();
|
|
698
|
+
}
|
|
699
|
+
get currentElement() {
|
|
700
|
+
return window.getComputedStyle(this.elementRef.nativeElement);
|
|
701
|
+
}
|
|
702
|
+
onMouseEnter() {
|
|
703
|
+
// console.log('ENTER', this.currentElement)
|
|
704
|
+
this.colorValue.emit(this.currentElement.getPropertyValue('background-color'));
|
|
705
|
+
}
|
|
706
|
+
onMouseLeave() {
|
|
707
|
+
// console.log('LEAVE', this.currentElement.getPropertyValue('background-color'))
|
|
708
|
+
this.colorValue.emit('white');
|
|
709
|
+
}
|
|
710
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorExtractorDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
711
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColorExtractorDirective, selector: "[getColor]", outputs: { colorValue: "colorValue" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, ngImport: i0 }); }
|
|
712
|
+
}
|
|
713
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorExtractorDirective, decorators: [{
|
|
714
|
+
type: Directive,
|
|
715
|
+
args: [{
|
|
716
|
+
selector: '[getColor]'
|
|
717
|
+
}]
|
|
718
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { colorValue: [{
|
|
719
|
+
type: Output
|
|
720
|
+
}], onMouseEnter: [{
|
|
721
|
+
type: HostListener,
|
|
722
|
+
args: ['mouseenter']
|
|
723
|
+
}], onMouseLeave: [{
|
|
724
|
+
type: HostListener,
|
|
725
|
+
args: ['mouseleave']
|
|
726
|
+
}] } });
|
|
727
|
+
|
|
728
|
+
class ColorUtilitiesModule {
|
|
729
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorUtilitiesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
730
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: ColorUtilitiesModule, declarations: [ColorUtilitiesDemoComponent,
|
|
731
|
+
ColorGrabberDirective,
|
|
732
|
+
ColorExtractorDirective], imports: [CommonModule,
|
|
733
|
+
MatButtonModule,
|
|
734
|
+
MatDividerModule], exports: [ColorUtilitiesDemoComponent] }); }
|
|
735
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorUtilitiesModule, imports: [CommonModule,
|
|
736
|
+
MatButtonModule,
|
|
737
|
+
MatDividerModule] }); }
|
|
738
|
+
}
|
|
739
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorUtilitiesModule, decorators: [{
|
|
740
|
+
type: NgModule,
|
|
741
|
+
args: [{
|
|
742
|
+
imports: [
|
|
743
|
+
CommonModule,
|
|
744
|
+
MatButtonModule,
|
|
745
|
+
MatDividerModule
|
|
746
|
+
],
|
|
747
|
+
declarations: [
|
|
748
|
+
ColorUtilitiesDemoComponent,
|
|
749
|
+
ColorGrabberDirective,
|
|
750
|
+
ColorExtractorDirective
|
|
751
|
+
],
|
|
752
|
+
exports: [
|
|
753
|
+
ColorUtilitiesDemoComponent
|
|
754
|
+
]
|
|
755
|
+
}]
|
|
756
|
+
}] });
|
|
757
|
+
|
|
285
758
|
/*
|
|
286
759
|
* Public API Surface of color-utils
|
|
287
760
|
*/
|
|
@@ -290,5 +763,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
290
763
|
* Generated bundle index. Do not edit.
|
|
291
764
|
*/
|
|
292
765
|
|
|
293
|
-
export { ColorConversionService, ColorExtractorDirective, ColorPalletteService, TextColorService };
|
|
766
|
+
export { ColorConversionService, ColorExtractorDirective, ColorGrabberDirective, ColorLightenDarkenService, ColorPalletteService, ColorSchemeService, ColorUtilitiesDemoComponent, ColorUtilitiesModule, TextColorService };
|
|
294
767
|
//# sourceMappingURL=color-util-helpers.mjs.map
|