Skip to content

Commit fd241e5

Browse files
committed
perf: removed recursion
1 parent 434ec47 commit fd241e5

File tree

2 files changed

+37
-54
lines changed

2 files changed

+37
-54
lines changed

src/index.ts

Lines changed: 30 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ type RgbType = {
55
};
66

77
export class Colors {
8-
result: string[];
9-
limit: number;
10-
prefix: boolean;
8+
result: string[] = [];
9+
limit: number = 0;
10+
prefix: boolean = false;
1111

12-
constructor() {
13-
this.result = [];
14-
this.limit = 0;
15-
this.prefix = false;
16-
}
12+
constructor() { }
1713

1814
#hex2Rgb(hex: string) {
1915
const sections = this.#hex2Groups(hex);
@@ -51,23 +47,28 @@ export class Colors {
5147
}
5248

5349
#padHex(color: string) {
54-
return `${color[0].padStart(2, color[0])}${color[1].padStart(2, color[1])}${color[2].padStart(2, color[2])}`;
50+
return `${color.padStart(6, color[0])}`
5551
}
5652

57-
#generateShades(rgb: RgbType, percentage: number) {
58-
const rgbShade = {
59-
red: this.#getShade(rgb.red, this.limit),
60-
green: this.#getShade(rgb.green, this.limit),
61-
blue: this.#getShade(rgb.blue, this.limit),
62-
};
63-
const hex = this.#rgb2hex(rgbShade);
64-
this.result.push(`${this.prefix ? '#' + hex : hex}`);
65-
this.limit += percentage;
66-
if (this.limit >= 100) {
67-
return;
53+
#generate(rgb: RgbType, percentage: number, type: 'shades' | 'tints') {
54+
const color: RgbType = { red: 0, green: 0, blue: 0 };
55+
56+
if (type === 'shades') {
57+
color.red = this.#getShade(rgb.red, this.limit);
58+
color.green = this.#getShade(rgb.green, this.limit);
59+
color.blue = this.#getShade(rgb.blue, this.limit);
60+
} else {
61+
color.red = this.#getTint(rgb.red, this.limit);
62+
color.green = this.#getTint(rgb.green, this.limit);
63+
color.blue = this.#getTint(rgb.blue, this.limit);
64+
}
65+
66+
while (this.limit < 100) {
67+
const hex = this.#rgb2hex(color);
68+
this.result.push(`${this.prefix ? '#' + hex : hex}`);
69+
this.limit += percentage;
6870
}
6971

70-
this.#generateShades(rgb, percentage);
7172
}
7273

7374
#getTint(color: number, percentage: number) {
@@ -76,21 +77,6 @@ export class Colors {
7677
return (tint > 255) ? 255 : tint;
7778
}
7879

79-
#generateTints(rgb: RgbType, percentage: number) {
80-
this.limit += percentage;
81-
const rgbTint = {
82-
red: this.#getTint(rgb.red, this.limit),
83-
green: this.#getTint(rgb.green, this.limit),
84-
blue: this.#getTint(rgb.blue, this.limit),
85-
};
86-
const hex = this.#rgb2hex(rgbTint);
87-
this.result.push(`${this.prefix ? '#' + hex : hex}`);
88-
if (this.limit >= 100) {
89-
return;
90-
}
91-
this.#generateTints(rgb, percentage);
92-
}
93-
9480
createColors(color: string, percentage: number, prefix: boolean = false) {
9581
// Check if the input exists
9682
if (!color || !percentage) {
@@ -100,14 +86,10 @@ export class Colors {
10086
if (typeof color !== 'string' || typeof percentage !== 'number' || typeof prefix !== 'boolean') {
10187
throw new Error('Invalid input. Wrong input types are given.');
10288
}
103-
// Check if the percentage is valid
104-
if (percentage < 0 || percentage > 100) {
105-
throw new Error('Invalid input. Invalid percentage value is given.')
106-
}
107-
// Check if HEX is valid
108-
if (color.length !== 3 && color.length !== 6) {
109-
throw new Error("Invalid input. Not a valid length.");
89+
if (color.length !== 3 && color.length !== 6 || percentage < 0 || percentage > 100) {
90+
throw new Error('Invalid input. Wrong input values are given.');
11091
}
92+
11193
// Pad the HEX string if it has only 3 characters
11294
if (color.length === 3) {
11395
color = this.#padHex(color);
@@ -118,15 +100,16 @@ export class Colors {
118100

119101
const rgb = this.#hex2Rgb(color);
120102
// Generate Tints
121-
this.#generateTints(rgb, percentage);
103+
this.#generate(rgb, percentage, 'tints');
122104
// Reset Limit
123105
this.limit = 0;
124106
// Generate Shades
125-
this.#generateShades(rgb, percentage);
107+
this.#generate(rgb, percentage, 'shades');
126108

127109
// Arrange colors in ascending order
128-
const tints = this.result.slice(0, this.result.length / 2).reverse();
129-
const shades = this.result.slice(this.result.length / 2, this.result.length).reverse();
110+
const mid = this.result.length / 2
111+
const tints = this.result.slice(0, mid).reverse();
112+
const shades = this.result.slice(mid).reverse();
130113
shades.unshift(`${this.prefix ? '#' + color : color}`);
131114

132115
// Reset global variables

tests/outputs/errors.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,28 @@ describe("throws an error", () => {
1717

1818
test("for invalid input length", () => {
1919
expect(() => ctx.createColors("66", 10)).toThrow(
20-
"Invalid input. Not a valid length."
20+
"Invalid input. Wrong input values are given."
2121
);
2222
expect(() => ctx.createColors("6", 10)).toThrow(
23-
"Invalid input. Not a valid length."
23+
"Invalid input. Wrong input values are given."
2424
);
2525
expect(() => ctx.createColors("6666", 10)).toThrow(
26-
"Invalid input. Not a valid length."
26+
"Invalid input. Wrong input values are given."
2727
);
2828
expect(() => ctx.createColors("66666", 10)).toThrow(
29-
"Invalid input. Not a valid length."
29+
"Invalid input. Wrong input values are given."
3030
);
3131
expect(() => ctx.createColors("6666666", 10)).toThrow(
32-
"Invalid input. Not a valid length."
32+
"Invalid input. Wrong input values are given."
3333
);
3434
});
3535

3636
test("for invalid percentage value", () => {
3737
expect(() => ctx.createColors("66", -10)).toThrow(
38-
"Invalid input. Invalid percentage value is given."
38+
"Invalid input. Wrong input values are given."
3939
);
4040
expect(() => ctx.createColors("66", 110)).toThrow(
41-
"Invalid input. Invalid percentage value is given."
41+
"Invalid input. Wrong input values are given."
4242
);
4343
});
4444

0 commit comments

Comments
 (0)