]> git.r.bdr.sh - rbdr/fyr/commitdiff
Add the pattern selector
authorRuben Beltran del Rio <redacted>
Thu, 20 Jul 2023 19:14:07 +0000 (21:14 +0200)
committerRuben Beltran del Rio <redacted>
Thu, 20 Jul 2023 19:14:07 +0000 (21:14 +0200)
css/application.css
index.html
js/fyr.js [new file with mode: 0644]
js/updater.js [deleted file]

index 10333c373998c0d5c673172dab4f587779e268f4..66d05443cd23656d2df6bdf0124f1a2410a81ad0 100644 (file)
@@ -18,11 +18,50 @@ a {
   color: #4F8FE6;
 }
 
-.updater {
+.color-editor {
+  position: relative;
+  height: 230px;
+}
+
+.color {
   width: 200px;
   height: 200px;
   background: #fff;
-  border: 10px solid #0F261F;
+  margin-left: 20px;
+}
+
+.light {
+  width: 20px;
+  height: 20px;
+  background: #FA2B00;
+  position: absolute;
+  left: 220px;
+}
+
+.x-label, .y-label, .z-label {
+  margin: 0;
+  padding: 0;
+  color: #FA2B00;
+  width: 100px;
+  position: absolute;
+  top: 200px;
+}
+
+.y-label {
+  transform: rotate(-90deg);
+  left: -45px;
+  top: 135px;
+}
+
+.z-label {
+  left: 125px;
+}
+
+.timeline {
+  width: 200px;
+  height: 50px;
+  background: black;
+  margin: 0 0 0 20px;
 }
 
 @media (prefers-color-scheme: dark) {
@@ -30,9 +69,4 @@ a {
     color: #fff;
     background: #0F261F;
   }
-
-  .updater {
-    background: #0F261F;
-    border: 10px solid #fff;
-  }
 }
index e503143a3b4acb220481b635aa5934a05356d7a4..257cfe47f6bcdaa5c710664d0dc86eb0a6837387 100644 (file)
@@ -15,7 +15,7 @@
     <link rel="icon" type="image/png" sizes="96x96" href="/images/icon96.png">
     <link rel="icon" type="image/png" sizes="16x16" href="/images/icon16.png">
 
-    <script type="module" src="/js/updater.js"></script>
+    <script type="module" src="/js/fyr.js"></script>
   </head>
   <body>
     <div class="content-wrapper">
         <h1><img alt="" src="/images/logo.png" />Fyr.</h1>
         <p>Communicate through light.</p>
         <h2>Update Status</h2>
-        <div class="updater" />
+        <p>Move your mouse around the color box to change hue and saturation. Scroll inside the box to adjust lightness. Press to start recording the color in the timeline, release to stop.</p>
+        <div class="timeline"></div>
+        <div class="color-editor">
+          <div class="color"></div>
+          <div class="light"></div>
+          <p class="x-label">Hue →</p>
+          <p class="z-label">Lightness ⇈</p>
+          <p class="y-label">Saturation →</p>
+        </div>
+        <button class="post">Post</button>
+        <button class="clear">Clear</button>
       </main>
     </div>
   </body>
diff --git a/js/fyr.js b/js/fyr.js
new file mode 100644 (file)
index 0000000..e6c727c
--- /dev/null
+++ b/js/fyr.js
@@ -0,0 +1,112 @@
+var color = document.querySelector('.color'),
+    light = document.querySelector('.light'),
+    timeline = document.querySelector('.timeline'),
+    clear = document.querySelector('.clear'),
+    colors = [],
+    selecting = false,
+    recording = false,
+    animationTime = 0,
+    lastFrame = 0,
+    t = null,
+    h = 0,
+    s = 100,
+    l = 50;
+
+function render() {
+  color.style.backgroundColor = `hsl(${h} ${s}% ${l}%)`;
+  light.style.transform = `translateY(-${l*2.2}px)`;
+}
+
+function renderTimeline() {
+  var background = 'linear-gradient(90deg,',
+      last = 0;
+  for (var {h, s, l, t: now} of colors) {
+    background += `hsl(${h} ${s}% ${l}%) ${Math.round(100*last/3000)}%,`;
+    background += `hsl(${h} ${s}% ${l}%) ${Math.round(100*(last+now)/3000)}%,`;
+    last += now;
+  }
+  background += `black ${Math.round(100*last/3000)}%, black 101%)`;
+  timeline.style.background = background;
+}
+
+function length() {
+  return colors.map((c) => c.t).reduce((s, t) => s + t, 0);
+}
+
+function addColor() {
+  t = Date.now();
+  colors.push({h, s, l, t: 0});
+}
+
+function record() {
+  if (recording) setTimeout(record, 100);
+  var c = colors[colors.length - 1],
+      l = length();
+  if (c.h !== h || c.s !== s || c.l !== l) {
+    c.t = Math.min(3000, Date.now() - t);
+    addColor();
+    c = colors[colors.length - 1];
+  }
+  if (l >= 3000) return;
+  c.t = Math.min(3000, Date.now() - t);
+  renderTimeline();
+}
+
+function preview(current) {
+  if (selecting || recording) return; 
+  window.requestAnimationFrame(preview);
+  var dt = current - lastFrame,
+      last = 0;
+  if (dt > 32) {
+    animationTime = (animationTime + dt) % 3000
+    color.style.background = `hsl(0 0% 0%)`;
+    for (var {h, s, l, t: now} of colors) {
+      if (animationTime >= last && animationTime < last+now) {
+        color.style.background = `hsl(${h} ${s}% ${l}%)`;
+        break;
+      }
+      last += now;
+    }
+    lastFrame = current;
+  }
+}
+
+color.addEventListener('mousemove', ({offsetX: x, offsetY: y}) => {
+  h = Math.round(360 * x / 200);
+  s = Math.round(100 * (200 - y) / 200);
+  render();
+});
+
+color.addEventListener('wheel', ({deltaY: y}) => {
+  selecting = true;
+  l = Math.min(Math.max(0, l + y/4), 100)
+  render();
+});
+
+color.addEventListener('mousedown', () => {
+  addColor();
+  recording = true;
+  setTimeout(record, 100);
+});
+
+color.addEventListener('mouseup', () => {
+  recording = false;
+});
+
+color.addEventListener('mouseenter', () => {
+  selecting = true;
+});
+
+color.addEventListener('mouseout', () => {
+  recording = false;
+  selecting = false;
+  window.requestAnimationFrame(preview);
+});
+
+clear.addEventListener('click', () => {
+  colors = [];
+  renderTimeline();
+});
+
+render();
+renderTimeline();
diff --git a/js/updater.js b/js/updater.js
deleted file mode 100644 (file)
index 91c447e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-function getColors({x, y}, [{x: ax, y: ay}, {x: bx, y: by}, {x: cx, y: cy}]) {
-
-  if (x < 50 && y < 50) return {r: 255, g: 255, b: 255};
-  if (x > 150 && y < 50) return {r: 0, g: 0, b: 0};
-
-  var { abs, round, min } = Math,
-      area = abs((bx - ax) * (cy - ay) - (cx - ax) * (by - ay)),
-      R = abs((bx - x) * (cy - y) - (cx - x) * (by - y)),
-      G = abs((ax - x) * (cy - y) - (cx - x) * (ay - y)),
-      B = abs((ax - x) * (by - y) - (bx - x) * (ay - y));
-
-  // Normalize the areas to get the weights
-  const weights = {
-    r: round(255 * min(1, R / area)),
-    g: round(255 * min(1, G / area)),
-    b: round(255 * min(1, B / area))
-  };
-
-  return weights;
-}
-
-var updater = document.querySelector('.updater'),
-    color = {r: 0, g: 0, b: 0};
-updater.addEventListener('mousemove', ({offsetX: x, offsetY: y}) => {
-  var {r, g, b} = color = getColors(
-    {x, y},
-    [{x: 0, y: 200}, {x: 200, y: 200}, {x: 100, y: 0}]
-  )
-  updater.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
-});
-updater.addEventListener('mousedown', () => {
-  console.log('Adding Color', color);
-});
-updater.addEventListener('mouseup', () => {
-  console.log('Stop Adding Color', color);
-});