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