|
1 | | -import type { ColorInput, HSL, HSV, RGB } from './types'; |
| 1 | +import type { ColorInput, HSL, HSV, OptionalA, RGB } from './types'; |
2 | 2 |
|
3 | 3 | type ParseNumber = (num: number, txt: string, index: number) => number; |
4 | 4 |
|
@@ -76,15 +76,20 @@ export class FastColor { |
76 | 76 |
|
77 | 77 | constructor(input: ColorInput) { |
78 | 78 | if (typeof input === 'string') { |
79 | | - const trimed = input.trim(); |
80 | | - if (trimed[0] === '#') { |
81 | | - this.fromHexString(trimed); |
82 | | - } else if (trimed.startsWith('rgb')) { |
83 | | - this.fromRgbString(trimed); |
84 | | - } else if (trimed.startsWith('hsl')) { |
85 | | - this.fromHslString(trimed); |
86 | | - } else if (trimed.startsWith('hsv') || trimed.startsWith('hsb')) { |
87 | | - this.fromHsvString(trimed); |
| 79 | + const trimStr = input.trim(); |
| 80 | + |
| 81 | + function matchPrefix(prefix: string) { |
| 82 | + return trimStr.startsWith(prefix); |
| 83 | + } |
| 84 | + |
| 85 | + if (/^#?[A-F\d]{3,8}$/i.test(trimStr)) { |
| 86 | + this.fromHexString(trimStr); |
| 87 | + } else if (matchPrefix('rgb')) { |
| 88 | + this.fromRgbString(trimStr); |
| 89 | + } else if (matchPrefix('hsl')) { |
| 90 | + this.fromHslString(trimStr); |
| 91 | + } else if (matchPrefix('hsv') || matchPrefix('hsb')) { |
| 92 | + this.fromHsvString(trimStr); |
88 | 93 | } |
89 | 94 | } else if ('r' in input && 'g' in input && 'b' in input) { |
90 | 95 | this.r = input.r; |
@@ -401,23 +406,32 @@ export class FastColor { |
401 | 406 | return this._min; |
402 | 407 | } |
403 | 408 |
|
404 | | - private fromHexString(trimed: string) { |
405 | | - if (trimed.length < 6) { |
| 409 | + private fromHexString(trimStr: string) { |
| 410 | + const withoutPrefix = trimStr.replace('#', ''); |
| 411 | + |
| 412 | + function connectNum(index1: number, index2?: number) { |
| 413 | + return parseInt( |
| 414 | + withoutPrefix[index1] + withoutPrefix[index2 || index1], |
| 415 | + 16, |
| 416 | + ); |
| 417 | + } |
| 418 | + |
| 419 | + if (withoutPrefix.length < 6) { |
406 | 420 | // #rgb or #rgba |
407 | | - this.r = parseInt(trimed[1] + trimed[1], 16); |
408 | | - this.g = parseInt(trimed[2] + trimed[2], 16); |
409 | | - this.b = parseInt(trimed[3] + trimed[3], 16); |
410 | | - this.a = trimed[4] ? parseInt(trimed[4] + trimed[4], 16) / 255 : 1; |
| 421 | + this.r = connectNum(0); |
| 422 | + this.g = connectNum(1); |
| 423 | + this.b = connectNum(2); |
| 424 | + this.a = withoutPrefix[3] ? connectNum(3) / 255 : 1; |
411 | 425 | } else { |
412 | 426 | // #rrggbb or #rrggbbaa |
413 | | - this.r = parseInt(trimed[1] + trimed[2], 16); |
414 | | - this.g = parseInt(trimed[3] + trimed[4], 16); |
415 | | - this.b = parseInt(trimed[5] + trimed[6], 16); |
416 | | - this.a = trimed[8] ? parseInt(trimed[7] + trimed[8], 16) / 255 : 1; |
| 427 | + this.r = connectNum(0, 1); |
| 428 | + this.g = connectNum(2, 3); |
| 429 | + this.b = connectNum(4, 5); |
| 430 | + this.a = withoutPrefix[6] ? connectNum(6, 7) / 255 : 1; |
417 | 431 | } |
418 | 432 | } |
419 | 433 |
|
420 | | - private fromHsl({ h, s, l, a }: HSL): void { |
| 434 | + private fromHsl({ h, s, l, a }: OptionalA<HSL>): void { |
421 | 435 | this._h = h % 360; |
422 | 436 | this._s = s; |
423 | 437 | this._l = l; |
@@ -464,7 +478,7 @@ export class FastColor { |
464 | 478 | this.b = Math.round((this.b + lightnessModification) * 255); |
465 | 479 | } |
466 | 480 |
|
467 | | - private fromHsv({ h, s, v, a }: HSV): void { |
| 481 | + private fromHsv({ h, s, v, a }: OptionalA<HSV>): void { |
468 | 482 | this._h = h % 360; |
469 | 483 | this._s = s; |
470 | 484 | this._v = v; |
|
0 commit comments