-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrainbow-elements.ts
66 lines (62 loc) · 2.46 KB
/
rainbow-elements.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const ReType = ["color", "backgroundColor", "fill", "stroke"] as const;
type ReType = typeof ReType[number];
const isReType = (type: string): type is ReType => {
return ReType.indexOf(type as any) !== -1;
};
const errorMessage = (type: string) => {
return `re-type error : "${type}" is not in re-type (${ReType.map((t) => `"${t}"`).join(" | ")})`;
};
class RainbowElements {
config: { attributes: boolean; childList: boolean; subtree: boolean };
observer;
constructor() {
this.config = { attributes: true, childList: true, subtree: true };
this.observer = new MutationObserver(this.paint);
}
paint() {
const maxHue = 270;
const targetDoms = document.querySelectorAll<HTMLElement>(".rainbow-elements");
targetDoms.forEach((targetDom) => {
const type = targetDom.dataset.reType || "color";
const saturation = targetDom.dataset.reSaturation || "1";
const lightness = targetDom.dataset.reLightness || "0.5";
const alpha = targetDom.dataset.reAlpha || "1";
const numOfElements = targetDom.children.length;
for (let index = 0; index < targetDom.children.length; ++index) {
const childDom = targetDom.children[index] as HTMLElement;
const hsla = `hsla(${index === 0 ? 0 : (maxHue / (numOfElements - 1)) * index}, ${
parseFloat(saturation) * 100 + "%"
}, ${parseFloat(lightness) * 100 + "%"}, ${alpha})`;
if (isReType(type)) {
childDom.style[type] = hsla;
} else {
throw new Error(errorMessage(type));
}
}
});
}
clear() {
const targetDoms = document.querySelectorAll<HTMLElement>(".rainbow-elements");
targetDoms.forEach((targetDom) => {
const type = targetDom.dataset.reType || "color";
for (let i = 0; i < targetDom.children.length; ++i) {
const childDom = targetDom.children[i] as HTMLElement;
if (isReType(type)) {
childDom.style[type] = "";
} else {
throw new Error(errorMessage(type));
}
}
});
}
run() {
this.paint();
this.observer.observe(document.body, this.config);
}
stop() {
this.clear();
this.observer.disconnect();
}
}
const re = new RainbowElements();
export { re };