3
3
// https://opensource.org/licenses/MIT.
4
4
5
5
import { Value } from './value' ;
6
- import { fuzzyAssertInRange , fuzzyEquals , fuzzyRound } from './utils' ;
6
+ import { fuzzyAssertInRange , fuzzyEquals , fuzzyRound , positiveMod } from './utils' ;
7
7
import { hash } from 'immutable' ;
8
8
9
9
interface RgbColor {
10
10
red : number ;
11
11
green : number ;
12
12
blue : number ;
13
- alpha : number ;
13
+ alpha ? : number ;
14
14
}
15
15
16
16
interface HslColor {
17
17
hue : number ;
18
18
saturation : number ;
19
19
lightness : number ;
20
- alpha : number ;
20
+ alpha ? : number ;
21
21
}
22
22
23
23
interface HwbColor {
24
24
hue : number ;
25
25
whiteness : number ;
26
26
blackness : number ;
27
- alpha : number ;
27
+ alpha ? : number ;
28
28
}
29
29
30
30
/** A SassScript color. */
@@ -37,6 +37,9 @@ export class SassColor extends Value {
37
37
private lightnessInternal ?: number ;
38
38
private readonly alphaInternal : number ;
39
39
40
+ constructor ( color : RgbColor ) ;
41
+ constructor ( color : HslColor ) ;
42
+ constructor ( color : HwbColor ) ;
40
43
constructor ( color : RgbColor | HslColor | HwbColor ) {
41
44
super ( ) ;
42
45
@@ -60,7 +63,7 @@ export class SassColor extends Value {
60
63
'blue'
61
64
) ;
62
65
} else if ( 'saturation' in color ) {
63
- this . hueInternal = color . hue % 360 ;
66
+ this . hueInternal = positiveMod ( color . hue , 360 ) ;
64
67
this . saturationInternal = fuzzyAssertInRange (
65
68
color . saturation ,
66
69
0 ,
@@ -75,7 +78,7 @@ export class SassColor extends Value {
75
78
) ;
76
79
} else {
77
80
// From https://www.w3.org/TR/css-color-4/#hwb-to-rgb
78
- const scaledHue = ( color . hue % 360 ) / 360 ;
81
+ const scaledHue = positiveMod ( color . hue , 360 ) / 360 ;
79
82
let scaledWhiteness =
80
83
fuzzyAssertInRange ( color . whiteness , 0 , 100 , 'whiteness' ) / 100 ;
81
84
let scaledBlackness =
@@ -91,13 +94,13 @@ export class SassColor extends Value {
91
94
// don't cache its values because we expect the memory overhead of doing so
92
95
// to outweigh the cost of recalculating it on access. Instead, we eagerly
93
96
// convert it to RGB and then convert back if necessary.
94
- this . redInternal = toRgb (
97
+ this . redInternal = hwbToRgb (
95
98
scaledHue + 1 / 3 ,
96
99
scaledWhiteness ,
97
100
scaledBlackness
98
101
) ;
99
- this . greenInternal = toRgb ( scaledHue , scaledWhiteness , scaledBlackness ) ;
100
- this . blueInternal = toRgb (
102
+ this . greenInternal = hwbToRgb ( scaledHue , scaledWhiteness , scaledBlackness ) ;
103
+ this . blueInternal = hwbToRgb (
101
104
scaledHue - 1 / 3 ,
102
105
scaledWhiteness ,
103
106
scaledBlackness
@@ -186,6 +189,9 @@ export class SassColor extends Value {
186
189
/**
187
190
* Returns a copy of `this` with its channels changed to match `color`.
188
191
*/
192
+ change ( color : Partial < RgbColor > ) : SassColor ;
193
+ change ( color : Partial < HslColor > ) : SassColor ;
194
+ change ( color : Partial < HwbColor > ) : SassColor ;
189
195
change (
190
196
color : Partial < RgbColor > | Partial < HslColor > | Partial < HwbColor >
191
197
) : SassColor {
@@ -270,11 +276,11 @@ export class SassColor extends Value {
270
276
if ( max === min ) {
271
277
this . hueInternal = 0 ;
272
278
} else if ( max === scaledRed ) {
273
- this . hueInternal = ( ( 60 * ( scaledGreen - scaledBlue ) ) / delta ) % 360 ;
279
+ this . hueInternal = positiveMod ( ( 60 * ( scaledGreen - scaledBlue ) ) / delta , 360 ) ;
274
280
} else if ( max === scaledGreen ) {
275
- this . hueInternal = ( 120 + ( 60 * ( scaledBlue - scaledRed ) ) / delta ) % 360 ;
281
+ this . hueInternal = positiveMod ( 120 + ( 60 * ( scaledBlue - scaledRed ) ) / delta , 360 ) ;
276
282
} else if ( max === scaledBlue ) {
277
- this . hueInternal = ( 240 + ( 60 * ( scaledRed - scaledGreen ) ) / delta ) % 360 ;
283
+ this . hueInternal = positiveMod ( 240 + ( 60 * ( scaledRed - scaledGreen ) ) / delta , 360 ) ;
278
284
}
279
285
280
286
this . lightnessInternal = 50 * ( max + min ) ;
@@ -312,7 +318,7 @@ export class SassColor extends Value {
312
318
}
313
319
314
320
// A helper for converting HWB colors to RGB.
315
- function toRgb ( hue : number , scaledWhiteness : number , scaledBlackness : number ) {
321
+ function hwbToRgb ( hue : number , scaledWhiteness : number , scaledBlackness : number ) {
316
322
const factor = 1 - scaledWhiteness - scaledBlackness ;
317
323
const channel = hueToRgb ( 0 , 1 , hue ) * factor + scaledWhiteness ;
318
324
return fuzzyRound ( channel * 255 ) ;
0 commit comments