@mintplayer/ng-bootstrap 21.26.0 → 21.27.0

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.
@@ -1,9 +1,165 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, viewChild, input, model, output, signal, computed, effect, ChangeDetectionStrategy, Component, Directive, forwardRef, ElementRef } from '@angular/core';
2
+ import { inject, viewChild, input, model, output, signal, computed, effect, ChangeDetectionStrategy, Component, Directive, forwardRef } from '@angular/core';
3
3
  import * as i1 from '@mintplayer/ng-swiper/observe-size';
4
4
  import { BsObserveSizeDirective } from '@mintplayer/ng-swiper/observe-size';
5
5
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
6
6
 
7
+ /**
8
+ * Single source of truth for color-space conversions used by the picker.
9
+ *
10
+ * Conventions across this module:
11
+ * - hue is in degrees [0, 360)
12
+ * - saturation, lightness, value, alpha are in [0, 1]
13
+ * - r, g, b are in [0, 255] (integer on the way out, real-valued internally)
14
+ * - hex is "#RRGGBB" — three-digit "#RGB" is accepted on parse only
15
+ */
16
+ const TWO_PI = Math.PI * 2;
17
+ const clamp01 = (n) => Math.max(0, Math.min(1, n));
18
+ const clamp255 = (n) => Math.max(0, Math.min(255, Math.round(n)));
19
+ const HEX6_RE = /^[0-9a-fA-F]{6}$/;
20
+ const BLACK = { r: 0, g: 0, b: 0 };
21
+ function hex2rgb(hex) {
22
+ const stripped = hex.startsWith('#') ? hex.slice(1) : hex;
23
+ const expanded = stripped.length === 3
24
+ ? stripped.split('').map(c => c + c).join('')
25
+ : stripped;
26
+ if (!HEX6_RE.test(expanded))
27
+ return { ...BLACK };
28
+ return {
29
+ r: parseInt(expanded.slice(0, 2), 16),
30
+ g: parseInt(expanded.slice(2, 4), 16),
31
+ b: parseInt(expanded.slice(4, 6), 16),
32
+ };
33
+ }
34
+ function rgb2hex(rgb) {
35
+ const r = clamp255(rgb.r);
36
+ const g = clamp255(rgb.g);
37
+ const b = clamp255(rgb.b);
38
+ return '#' + ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
39
+ }
40
+ function rgb2hsv(rgb) {
41
+ const r = rgb.r / 255;
42
+ const g = rgb.g / 255;
43
+ const b = rgb.b / 255;
44
+ const max = Math.max(r, g, b);
45
+ const min = Math.min(r, g, b);
46
+ const d = max - min;
47
+ const value = max;
48
+ const saturation = max === 0 ? 0 : d / max;
49
+ const hue = d === 0 ? 0 : hueFromRgb(r, g, b, max, d);
50
+ return { hue, saturation, value };
51
+ }
52
+ function hsv2rgb(hsv) {
53
+ const s = clamp01(hsv.saturation);
54
+ const v = clamp01(hsv.value);
55
+ const h = ((hsv.hue % 360) + 360) % 360;
56
+ const c = v * s;
57
+ const hp = h / 60;
58
+ const x = c * (1 - Math.abs((hp % 2) - 1));
59
+ const m = v - c;
60
+ let r1 = 0, g1 = 0, b1 = 0;
61
+ if (hp < 1) {
62
+ r1 = c;
63
+ g1 = x;
64
+ }
65
+ else if (hp < 2) {
66
+ r1 = x;
67
+ g1 = c;
68
+ }
69
+ else if (hp < 3) {
70
+ g1 = c;
71
+ b1 = x;
72
+ }
73
+ else if (hp < 4) {
74
+ g1 = x;
75
+ b1 = c;
76
+ }
77
+ else if (hp < 5) {
78
+ r1 = x;
79
+ b1 = c;
80
+ }
81
+ else {
82
+ r1 = c;
83
+ b1 = x;
84
+ }
85
+ return {
86
+ r: (r1 + m) * 255,
87
+ g: (g1 + m) * 255,
88
+ b: (b1 + m) * 255,
89
+ };
90
+ }
91
+ function rgb2hsl(rgb) {
92
+ const r = rgb.r / 255;
93
+ const g = rgb.g / 255;
94
+ const b = rgb.b / 255;
95
+ const max = Math.max(r, g, b);
96
+ const min = Math.min(r, g, b);
97
+ const d = max - min;
98
+ const luminosity = (max + min) / 2;
99
+ const saturation = d === 0
100
+ ? 0
101
+ : d / (1 - Math.abs(2 * luminosity - 1));
102
+ const hue = d === 0 ? 0 : hueFromRgb(r, g, b, max, d);
103
+ return { hue, saturation, luminosity };
104
+ }
105
+ function hsl2rgb(hsl) {
106
+ return hsv2rgb(hsl2hsv(hsl));
107
+ }
108
+ function hsv2hsl(hsv) {
109
+ const v = clamp01(hsv.value);
110
+ const s = clamp01(hsv.saturation);
111
+ const luminosity = v * (1 - s / 2);
112
+ const denom = Math.min(luminosity, 1 - luminosity);
113
+ const saturation = denom === 0 ? 0 : (v - luminosity) / denom;
114
+ return { hue: hsv.hue, saturation, luminosity };
115
+ }
116
+ function hsl2hsv(hsl) {
117
+ const l = clamp01(hsl.luminosity);
118
+ const s = clamp01(hsl.saturation);
119
+ const value = l + s * Math.min(l, 1 - l);
120
+ const saturation = value === 0 ? 0 : 2 * (1 - l / value);
121
+ return { hue: hsl.hue, saturation, value };
122
+ }
123
+ function hex2hsv(hex) {
124
+ return rgb2hsv(hex2rgb(hex));
125
+ }
126
+ function hsv2hex(hsv) {
127
+ return rgb2hex(hsv2rgb(hsv));
128
+ }
129
+ /** Polar position (cx, cy) on a disc of radius R → HSV (hue, saturation). */
130
+ function polar2hs(dx, dy, radius) {
131
+ const r = Math.sqrt(dx * dx + dy * dy);
132
+ const saturation = clamp01(r / radius);
133
+ let hue = (Math.atan2(dy, dx) * 360) / TWO_PI;
134
+ if (hue < 0)
135
+ hue += 360;
136
+ return { hue, saturation };
137
+ }
138
+ /** Inverse of polar2hs. Hue in degrees, saturation in [0, 1] → (dx, dy) on a disc of given radius. */
139
+ function hs2polar(hue, saturation, radius) {
140
+ const theta = (hue * TWO_PI) / 360;
141
+ const r = clamp01(saturation) * radius;
142
+ return { dx: r * Math.cos(theta), dy: r * Math.sin(theta) };
143
+ }
144
+ function hueFromRgb(r, g, b, max, d) {
145
+ let h;
146
+ switch (max) {
147
+ case r:
148
+ h = ((g - b) / d) % 6;
149
+ break;
150
+ case g:
151
+ h = (b - r) / d + 2;
152
+ break;
153
+ default:
154
+ h = (r - g) / d + 4;
155
+ break;
156
+ }
157
+ h *= 60;
158
+ if (h < 0)
159
+ h += 360;
160
+ return h;
161
+ }
162
+
7
163
  class BsSliderComponent {
8
164
  constructor() {
9
165
  this.observeSize = inject(BsObserveSizeDirective);
@@ -104,35 +260,36 @@ class BsAlphaStripComponent {
104
260
  this.canvas = viewChild.required('track');
105
261
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
106
262
  this.hs = model({ hue: 0, saturation: 0 }, ...(ngDevMode ? [{ debugName: "hs" }] : /* istanbul ignore next */ []));
107
- this.luminosity = model(0.5, ...(ngDevMode ? [{ debugName: "luminosity" }] : /* istanbul ignore next */ []));
263
+ this.brightness = model(1, ...(ngDevMode ? [{ debugName: "brightness" }] : /* istanbul ignore next */ []));
108
264
  this.alpha = model(1, ...(ngDevMode ? [{ debugName: "alpha" }] : /* istanbul ignore next */ []));
109
265
  this.alphaChange = output();
110
266
  this.canvasContext = null;
111
267
  this.resultBackground = computed(() => {
112
268
  const hs = this.hs();
113
- const luminosity = this.luminosity();
269
+ const brightness = this.brightness();
114
270
  const alpha = this.alpha();
115
- return `hsla(${hs.hue}, ${hs.saturation * 100}%, ${luminosity * 100}%, ${alpha})`;
271
+ const rgb = hsv2rgb({ hue: hs.hue, saturation: hs.saturation, value: brightness });
272
+ return `rgba(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)}, ${alpha})`;
116
273
  }, ...(ngDevMode ? [{ debugName: "resultBackground" }] : /* istanbul ignore next */ []));
117
- // Draw gradient when HS or luminosity changes
118
274
  effect(() => {
119
275
  const hs = this.hs();
120
- const luminosity = this.luminosity();
276
+ const brightness = this.brightness();
121
277
  setTimeout(() => {
122
278
  if (this.canvasContext) {
123
279
  const width = this.canvas().nativeElement.width;
124
280
  const height = this.canvas().nativeElement.height;
125
281
  this.canvasContext.clearRect(0, 0, width, height);
126
282
  this.canvasContext.save();
283
+ const rgb = hsv2rgb({ hue: hs.hue, saturation: hs.saturation, value: brightness });
284
+ const r = Math.round(rgb.r), g = Math.round(rgb.g), b = Math.round(rgb.b);
127
285
  const gradient = this.canvasContext.createLinearGradient(0, 0, width, 0);
128
- gradient.addColorStop(0, `hsla(${hs.hue}, ${hs.saturation * 100}%, ${luminosity * 100}%, 0)`);
129
- gradient.addColorStop(1, `hsla(${hs.hue}, ${hs.saturation * 100}%, ${luminosity * 100}%, 1)`);
286
+ gradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, 0)`);
287
+ gradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 1)`);
130
288
  this.canvasContext.fillStyle = gradient;
131
289
  this.canvasContext.fillRect(0, 0, width, height);
132
290
  }
133
291
  });
134
292
  });
135
- // Emit alpha changes
136
293
  effect(() => {
137
294
  const alpha = this.alpha();
138
295
  this.alphaChange.emit(alpha);
@@ -144,33 +301,77 @@ class BsAlphaStripComponent {
144
301
  }
145
302
  }
146
303
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsAlphaStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
147
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.11", type: BsAlphaStripComponent, isStandalone: true, selector: "bs-alpha-strip", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hs: { classPropertyName: "hs", publicName: "hs", isSignal: true, isRequired: false, transformFunction: null }, luminosity: { classPropertyName: "luminosity", publicName: "luminosity", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { hs: "hsChange", luminosity: "luminosityChange", alpha: "alphaChange", alphaChange: "alphaChange" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<bs-slider [disabled]=\"disabled()\" [value]=\"alpha()\" (valueChange)=\"alphaChange.emit($event)\">\n <canvas bsTrack class=\" track position-absolute w-100\" #track></canvas>\n\n <!-- [style.background]=\"resultBackground()\" -->\n <div bsThumb [style.background]=\"resultBackground()\"></div>\n</bs-slider>\n", styles: [".track{background-image:linear-gradient(45deg,#C0C0C0 25%,transparent 25%),linear-gradient(-45deg,#C0C0C0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#C0C0C0 75%),linear-gradient(-45deg,transparent 75%,#C0C0C0 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px}\n"], dependencies: [{ kind: "component", type: BsSliderComponent, selector: "bs-slider", inputs: ["disabled", "value"], outputs: ["valueChange"] }, { kind: "directive", type: BsThumbDirective, selector: "[bsThumb]" }, { kind: "directive", type: BsTrackDirective, selector: "[bsTrack]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
304
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.11", type: BsAlphaStripComponent, isStandalone: true, selector: "bs-alpha-strip", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hs: { classPropertyName: "hs", publicName: "hs", isSignal: true, isRequired: false, transformFunction: null }, brightness: { classPropertyName: "brightness", publicName: "brightness", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { hs: "hsChange", brightness: "brightnessChange", alpha: "alphaChange", alphaChange: "alphaChange" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<bs-slider [disabled]=\"disabled()\" [value]=\"alpha()\" (valueChange)=\"alphaChange.emit($event)\">\n <canvas bsTrack class=\" track position-absolute w-100\" #track></canvas>\n\n <!-- [style.background]=\"resultBackground()\" -->\n <div bsThumb [style.background]=\"resultBackground()\"></div>\n</bs-slider>\n", styles: [".track{background-image:linear-gradient(45deg,#C0C0C0 25%,transparent 25%),linear-gradient(-45deg,#C0C0C0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#C0C0C0 75%),linear-gradient(-45deg,transparent 75%,#C0C0C0 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px}\n"], dependencies: [{ kind: "component", type: BsSliderComponent, selector: "bs-slider", inputs: ["disabled", "value"], outputs: ["valueChange"] }, { kind: "directive", type: BsThumbDirective, selector: "[bsThumb]" }, { kind: "directive", type: BsTrackDirective, selector: "[bsTrack]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
148
305
  }
149
306
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsAlphaStripComponent, decorators: [{
150
307
  type: Component,
151
308
  args: [{ selector: 'bs-alpha-strip', imports: [BsSliderComponent, BsThumbDirective, BsTrackDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<bs-slider [disabled]=\"disabled()\" [value]=\"alpha()\" (valueChange)=\"alphaChange.emit($event)\">\n <canvas bsTrack class=\" track position-absolute w-100\" #track></canvas>\n\n <!-- [style.background]=\"resultBackground()\" -->\n <div bsThumb [style.background]=\"resultBackground()\"></div>\n</bs-slider>\n", styles: [".track{background-image:linear-gradient(45deg,#C0C0C0 25%,transparent 25%),linear-gradient(-45deg,#C0C0C0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#C0C0C0 75%),linear-gradient(-45deg,transparent 75%,#C0C0C0 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px}\n"] }]
152
- }], ctorParameters: () => [], propDecorators: { canvas: [{ type: i0.ViewChild, args: ['track', { isSignal: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hs: [{ type: i0.Input, args: [{ isSignal: true, alias: "hs", required: false }] }, { type: i0.Output, args: ["hsChange"] }], luminosity: [{ type: i0.Input, args: [{ isSignal: true, alias: "luminosity", required: false }] }, { type: i0.Output, args: ["luminosityChange"] }], alpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "alpha", required: false }] }, { type: i0.Output, args: ["alphaChange"] }], alphaChange: [{ type: i0.Output, args: ["alphaChange"] }] } });
309
+ }], ctorParameters: () => [], propDecorators: { canvas: [{ type: i0.ViewChild, args: ['track', { isSignal: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hs: [{ type: i0.Input, args: [{ isSignal: true, alias: "hs", required: false }] }, { type: i0.Output, args: ["hsChange"] }], brightness: [{ type: i0.Input, args: [{ isSignal: true, alias: "brightness", required: false }] }, { type: i0.Output, args: ["brightnessChange"] }], alpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "alpha", required: false }] }, { type: i0.Output, args: ["alphaChange"] }], alphaChange: [{ type: i0.Output, args: ["alphaChange"] }] } });
310
+
311
+ class BsBrightnessStripComponent {
312
+ constructor() {
313
+ this.canvas = viewChild.required('canvas');
314
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
315
+ this.hs = model({ hue: 0, saturation: 0 }, ...(ngDevMode ? [{ debugName: "hs" }] : /* istanbul ignore next */ []));
316
+ this.brightness = model(1, ...(ngDevMode ? [{ debugName: "brightness" }] : /* istanbul ignore next */ []));
317
+ this.brightnessChange = output();
318
+ this.canvasContext = null;
319
+ this.resultBackground = computed(() => {
320
+ const hs = this.hs();
321
+ const brightness = this.brightness();
322
+ const rgb = hsv2rgb({ hue: hs.hue, saturation: hs.saturation, value: brightness });
323
+ return `rgb(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)})`;
324
+ }, ...(ngDevMode ? [{ debugName: "resultBackground" }] : /* istanbul ignore next */ []));
325
+ effect(() => {
326
+ const hs = this.hs();
327
+ if (this.canvasContext) {
328
+ const width = this.canvas().nativeElement.width;
329
+ const height = this.canvas().nativeElement.height;
330
+ this.canvasContext.clearRect(0, 0, width, height);
331
+ this.canvasContext.save();
332
+ const peak = hsv2rgb({ hue: hs.hue, saturation: hs.saturation, value: 1 });
333
+ const gradient = this.canvasContext.createLinearGradient(0, 0, width, 0);
334
+ gradient.addColorStop(0, 'rgb(0, 0, 0)');
335
+ gradient.addColorStop(1, `rgb(${Math.round(peak.r)}, ${Math.round(peak.g)}, ${Math.round(peak.b)})`);
336
+ this.canvasContext.fillStyle = gradient;
337
+ this.canvasContext.fillRect(0, 0, width, height);
338
+ }
339
+ });
340
+ effect(() => {
341
+ const brightness = this.brightness();
342
+ this.brightnessChange.emit(brightness);
343
+ });
344
+ }
345
+ ngAfterViewInit() {
346
+ if (typeof window !== 'undefined') {
347
+ this.canvasContext = this.canvas().nativeElement.getContext('2d', { willReadFrequently: true });
348
+ }
349
+ }
350
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsBrightnessStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
351
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.11", type: BsBrightnessStripComponent, isStandalone: true, selector: "bs-brightness-strip", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hs: { classPropertyName: "hs", publicName: "hs", isSignal: true, isRequired: false, transformFunction: null }, brightness: { classPropertyName: "brightness", publicName: "brightness", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { hs: "hsChange", brightness: "brightnessChange", brightnessChange: "brightnessChange" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: "<bs-slider [disabled]=\"disabled()\" [value]=\"brightness()\" (valueChange)=\"brightnessChange.emit($event)\">\n <canvas bsTrack class=\"position-absolute w-100\" #canvas></canvas>\n <div bsThumb [style.background]=\"resultBackground()\"></div>\n</bs-slider>\n", styles: [""], dependencies: [{ kind: "component", type: BsSliderComponent, selector: "bs-slider", inputs: ["disabled", "value"], outputs: ["valueChange"] }, { kind: "directive", type: BsThumbDirective, selector: "[bsThumb]" }, { kind: "directive", type: BsTrackDirective, selector: "[bsTrack]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
352
+ }
353
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsBrightnessStripComponent, decorators: [{
354
+ type: Component,
355
+ args: [{ selector: 'bs-brightness-strip', imports: [BsSliderComponent, BsThumbDirective, BsTrackDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<bs-slider [disabled]=\"disabled()\" [value]=\"brightness()\" (valueChange)=\"brightnessChange.emit($event)\">\n <canvas bsTrack class=\"position-absolute w-100\" #canvas></canvas>\n <div bsThumb [style.background]=\"resultBackground()\"></div>\n</bs-slider>\n" }]
356
+ }], ctorParameters: () => [], propDecorators: { canvas: [{ type: i0.ViewChild, args: ['canvas', { isSignal: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hs: [{ type: i0.Input, args: [{ isSignal: true, alias: "hs", required: false }] }, { type: i0.Output, args: ["hsChange"] }], brightness: [{ type: i0.Input, args: [{ isSignal: true, alias: "brightness", required: false }] }, { type: i0.Output, args: ["brightnessChange"] }], brightnessChange: [{ type: i0.Output, args: ["brightnessChange"] }] } });
153
357
 
154
358
  class BsColorPickerValueAccessor {
155
359
  constructor() {
156
360
  this.host = inject(BsColorPickerComponent);
157
- // Effect to emit value changes
361
+ // The hex most recently observed (either written by the form or emitted to it).
362
+ // Lets the emit effect dedup the echo from writeValue, breaking the round-trip loop.
363
+ this.lastHex = null;
158
364
  effect(() => {
159
365
  const hs = this.host.hs();
160
- const luminosity = this.host.luminosity();
161
- const rgb = this.hsl2rgb(hs.hue, hs.saturation, luminosity);
162
- const hex = this.rgb2hex(rgb);
163
- setTimeout(() => this.onValueChange && this.onValueChange(hex), 10);
366
+ const brightness = this.host.brightness();
367
+ const rgb = hsv2rgb({ hue: hs.hue, saturation: hs.saturation, value: brightness });
368
+ const hex = rgb2hex(rgb);
369
+ if (hex === this.lastHex)
370
+ return;
371
+ this.lastHex = hex;
372
+ this.onValueChange?.(hex);
164
373
  });
165
374
  }
166
- hsl2rgb(h, s, l) {
167
- const k = (n) => (n + h / 30) % 12;
168
- const a = s * Math.min(l, 1 - l);
169
- const f = (n) => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
170
- const retValue = { r: 255 * f(0), g: 255 * f(8), b: 255 * f(4) };
171
- return retValue;
172
- }
173
- //#region ControlValueAccessor implementation
174
375
  registerOnChange(fn) {
175
376
  this.onValueChange = fn;
176
377
  }
@@ -178,73 +379,16 @@ class BsColorPickerValueAccessor {
178
379
  this.onTouched = fn;
179
380
  }
180
381
  writeValue(value) {
181
- if (this.host && this.host.colorWheel()) {
182
- if (value) {
183
- const rgb = this.hex2rgb(value);
184
- const hsl = this.rgb2Hsl(rgb);
185
- this.host.hs.set({ hue: hsl.h, saturation: hsl.s });
186
- this.host.luminosity.set(hsl.l);
187
- }
188
- }
382
+ if (!value)
383
+ return;
384
+ const hsv = hex2hsv(value);
385
+ this.lastHex = rgb2hex(hsv2rgb(hsv));
386
+ this.host.hs.set({ hue: hsv.hue, saturation: hsv.saturation });
387
+ this.host.brightness.set(hsv.value);
189
388
  }
190
389
  setDisabledState(isDisabled) {
191
390
  this.host.disabled.set(isDisabled);
192
391
  }
193
- //#endregion
194
- //#region Color Conversion
195
- rgb2hex(rgb) {
196
- return '#' + (Math.round((rgb.r << 16) + (rgb.g << 8) + rgb.b)).toString(16).padStart(6, '0');
197
- }
198
- hex2rgb(hex) {
199
- const r = parseInt(hex.slice(1, 3), 16), g = parseInt(hex.slice(3, 5), 16), b = parseInt(hex.slice(5, 7), 16);
200
- return { r, g, b };
201
- }
202
- /**
203
- * Divide 1 to n, handling floating point errors.
204
- * Ensures that the value is in between 0 and 1.
205
- **/
206
- bound01(n, max) {
207
- n = Math.min(max, Math.max(0, n));
208
- if (Math.abs(n - max) < 0.000001) {
209
- return 1;
210
- }
211
- else {
212
- return (n % max) / max;
213
- }
214
- }
215
- rgb2Hsl(color) {
216
- const r01 = this.bound01(color.r, 255);
217
- const g01 = this.bound01(color.g, 255);
218
- const b01 = this.bound01(color.b, 255);
219
- const max = Math.max(r01, g01, b01);
220
- const min = Math.min(r01, g01, b01);
221
- let h, s;
222
- const l = (max + min) / 2;
223
- if (max === min) {
224
- h = s = 0;
225
- }
226
- else {
227
- const d = max - min;
228
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
229
- switch (max) {
230
- case r01:
231
- h = (g01 - b01) / d + (g01 < b01 ? 6 : 0);
232
- break;
233
- case g01:
234
- h = (b01 - r01) / d + 2;
235
- break;
236
- case b01:
237
- h = (r01 - g01) / d + 4;
238
- break;
239
- default: {
240
- throw 'Invalid operation';
241
- }
242
- }
243
- h /= 6;
244
- }
245
- h *= 360;
246
- return { h, s, l };
247
- }
248
392
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsColorPickerValueAccessor, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
249
393
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.11", type: BsColorPickerValueAccessor, isStandalone: true, selector: "bs-color-picker", providers: [{
250
394
  provide: NG_VALUE_ACCESSOR,
@@ -267,325 +411,73 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
267
411
 
268
412
  class BsColorWheelComponent {
269
413
  constructor() {
270
- this.element = inject((ElementRef));
271
- this.canvas = viewChild.required('canvas');
272
- // Inputs
414
+ this.surface = viewChild.required('surface');
273
415
  this.width = model(150, ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
274
416
  this.height = model(150, ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
275
- this.diameterRatio = model(0, ...(ngDevMode ? [{ debugName: "diameterRatio" }] : /* istanbul ignore next */ []));
276
- this.luminosity = model(0, ...(ngDevMode ? [{ debugName: "luminosity" }] : /* istanbul ignore next */ []));
277
- // HS model with output
417
+ this.brightness = model(1, ...(ngDevMode ? [{ debugName: "brightness" }] : /* istanbul ignore next */ []));
278
418
  this.hs = model({ hue: 0, saturation: 0 }, ...(ngDevMode ? [{ debugName: "hs" }] : /* istanbul ignore next */ []));
279
419
  this.hsChange = output();
280
- // Internal state
281
420
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
282
- this.viewInited = signal(false, ...(ngDevMode ? [{ debugName: "viewInited" }] : /* istanbul ignore next */ []));
283
421
  this.isPointerDown = signal(false, ...(ngDevMode ? [{ debugName: "isPointerDown" }] : /* istanbul ignore next */ []));
284
- this.canvasContext = null;
285
- // Computed values
286
- this.squareSize = computed(() => {
287
- const width = this.width();
288
- const height = this.height();
289
- if (width === null || height === null) {
290
- return null;
291
- }
292
- return Math.min(width, height);
293
- }, ...(ngDevMode ? [{ debugName: "squareSize" }] : /* istanbul ignore next */ []));
294
- this.shiftX = computed(() => {
295
- const width = this.width();
296
- const height = this.height();
297
- if (width === null || height === null) {
298
- return null;
299
- }
300
- else if (width < height) {
301
- return 0;
302
- }
303
- else {
304
- return (width - height) / 2;
305
- }
306
- }, ...(ngDevMode ? [{ debugName: "shiftX" }] : /* istanbul ignore next */ []));
307
- this.shiftY = computed(() => {
308
- const width = this.width();
309
- const height = this.height();
310
- if (width === null || height === null) {
311
- return null;
312
- }
313
- else if (width < height) {
314
- return (height - width) / 2;
315
- }
316
- else {
317
- return 0;
318
- }
319
- }, ...(ngDevMode ? [{ debugName: "shiftY" }] : /* istanbul ignore next */ []));
320
- this.innerRadius = computed(() => {
321
- const squareSize = this.squareSize();
322
- const diameterRatio = this.diameterRatio();
323
- if (squareSize) {
324
- return squareSize / 2 * diameterRatio;
325
- }
326
- else {
327
- return 0;
328
- }
329
- }, ...(ngDevMode ? [{ debugName: "innerRadius" }] : /* istanbul ignore next */ []));
330
- this.outerRadius = computed(() => {
331
- const squareSize = this.squareSize();
332
- if (squareSize) {
333
- return squareSize / 2;
334
- }
335
- else {
336
- return 150;
337
- }
338
- }, ...(ngDevMode ? [{ debugName: "outerRadius" }] : /* istanbul ignore next */ []));
422
+ this.squareSize = computed(() => Math.min(this.width(), this.height()), ...(ngDevMode ? [{ debugName: "squareSize" }] : /* istanbul ignore next */ []));
423
+ this.shiftX = computed(() => Math.max(0, (this.width() - this.height()) / 2), ...(ngDevMode ? [{ debugName: "shiftX" }] : /* istanbul ignore next */ []));
424
+ this.shiftY = computed(() => Math.max(0, (this.height() - this.width()) / 2), ...(ngDevMode ? [{ debugName: "shiftY" }] : /* istanbul ignore next */ []));
425
+ this.outerRadius = computed(() => this.squareSize() / 2, ...(ngDevMode ? [{ debugName: "outerRadius" }] : /* istanbul ignore next */ []));
426
+ this.overlayOpacity = computed(() => 1 - this.brightness(), ...(ngDevMode ? [{ debugName: "overlayOpacity" }] : /* istanbul ignore next */ []));
339
427
  this.markerPosition = computed(() => {
340
428
  const hs = this.hs();
341
- const shiftX = this.shiftX() ?? 0;
342
- const shiftY = this.shiftY() ?? 0;
343
- const position = this.color2position(hs);
344
- return {
345
- x: position.x + shiftX,
346
- y: position.y + shiftY,
347
- };
429
+ const radius = this.outerRadius();
430
+ const cx = this.shiftX() + radius;
431
+ const cy = this.shiftY() + radius;
432
+ const { dx, dy } = hs2polar(hs.hue, hs.saturation, radius);
433
+ return { x: cx + dx, y: cy + dy };
348
434
  }, ...(ngDevMode ? [{ debugName: "markerPosition" }] : /* istanbul ignore next */ []));
349
- // Draw color wheel when dimensions change
350
- effect(() => {
351
- const innerRadius = this.innerRadius();
352
- const outerRadius = this.outerRadius();
353
- const shiftX = this.shiftX();
354
- const shiftY = this.shiftY();
355
- // Use setTimeout to debounce slightly
356
- setTimeout(() => {
357
- if (this.canvasContext && innerRadius !== null && outerRadius !== null && shiftX !== null && shiftY !== null) {
358
- this.canvasContext.clearRect(0, 0, this.canvas().nativeElement.width, this.canvas().nativeElement.height);
359
- this.canvasContext.save();
360
- this.canvasContext.translate(shiftX + outerRadius, shiftY + outerRadius);
361
- for (let x = 0; x < 360; x++) {
362
- this.canvasContext.rotate(1 * Math.PI / 180);
363
- const gradient = this.canvasContext.createLinearGradient(innerRadius, 0, outerRadius, 0);
364
- gradient.addColorStop(0, `hsl(${x}, 0%, 50%)`);
365
- gradient.addColorStop(1, `hsl(${x}, 100%, 50%)`);
366
- this.canvasContext.fillStyle = gradient;
367
- this.canvasContext.fillRect(innerRadius, 0, outerRadius - innerRadius, outerRadius / 50);
368
- }
369
- this.canvasContext.restore();
370
- }
371
- }, 20);
372
- });
373
- // Emit HS changes
374
435
  effect(() => {
375
436
  const hs = this.hs();
376
437
  this.hsChange.emit(hs);
377
438
  });
378
439
  }
379
- ngAfterViewInit() {
380
- this.viewInited.set(true);
381
- if (typeof window !== 'undefined') {
382
- this.canvasContext = this.canvas().nativeElement.getContext('2d', { willReadFrequently: true });
383
- }
384
- }
385
440
  onPointerDown(ev) {
386
- if (!this.disabled()) {
441
+ if (this.disabled())
442
+ return;
443
+ if (!('touches' in ev))
387
444
  ev.preventDefault();
388
- ev.stopPropagation();
389
- this.isPointerDown.set(true);
390
- this.updateColor(ev, !('touches' in ev));
391
- }
445
+ ev.stopPropagation();
446
+ this.isPointerDown.set(true);
447
+ this.updateColor(ev);
392
448
  }
393
449
  onPointerMove(ev) {
394
- if (this.isPointerDown()) {
450
+ if (!this.isPointerDown())
451
+ return;
452
+ if (!('touches' in ev))
395
453
  ev.preventDefault();
396
- ev.stopPropagation();
397
- this.updateColor(ev, !('touches' in ev));
398
- }
399
- }
400
- onMouseMove(ev) {
401
- this.onPointerMove(ev);
454
+ ev.stopPropagation();
455
+ this.updateColor(ev);
402
456
  }
403
- onPointerUp(ev) {
457
+ onPointerUp(_ev) {
404
458
  this.isPointerDown.set(false);
405
459
  }
406
- updateColor(ev, subtract) {
407
- let co;
408
- const rect = this.canvas().nativeElement.getBoundingClientRect();
409
- if ('touches' in ev) {
410
- co = {
411
- x: ev.touches[0].clientX - rect.left,
412
- y: ev.touches[0].clientY - rect.top,
413
- };
414
- }
415
- else {
416
- co = {
417
- x: ev.clientX - (subtract ? rect.left : 0),
418
- y: ev.clientY - (subtract ? rect.top : 0),
419
- };
420
- }
421
- const color = this.position2color(co.x, co.y);
422
- if (color) {
423
- this.hs.set({ hue: color.hue, saturation: color.saturation });
424
- }
425
- else {
426
- console.warn('Color is null');
427
- }
428
- }
429
- isInsideCircle(x, y) {
430
- const squareSize = this.squareSize();
431
- const shiftX = this.shiftX();
432
- const shiftY = this.shiftY();
433
- // Position to the square
434
- const sx = x - (shiftX ?? 0);
435
- const sy = y - (shiftY ?? 0);
436
- // Square radius
437
- const sr = (squareSize ?? 0) / 2;
438
- const radius = Math.sqrt(Math.pow(sx - sr, 2) + Math.pow(sy - sr, 2));
439
- const angle = (Math.atan2(sr - sy, sr - sx) + Math.PI) % 360;
440
- return {
441
- inside: radius <= sr,
442
- angle
443
- };
444
- }
445
- position2color(x, y) {
446
- if (!this.canvasContext) {
447
- return null;
448
- }
449
- const result = this.isInsideCircle(x, y);
450
- if (result.inside) {
451
- const imageData = this.canvasContext.getImageData(x, y, 1, 1).data;
452
- const hsl = this.rgb2Hsl({ r: imageData[0], g: imageData[1], b: imageData[2] });
453
- return hsl;
454
- }
455
- return { hue: result.angle * 180 / Math.PI, saturation: 1, luminosity: 0.5 };
456
- }
457
- color2position(hs) {
458
- let innerRadius = this.innerRadius();
459
- let outerRadius = this.outerRadius();
460
- if (innerRadius === null) {
461
- innerRadius = 0;
462
- }
463
- if (!outerRadius) {
464
- outerRadius = 100;
465
- }
466
- const theta = hs.hue * Math.PI / 180;
467
- const c = {
468
- x: -outerRadius * Math.cos(theta),
469
- y: -outerRadius * Math.sin(theta)
470
- };
471
- const d = hs.saturation * (outerRadius - innerRadius) + innerRadius;
472
- const o = { x: outerRadius, y: outerRadius };
473
- return {
474
- x: o.x - d * (c.x / outerRadius),
475
- y: o.y - d * (c.y / outerRadius),
476
- };
477
- }
478
- rgb2Hsl(color) {
479
- const r01 = this.bound01(color.r, 255);
480
- const g01 = this.bound01(color.g, 255);
481
- const b01 = this.bound01(color.b, 255);
482
- const max = Math.max(r01, g01, b01);
483
- const min = Math.min(r01, g01, b01);
484
- let h, s;
485
- const l = (max + min) / 2;
486
- if (max === min) {
487
- h = s = 0;
488
- }
489
- else {
490
- const d = max - min;
491
- s = (l > 0.5) ? (d / (2 - max - min)) : (d / (max + min));
492
- switch (max) {
493
- case r01:
494
- {
495
- h = (g01 - b01) / d + ((g01 < b01) ? 6 : 0);
496
- }
497
- break;
498
- case g01:
499
- {
500
- h = (b01 - r01) / d + 2;
501
- }
502
- break;
503
- case b01:
504
- {
505
- h = (r01 - g01) / d + 4;
506
- }
507
- break;
508
- default: {
509
- throw 'Invalid operation';
510
- }
511
- }
512
- h /= 6;
513
- }
514
- h *= 360;
515
- return { hue: h, saturation: s, luminosity: l };
516
- }
517
- /**
518
- * Divide 1 to n, handling floating point errors.
519
- * Ensures that the value is in between 0 and 1.
520
- **/
521
- bound01(n, max) {
522
- n = Math.min(max, Math.max(0, n));
523
- if ((Math.abs(n - max) < 0.000001)) {
524
- return 1;
525
- }
526
- else {
527
- return (n % max) / max;
528
- }
460
+ updateColor(ev) {
461
+ const rect = this.surface().nativeElement.getBoundingClientRect();
462
+ const clientX = 'touches' in ev ? ev.touches[0].clientX : ev.clientX;
463
+ const clientY = 'touches' in ev ? ev.touches[0].clientY : ev.clientY;
464
+ const radius = this.outerRadius();
465
+ const dx = clientX - rect.left - radius;
466
+ const dy = clientY - rect.top - radius;
467
+ const hs = polar2hs(dx, dy, radius);
468
+ this.hs.set(hs);
529
469
  }
530
470
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsColorWheelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
531
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: BsColorWheelComponent, isStandalone: true, selector: "bs-color-wheel", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, diameterRatio: { classPropertyName: "diameterRatio", publicName: "diameterRatio", isSignal: true, isRequired: false, transformFunction: null }, luminosity: { classPropertyName: "luminosity", publicName: "luminosity", isSignal: true, isRequired: false, transformFunction: null }, hs: { classPropertyName: "hs", publicName: "hs", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { width: "widthChange", height: "heightChange", diameterRatio: "diameterRatioChange", luminosity: "luminosityChange", hs: "hsChange", hsChange: "hsChange" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onPointerUp($event)" }, classAttribute: "position-relative" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: "<canvas\n class=\"d-block\"\n [width]=\"width()\"\n [height]=\"height()\"\n (mousedown)=\"onPointerDown($event)\"\n (touchstart)=\"onPointerDown($event)\"\n (touchmove)=\"onPointerMove($event)\"\n (touchend)=\"onPointerUp($event)\"\n #canvas></canvas>\n\n@if (markerPosition(); as markerPosition) {\n <div class=\"thumb position-absolute pe-none\" [style.left.px]=\"markerPosition.x\" [style.top.px]=\"markerPosition.y\"></div>\n}\n", styles: [".thumb{width:30px;height:30px;border-radius:15px;margin-top:-15px;margin-left:-15px;box-sizing:border-box;border:2px solid white;box-shadow:#0000001a 0 0 10px 5px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
471
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: BsColorWheelComponent, isStandalone: true, selector: "bs-color-wheel", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, brightness: { classPropertyName: "brightness", publicName: "brightness", isSignal: true, isRequired: false, transformFunction: null }, hs: { classPropertyName: "hs", publicName: "hs", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { width: "widthChange", height: "heightChange", brightness: "brightnessChange", hs: "hsChange", hsChange: "hsChange" }, host: { listeners: { "document:mousemove": "onPointerMove($event)", "document:mouseup": "onPointerUp($event)" }, classAttribute: "position-relative" }, viewQueries: [{ propertyName: "surface", first: true, predicate: ["surface"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [style.width.px]=\"width()\" [style.height.px]=\"height()\" class=\"position-relative\">\n <div class=\"wheel-surface position-absolute\"\n [style.left.px]=\"shiftX()\"\n [style.top.px]=\"shiftY()\"\n [style.width.px]=\"squareSize()\"\n [style.height.px]=\"squareSize()\"\n (mousedown)=\"onPointerDown($event)\"\n (touchstart)=\"onPointerDown($event)\"\n (touchmove)=\"onPointerMove($event)\"\n (touchend)=\"onPointerUp($event)\"\n #surface></div>\n\n <div class=\"brightness-overlay position-absolute pe-none\"\n [style.opacity]=\"overlayOpacity()\"\n [style.left.px]=\"shiftX()\"\n [style.top.px]=\"shiftY()\"\n [style.width.px]=\"squareSize()\"\n [style.height.px]=\"squareSize()\"></div>\n\n @if (markerPosition(); as markerPosition) {\n <div class=\"thumb position-absolute pe-none\" [style.left.px]=\"markerPosition.x\" [style.top.px]=\"markerPosition.y\"></div>\n }\n</div>\n", styles: [".wheel-surface{border-radius:50%;background:radial-gradient(circle closest-side,#fff,transparent),conic-gradient(from 90deg,red,#ff0,#0f0,#0ff,#00f,#f0f,red);touch-action:none;cursor:crosshair}.brightness-overlay{background:#000;border-radius:50%;transition:opacity 60ms linear}.thumb{width:30px;height:30px;border-radius:15px;margin-top:-15px;margin-left:-15px;box-sizing:border-box;border:2px solid white;box-shadow:#0000001a 0 0 10px 5px;pointer-events:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
532
472
  }
533
473
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsColorWheelComponent, decorators: [{
534
474
  type: Component,
535
475
  args: [{ selector: 'bs-color-wheel', changeDetection: ChangeDetectionStrategy.OnPush, host: {
536
476
  'class': 'position-relative',
537
- '(document:mousemove)': 'onMouseMove($event)',
477
+ '(document:mousemove)': 'onPointerMove($event)',
538
478
  '(document:mouseup)': 'onPointerUp($event)',
539
- }, template: "<canvas\n class=\"d-block\"\n [width]=\"width()\"\n [height]=\"height()\"\n (mousedown)=\"onPointerDown($event)\"\n (touchstart)=\"onPointerDown($event)\"\n (touchmove)=\"onPointerMove($event)\"\n (touchend)=\"onPointerUp($event)\"\n #canvas></canvas>\n\n@if (markerPosition(); as markerPosition) {\n <div class=\"thumb position-absolute pe-none\" [style.left.px]=\"markerPosition.x\" [style.top.px]=\"markerPosition.y\"></div>\n}\n", styles: [".thumb{width:30px;height:30px;border-radius:15px;margin-top:-15px;margin-left:-15px;box-sizing:border-box;border:2px solid white;box-shadow:#0000001a 0 0 10px 5px}\n"] }]
540
- }], ctorParameters: () => [], propDecorators: { canvas: [{ type: i0.ViewChild, args: ['canvas', { isSignal: true }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }, { type: i0.Output, args: ["widthChange"] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }, { type: i0.Output, args: ["heightChange"] }], diameterRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "diameterRatio", required: false }] }, { type: i0.Output, args: ["diameterRatioChange"] }], luminosity: [{ type: i0.Input, args: [{ isSignal: true, alias: "luminosity", required: false }] }, { type: i0.Output, args: ["luminosityChange"] }], hs: [{ type: i0.Input, args: [{ isSignal: true, alias: "hs", required: false }] }, { type: i0.Output, args: ["hsChange"] }], hsChange: [{ type: i0.Output, args: ["hsChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
541
-
542
- class BsLuminosityStripComponent {
543
- constructor() {
544
- this.canvas = viewChild.required('canvas');
545
- this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
546
- this.hs = model({ hue: 0, saturation: 0 }, ...(ngDevMode ? [{ debugName: "hs" }] : /* istanbul ignore next */ []));
547
- this.luminosity = model(0.5, ...(ngDevMode ? [{ debugName: "luminosity" }] : /* istanbul ignore next */ []));
548
- this.luminosityChange = output();
549
- this.canvasContext = null;
550
- this.resultBackground = computed(() => {
551
- const hs = this.hs();
552
- const luminosity = this.luminosity();
553
- return `hsl(${hs.hue}, ${hs.saturation * 100}%, ${luminosity * 100}%)`;
554
- }, ...(ngDevMode ? [{ debugName: "resultBackground" }] : /* istanbul ignore next */ []));
555
- // Draw gradient when HS changes
556
- effect(() => {
557
- const hs = this.hs();
558
- if (this.canvasContext) {
559
- const width = this.canvas().nativeElement.width;
560
- const height = this.canvas().nativeElement.height;
561
- this.canvasContext.clearRect(0, 0, width, height);
562
- this.canvasContext.save();
563
- const gradient = this.canvasContext.createLinearGradient(0, 0, width, 0);
564
- gradient.addColorStop(0, `hsl(${hs.hue}, ${hs.saturation * 100}%, 0%)`);
565
- gradient.addColorStop(0.5, `hsl(${hs.hue}, ${hs.saturation * 100}%, 50%)`);
566
- gradient.addColorStop(1, `hsl(${hs.hue}, ${hs.saturation * 100}%, 100%)`);
567
- this.canvasContext.fillStyle = gradient;
568
- this.canvasContext.fillRect(0, 0, width, height);
569
- }
570
- });
571
- // Emit luminosity changes
572
- effect(() => {
573
- const luminosity = this.luminosity();
574
- this.luminosityChange.emit(luminosity);
575
- });
576
- }
577
- ngAfterViewInit() {
578
- if (typeof window !== 'undefined') {
579
- this.canvasContext = this.canvas().nativeElement.getContext('2d', { willReadFrequently: true });
580
- }
581
- }
582
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsLuminosityStripComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
583
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.11", type: BsLuminosityStripComponent, isStandalone: true, selector: "bs-luminosity-strip", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hs: { classPropertyName: "hs", publicName: "hs", isSignal: true, isRequired: false, transformFunction: null }, luminosity: { classPropertyName: "luminosity", publicName: "luminosity", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { hs: "hsChange", luminosity: "luminosityChange", luminosityChange: "luminosityChange" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: "<bs-slider [disabled]=\"disabled()\" [value]=\"luminosity()\" (valueChange)=\"luminosityChange.emit($event)\">\n <canvas bsTrack class=\"position-absolute w-100\" #canvas></canvas>\n <div bsThumb [style.background]=\"resultBackground()\"></div>\n</bs-slider>\n", styles: [""], dependencies: [{ kind: "component", type: BsSliderComponent, selector: "bs-slider", inputs: ["disabled", "value"], outputs: ["valueChange"] }, { kind: "directive", type: BsThumbDirective, selector: "[bsThumb]" }, { kind: "directive", type: BsTrackDirective, selector: "[bsTrack]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
584
- }
585
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsLuminosityStripComponent, decorators: [{
586
- type: Component,
587
- args: [{ selector: 'bs-luminosity-strip', imports: [BsSliderComponent, BsThumbDirective, BsTrackDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<bs-slider [disabled]=\"disabled()\" [value]=\"luminosity()\" (valueChange)=\"luminosityChange.emit($event)\">\n <canvas bsTrack class=\"position-absolute w-100\" #canvas></canvas>\n <div bsThumb [style.background]=\"resultBackground()\"></div>\n</bs-slider>\n" }]
588
- }], ctorParameters: () => [], propDecorators: { canvas: [{ type: i0.ViewChild, args: ['canvas', { isSignal: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hs: [{ type: i0.Input, args: [{ isSignal: true, alias: "hs", required: false }] }, { type: i0.Output, args: ["hsChange"] }], luminosity: [{ type: i0.Input, args: [{ isSignal: true, alias: "luminosity", required: false }] }, { type: i0.Output, args: ["luminosityChange"] }], luminosityChange: [{ type: i0.Output, args: ["luminosityChange"] }] } });
479
+ }, template: "<div [style.width.px]=\"width()\" [style.height.px]=\"height()\" class=\"position-relative\">\n <div class=\"wheel-surface position-absolute\"\n [style.left.px]=\"shiftX()\"\n [style.top.px]=\"shiftY()\"\n [style.width.px]=\"squareSize()\"\n [style.height.px]=\"squareSize()\"\n (mousedown)=\"onPointerDown($event)\"\n (touchstart)=\"onPointerDown($event)\"\n (touchmove)=\"onPointerMove($event)\"\n (touchend)=\"onPointerUp($event)\"\n #surface></div>\n\n <div class=\"brightness-overlay position-absolute pe-none\"\n [style.opacity]=\"overlayOpacity()\"\n [style.left.px]=\"shiftX()\"\n [style.top.px]=\"shiftY()\"\n [style.width.px]=\"squareSize()\"\n [style.height.px]=\"squareSize()\"></div>\n\n @if (markerPosition(); as markerPosition) {\n <div class=\"thumb position-absolute pe-none\" [style.left.px]=\"markerPosition.x\" [style.top.px]=\"markerPosition.y\"></div>\n }\n</div>\n", styles: [".wheel-surface{border-radius:50%;background:radial-gradient(circle closest-side,#fff,transparent),conic-gradient(from 90deg,red,#ff0,#0f0,#0ff,#00f,#f0f,red);touch-action:none;cursor:crosshair}.brightness-overlay{background:#000;border-radius:50%;transition:opacity 60ms linear}.thumb{width:30px;height:30px;border-radius:15px;margin-top:-15px;margin-left:-15px;box-sizing:border-box;border:2px solid white;box-shadow:#0000001a 0 0 10px 5px;pointer-events:none}\n"] }]
480
+ }], ctorParameters: () => [], propDecorators: { surface: [{ type: i0.ViewChild, args: ['surface', { isSignal: true }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }, { type: i0.Output, args: ["widthChange"] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }, { type: i0.Output, args: ["heightChange"] }], brightness: [{ type: i0.Input, args: [{ isSignal: true, alias: "brightness", required: false }] }, { type: i0.Output, args: ["brightnessChange"] }], hs: [{ type: i0.Input, args: [{ isSignal: true, alias: "hs", required: false }] }, { type: i0.Output, args: ["hsChange"] }], hsChange: [{ type: i0.Output, args: ["hsChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
589
481
 
590
482
  class BsColorPickerComponent {
591
483
  constructor() {
@@ -594,7 +486,7 @@ class BsColorPickerComponent {
594
486
  this.disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
595
487
  this.allowAlpha = input(true, ...(ngDevMode ? [{ debugName: "allowAlpha" }] : /* istanbul ignore next */ []));
596
488
  this.hs = signal({ hue: 0, saturation: 0 }, ...(ngDevMode ? [{ debugName: "hs" }] : /* istanbul ignore next */ []));
597
- this.luminosity = signal(0, ...(ngDevMode ? [{ debugName: "luminosity" }] : /* istanbul ignore next */ []));
489
+ this.brightness = signal(1, ...(ngDevMode ? [{ debugName: "brightness" }] : /* istanbul ignore next */ []));
598
490
  this.alpha = model(1, ...(ngDevMode ? [{ debugName: "alpha" }] : /* istanbul ignore next */ []));
599
491
  this.alphaChange = output();
600
492
  effect(() => {
@@ -603,16 +495,16 @@ class BsColorPickerComponent {
603
495
  });
604
496
  }
605
497
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
606
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: BsColorPickerComponent, isStandalone: true, selector: "bs-color-picker", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, allowAlpha: { classPropertyName: "allowAlpha", publicName: "allowAlpha", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { alpha: "alphaChange", alphaChange: "alphaChange" }, viewQueries: [{ propertyName: "colorWheel", first: true, predicate: ["wheel"], descendants: true, isSignal: true }], hostDirectives: [{ directive: BsColorPickerValueAccessor }], ngImport: i0, template: "@let letDisabled = disabled();\n@let letHS = hs();\n@let letLuminosity = luminosity();\n@let letAlpha = alpha();\n\n<bs-color-wheel [disabled]=\"letDisabled\" [hs]=\"letHS\" (hsChange)=\"hs.set($event)\" [luminosity]=\"letLuminosity\" [width]=\"size()\" [height]=\"size()\" #wheel></bs-color-wheel>\n<bs-luminosity-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [luminosity]=\"letLuminosity\" (luminosityChange)=\"luminosity.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #strip></bs-luminosity-strip>\n@if (allowAlpha()) {\n <bs-alpha-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [luminosity]=\"letLuminosity\" [alpha]=\"letAlpha\" (alphaChange)=\"alpha.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #alphaStrip></bs-alpha-strip>\n}\n", styles: [""], dependencies: [{ kind: "component", type: BsColorWheelComponent, selector: "bs-color-wheel", inputs: ["width", "height", "diameterRatio", "luminosity", "hs", "disabled"], outputs: ["widthChange", "heightChange", "diameterRatioChange", "luminosityChange", "hsChange"] }, { kind: "component", type: BsLuminosityStripComponent, selector: "bs-luminosity-strip", inputs: ["disabled", "hs", "luminosity"], outputs: ["hsChange", "luminosityChange"] }, { kind: "component", type: BsAlphaStripComponent, selector: "bs-alpha-strip", inputs: ["disabled", "hs", "luminosity", "alpha"], outputs: ["hsChange", "luminosityChange", "alphaChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
498
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: BsColorPickerComponent, isStandalone: true, selector: "bs-color-picker", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, allowAlpha: { classPropertyName: "allowAlpha", publicName: "allowAlpha", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { alpha: "alphaChange", alphaChange: "alphaChange" }, viewQueries: [{ propertyName: "colorWheel", first: true, predicate: ["wheel"], descendants: true, isSignal: true }], hostDirectives: [{ directive: BsColorPickerValueAccessor }], ngImport: i0, template: "@let letDisabled = disabled();\n@let letHS = hs();\n@let letBrightness = brightness();\n@let letAlpha = alpha();\n\n<bs-color-wheel [disabled]=\"letDisabled\" [hs]=\"letHS\" (hsChange)=\"hs.set($event)\" [brightness]=\"letBrightness\" [width]=\"size()\" [height]=\"size()\" #wheel></bs-color-wheel>\n<bs-brightness-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [brightness]=\"letBrightness\" (brightnessChange)=\"brightness.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #strip></bs-brightness-strip>\n@if (allowAlpha()) {\n <bs-alpha-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [brightness]=\"letBrightness\" [alpha]=\"letAlpha\" (alphaChange)=\"alpha.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #alphaStrip></bs-alpha-strip>\n}\n", styles: [""], dependencies: [{ kind: "component", type: BsColorWheelComponent, selector: "bs-color-wheel", inputs: ["width", "height", "brightness", "hs", "disabled"], outputs: ["widthChange", "heightChange", "brightnessChange", "hsChange"] }, { kind: "component", type: BsBrightnessStripComponent, selector: "bs-brightness-strip", inputs: ["disabled", "hs", "brightness"], outputs: ["hsChange", "brightnessChange"] }, { kind: "component", type: BsAlphaStripComponent, selector: "bs-alpha-strip", inputs: ["disabled", "hs", "brightness", "alpha"], outputs: ["hsChange", "brightnessChange", "alphaChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
607
499
  }
608
500
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BsColorPickerComponent, decorators: [{
609
501
  type: Component,
610
- args: [{ selector: 'bs-color-picker', imports: [BsColorWheelComponent, BsLuminosityStripComponent, BsAlphaStripComponent], changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [BsColorPickerValueAccessor], template: "@let letDisabled = disabled();\n@let letHS = hs();\n@let letLuminosity = luminosity();\n@let letAlpha = alpha();\n\n<bs-color-wheel [disabled]=\"letDisabled\" [hs]=\"letHS\" (hsChange)=\"hs.set($event)\" [luminosity]=\"letLuminosity\" [width]=\"size()\" [height]=\"size()\" #wheel></bs-color-wheel>\n<bs-luminosity-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [luminosity]=\"letLuminosity\" (luminosityChange)=\"luminosity.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #strip></bs-luminosity-strip>\n@if (allowAlpha()) {\n <bs-alpha-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [luminosity]=\"letLuminosity\" [alpha]=\"letAlpha\" (alphaChange)=\"alpha.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #alphaStrip></bs-alpha-strip>\n}\n" }]
502
+ args: [{ selector: 'bs-color-picker', imports: [BsColorWheelComponent, BsBrightnessStripComponent, BsAlphaStripComponent], changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [BsColorPickerValueAccessor], template: "@let letDisabled = disabled();\n@let letHS = hs();\n@let letBrightness = brightness();\n@let letAlpha = alpha();\n\n<bs-color-wheel [disabled]=\"letDisabled\" [hs]=\"letHS\" (hsChange)=\"hs.set($event)\" [brightness]=\"letBrightness\" [width]=\"size()\" [height]=\"size()\" #wheel></bs-color-wheel>\n<bs-brightness-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [brightness]=\"letBrightness\" (brightnessChange)=\"brightness.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #strip></bs-brightness-strip>\n@if (allowAlpha()) {\n <bs-alpha-strip [disabled]=\"letDisabled\" [hs]=\"letHS\" [brightness]=\"letBrightness\" [alpha]=\"letAlpha\" (alphaChange)=\"alpha.set($event)\" class=\"d-block mt-2\" [style.width.px]=\"size()\" #alphaStrip></bs-alpha-strip>\n}\n" }]
611
503
  }], ctorParameters: () => [], propDecorators: { colorWheel: [{ type: i0.ViewChild, args: ['wheel', { isSignal: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], allowAlpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAlpha", required: false }] }], alpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "alpha", required: false }] }, { type: i0.Output, args: ["alphaChange"] }], alphaChange: [{ type: i0.Output, args: ["alphaChange"] }] } });
612
504
 
613
505
  /**
614
506
  * Generated bundle index. Do not edit.
615
507
  */
616
508
 
617
- export { BsAlphaStripComponent, BsColorPickerComponent, BsColorPickerValueAccessor, BsColorWheelComponent, BsLuminosityStripComponent, BsSliderComponent, BsThumbDirective, BsTrackDirective };
509
+ export { BsAlphaStripComponent, BsBrightnessStripComponent, BsColorPickerComponent, BsColorPickerValueAccessor, BsColorWheelComponent, BsSliderComponent, BsThumbDirective, BsTrackDirective, hex2hsv, hex2rgb, hs2polar, hsl2hsv, hsl2rgb, hsv2hex, hsv2hsl, hsv2rgb, polar2hs, rgb2hex, rgb2hsl, rgb2hsv };
618
510
  //# sourceMappingURL=mintplayer-ng-bootstrap-color-picker.mjs.map