Browse Source

Implement prev color tracker

Kirk Trombley 2 năm trước cách đây
mục cha
commit
c2e1098ade
4 tập tin đã thay đổi với 65 bổ sung27 xóa
  1. 15 4
      index.html
  2. 3 0
      math.js
  3. 16 4
      script.js
  4. 31 19
      styles.css

+ 15 - 4
index.html

@@ -196,18 +196,29 @@
     <!-- <form id="sortMetric"></form>
     <form id="clusterMetric"></form> -->
 
-    <div class="sidebar | flow">
+    <div class="sidebar | section | flow">
       <form id="colorSelect" class="flex col small-gap" autocomplete="off">
-        <label class="emphasis" for="color-input-text">Target Color</label>
+        <label class="emphasis" for="colorInputText">Target Color</label>
         <div class="color-inputs | flex small-gap">
-          <input name="colorText" type="text" pattern="#?[0-9a-fA-F]*" maxlength="7" />
+          <input
+            id="colorInputText"
+            name="colorText"
+            type="text"
+            pattern="#?[0-9a-fA-F]*"
+            maxlength="7"
+          />
           <input name="colorPicker" type="color" />
         </div>
         <button type="button" bind-to="randomButton">Random Color</button>
       </form>
     </div>
 
-    <main>test</main>
+    <main class="section">test</main>
+
+    <div class="section | flow">
+      <div class="emphasis center">Previous Colors</div>
+      <div id="prevColors"></div>
+    </div>
     <!-- 
       <form action="javascript:void(0);" id="sortControl" autocomplete="off">
         <div>

+ 3 - 0
math.js

@@ -5,6 +5,9 @@ const vectorMag = (v) => Math.sqrt(vectorDot(v, v));
 // Angle Math
 const rad2deg = 180 / Math.PI;
 
+// Misc
+const clamp = (mn, v, mx) => Math.min(Math.max(v, mn), mx);
+
 // Contrast
 const getContrastingTextColor = (hex) => {
   const { r, g, b } = d3.color(hex);

+ 16 - 4
script.js

@@ -14,9 +14,21 @@ U.element("colorSelect", ({ randomButton }, form) => {
 
 randomizeTargetColor();
 
-U.reactive(() => {
-  const contrast = getContrastingTextColor(targetColor.value);
+targetColor.subscribe((hex, { previous }) => {
   const style = document.querySelector(":root").style;
-  style.setProperty("--background", targetColor.value);
-  style.setProperty("--highlight", contrast);
+  style.setProperty("--background", hex);
+  style.setProperty("--highlight", getContrastingTextColor(hex));
+
+  if (previous) {
+    const prevButton = document.createElement("button");
+    prevButton.innerText = previous;
+    const { h, s, l } = d3.hsl(previous);
+    prevButton.style = `
+      color: ${getContrastingTextColor(previous)}; 
+      --button-bg: ${previous};
+      --button-bg-hover: ${d3.hsl(h, s, clamp(0.25, l * 1.25, 0.9)).formatHex()};
+    `;
+    prevButton.addEventListener("click", () => (targetColor.value = previous));
+    document.getElementById("prevColors").prepend(prevButton);
+  }
 });

+ 31 - 19
styles.css

@@ -87,13 +87,29 @@ body {
   --gap: 0.5rem;
 }
 
+.section {
+  padding-block-start: var(--flow-space, 1rem);
+  padding-inline: calc(var(--flow-space, 1rem) / 2);
+}
+
 /* Utility */
 
 .emphasis {
-  font-size: 1.2rem;
+  font-size: 1.125rem;
   font-weight: 600;
 }
 
+.center {
+  text-align: center;
+  margin-inline: auto;
+}
+
+button {
+  border-radius: 100vmax;
+  padding-block: 0.25rem;
+  border: 1px solid var(--highlight);
+}
+
 /* Block */
 
 body {
@@ -101,32 +117,28 @@ body {
   background-color: var(--background);
   accent-color: var(--highlight);
   transition: accent-color 250ms, color 250ms, background-color 250ms;
+
+  display: grid;
+  grid-template-columns: 14rem 1fr 8rem;
 }
 
-.sidebar {
-  position: fixed;
-  width: 14rem;
-  height: 100%;
-  border-right: 1px solid var(--highlight);
-  padding-block-start: var(--flow-space, 1rem);
-  padding-inline: calc(var(--flow-space, 1rem) / 2);
+body > * + * {
+  border-inline-start: 1px solid var(--highlight);
 }
 
-main {
-  position: relative;
-  width: calc(100% - 14rem);
-  padding-inline: calc(var(--flow-space, 1rem) / 2);
-  float: right;
+#prevColors button {
+  width: 100%;
+  margin-block-end: 0.5ch;
+  background-color: var(--button-bg);
+  transition: background-color 100ms;
 }
 
-#colorSelect label {
-  text-align: center;
+#prevColors button:hover {
+  background-color: var(--button-bg-hover);
 }
 
-#colorSelect button {
-  border-radius: 100vmax;
-  padding-block: 0.25rem;
-  border: 1px solid var(--highlight);
+#colorSelect label {
+  text-align: center;
 }
 
 #colorSelect input[type="text"] {