]> git.r.bdr.sh - rbdr/fyr/blob - js/fyr.js
7e7d94ba678e5d9c965539100a02fab12eb7148f
[rbdr/fyr] / js / fyr.js
1 var color = document.querySelector('.color'),
2 light = document.querySelector('.light'),
3 timeline = document.querySelector('.timeline'),
4 clear = document.querySelector('.clear'),
5 colors = [],
6 selecting = 0,
7 recording = 0,
8 animationTime = 0,
9 lastFrame = 0,
10 t = null,
11 h = 0,
12 s = 100,
13 l = 50,
14 {round, min, max} = Math;
15
16 function render() {
17 color.style.backgroundColor = `hsl(${h} ${s}% ${l}%)`;
18 light.style.transform = `translateY(-${l*2.2}px)`;
19 }
20
21 function renderTimeline() {
22 var background = 'linear-gradient(90deg,',
23 last = 0;
24 for (var {h, s, l, t: now} of colors) {
25 background += `hsl(${h} ${s}% ${l}%) ${round(100*last/3000)}%,`;
26 background += `hsl(${h} ${s}% ${l}%) ${round(100*(last+now)/3000)}%,`;
27 last += now;
28 }
29 background += `black ${round(100*last/3000)}%, black 101%)`;
30 timeline.style.background = background;
31 }
32
33 function length() {
34 return colors.map((c) => c.t).reduce((s, t) => s + t, 0);
35 }
36
37 function addColor() {
38 t = Date.now();
39 colors.push({h, s, l, t: 0});
40 }
41
42 function record() {
43 if (recording) setTimeout(record, 100);
44 var c = colors[colors.length - 1],
45 l = length();
46 if (c.h !== h || c.s !== s || c.l !== l) {
47 c.t = min(3000, Date.now() - t);
48 addColor();
49 c = colors[colors.length - 1];
50 }
51 if (l >= 3000) return;
52 c.t = min(3000, Date.now() - t);
53 renderTimeline();
54 }
55
56 function preview(current) {
57 if (selecting || recording) return;
58 window.requestAnimationFrame(preview);
59 var dt = current - lastFrame,
60 last = 0;
61 if (dt > 32) {
62 animationTime = (animationTime + dt) % 3000
63 color.style.background = `hsl(0 0% 0%)`;
64 for (var {h, s, l, t: now} of colors) {
65 if (animationTime >= last && animationTime < last+now) {
66 color.style.background = `hsl(${h} ${s}% ${l}%)`;
67 break;
68 }
69 last += now;
70 }
71 lastFrame = current;
72 }
73 }
74
75 color.addEventListener('mousemove', ({offsetX: x, offsetY: y}) => {
76 h = round(360 * x / 200);
77 s = round(100 * (200 - y) / 200);
78 render();
79 });
80
81 color.addEventListener('wheel', ({deltaY: y}) => {
82 selecting = 1;
83 l = min(max(0, l + y/4), 100)
84 render();
85 });
86
87 color.addEventListener('mousedown', () => {
88 addColor();
89 recording = 1;
90 setTimeout(record, 100);
91 });
92
93 color.addEventListener('mouseup', () => {
94 recording = 0;
95 });
96
97 color.addEventListener('mouseenter', () => {
98 selecting = 1;
99 });
100
101 color.addEventListener('mouseout', () => {
102 recording = 0;
103 selecting = 0;
104 window.requestAnimationFrame(preview);
105 });
106
107 clear.addEventListener('click', () => {
108 colors = [];
109 renderTimeline();
110 });
111
112 render();
113 renderTimeline();