Browse Source

more layout changes, and a few sprite fixes

Kirk Trombley 2 năm trước cách đây
mục cha
commit
dc8d41037c
3 tập tin đã thay đổi với 284 bổ sung191 xóa
  1. 202 145
      web/index.html
  2. 7 6
      web/main.js
  3. 75 40
      web/styles.css

+ 202 - 145
web/index.html

@@ -4,6 +4,10 @@
     <meta charset="utf-8" />
     <title>Pokemon By Color</title>
     <link rel="stylesheet" href="styles.css" />
+    <link
+      rel="stylesheet"
+      href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0"
+    />
     <script src="https://unpkg.com/fuse.js@6.5.3/dist/fuse.min.js"></script>
     <script src="database.js"></script>
     <script src="main.js" defer></script>
@@ -16,20 +20,20 @@
       <form
         action="javascript:void(0)"
         autocomplete="off"
-        class="metric-fields | flex col small-gap"
+        class="metric-fields | flex center-items smaller-gap"
       >
         <output hidden name="metric"></output>
-        <div class="flex center">
+        <div class="metric-kind-toggle | flex col center-content">
           <label>
             <input type="radio" name="metricKind" value="compare" />
             <div class="toggle-label | center pill-shape highlight-border">Compare</div>
           </label>
           <label>
             <input type="radio" name="metricKind" value="stat" />
-            <div class="toggle-label | center pill-shape highlight-border">Stat</div>
+            <div class="toggle-label | center pill-shape highlight-border">Statistic</div>
           </label>
         </div>
-        <select class="pill-shape highlight-border" name="compare" disabled>
+        <select class="pill-shape highlight-border ellipsis" name="compare" disabled>
           <option value="arcDiff">Arc Difference (Ω)</option>
           <option value="psi">RMS Deviation (Ψ)</option>
           <option value="theta">Quasi-mean Angular Difference (Θ)</option>
@@ -45,7 +49,7 @@
           <option value="deltaC">Chroma Difference (ΔC)</option>
           <option value="deltaH">Hue Angular Difference (Δh)</option>
         </select>
-        <select class="pill-shape highlight-border" name="stat" disabled>
+        <select class="pill-shape highlight-border ellipsis" name="stat" disabled>
           <option value="size">Size (N)</option>
           <option value="stddevTotal">Standard Deviation (σ)</option>
           <option value="deltaL">Mean Lightness (L̅)</option>
@@ -84,7 +88,7 @@
 
     <template id="pkmn-tile-template">
       <div class="pkmn-tile | flex col no-gap" bind-to="tileRoot">
-        <div class="pkmn-title | emphasis flex">
+        <div class="pkmn-title | emphasis flex center-items">
           <span class="ellipsis" bind-to="name"></span>
         </div>
         <div class="pkmn-info | highlight-border flex">
@@ -93,11 +97,17 @@
           <div class="pkmn-info-detail | math-font grid" bind-to="cls2Data"></div>
           <div class="pkmn-info-detail | math-font grid" bind-to="cls3Data"></div>
           <div class="pkmn-info-detail | math-font grid" bind-to="cls4Data"></div>
-          <div class="pkmn-info-main | flex col">
-            <a bind-to="link" target="_blank" rel="noopener noreferrer" href="">
+          <div class="pkmn-info-main | flex col smaller-gap">
+            <a
+              bind-to="link"
+              class="iflex center-content center-items"
+              target="_blank"
+              rel="noopener noreferrer"
+              href=""
+            >
               <img bind-to="image" />
             </a>
-            <div class="pkmn-score-row | flex">
+            <div class="pkmn-score-row | flex center-items">
               <div class="math-font" bind-to="score"></div>
               <div class="smaller">"<span bind-to="color"></span>"</div>
             </div>
@@ -109,7 +119,7 @@
               <span class="pkmn-info-icon | smaller" bind-to="infoHover">ⓘ</span>
             </div>
           </div>
-          <div class="cluster-buttons | math-font flex col">
+          <div class="cluster-buttons | math-font flex center-content col smaller-gap">
             <div class="flex">
               <button bind-to="cls1Btn" class="color-select" hidden></button>
               <span class="pkmn-info-icon | smaller" bind-to="infoHover1">ⓘ</span>
@@ -164,28 +174,37 @@
       autocomplete="off"
     ></form>
 
-    <div class="section flow small-flow-space">
-      <div class="color-inputs | flex col small-gap">
-        <label class="emphasis center" for="colorInputText">Target Color</label>
-        <div class="flex small-gap">
-          <input
-            form="targetColorForm"
-            class="pill-shape highlight-border"
-            name="colorText"
-            type="text"
-            pattern="#?[0-9a-fA-F]{0,6}"
-            maxlength="7"
-            placeholder="#000000"
-          />
-          <input form="targetColorForm" name="colorPicker" type="color" />
+    <main class="section flow">
+      <div class="flex wrap small-gap">
+        <!-- Color Select -->
+        <div id="sort-inputs" class="control-block | flex col smaller-gap center-items">
+          <div class="flex center-content center-items small-gap wrap">
+            <input
+              form="targetColorForm"
+              class="pill-shape highlight-border"
+              name="colorText"
+              type="text"
+              pattern="#?[0-9a-fA-F]{0,6}"
+              maxlength="7"
+              placeholder="#000000"
+            />
+            <input form="targetColorForm" name="colorPicker" type="color" />
+            <button
+              title="Randomize Color"
+              class="icon-button | material-symbols-outlined"
+              type="button"
+              form="targetColorForm"
+              name="randomColor"
+            >
+              shuffle
+            </button>
+          </div>
+          <output class="smaller" form="targetColorForm" name="info"></output>
         </div>
-        <button type="button" form="targetColorForm" name="randomColor">
-          Random Color
-        </button>
-        <output class="center smaller" form="targetColorForm" name="info"></output>
-        <div class="center">
+        <!-- Filter/Limit -->
+        <div class="control-block | flex center-items">
           <label>
-            <div class="emphasis">
+            <div class="center emphasis">
               Results:&nbsp;<output form="colorDisplayForm" name="output">10</output>
             </div>
             <input
@@ -197,160 +216,198 @@
               value="10"
             />
           </label>
+          <div id="filter-toggles" class="flex col">
+            <label class="center">
+              <input
+                form="filterControl"
+                type="checkbox"
+                name="allowRepeatDexNum"
+                hidden
+              />
+              <span class="toggle-label | pill-shape highlight-border">
+                Repeat Species
+              </span>
+            </label>
+            <label class="center">
+              <input
+                form="filterControl"
+                type="checkbox"
+                name="hideNoStart"
+                hidden
+                checked
+              />
+              <span class="toggle-label | pill-shape highlight-border">
+                Start Forms Only
+              </span>
+            </label>
+            <label class="center">
+              <input
+                form="filterControl"
+                type="checkbox"
+                name="allowNFE"
+                hidden
+                checked
+              />
+              <span class="toggle-label | pill-shape highlight-border">
+                Include NFE
+              </span>
+            </label>
+          </div>
         </div>
-        <label class="center">
-          <input form="filterControl" type="checkbox" name="allowRepeatDexNum" hidden />
-          <span class="toggle-label | pill-shape highlight-border">Repeat Species</span>
-        </label>
-        <label class="center">
-          <input form="filterControl" type="checkbox" name="hideNoStart" hidden checked />
-          <span class="toggle-label | pill-shape highlight-border">Start Forms Only</span>
-        </label>
-        <label class="center">
-          <input form="filterControl" type="checkbox" name="allowNFE" hidden checked />
-          <span class="toggle-label | pill-shape highlight-border">Include NFE</span>
-        </label>
-      </div>
-      <hr />
-      <div class="emphasis center">Sort Function</div>
-      <div id="sort-metric-mount"></div>
-      <!-- Main Sort Function -->
-      <div class="fn-control | flex col no-gap">
-        <div class="fn-minmax | center flex small-gap">
-          <label>
-            <input
-              form="colorSortForm"
-              type="radio"
-              name="sortOrder"
-              value="min"
-              checked
-            />
-            <span class="toggle-label | pill-shape highlight-border">Min</span>
-          </label>
-          <label>
-            <input form="colorSortForm" type="radio" name="sortOrder" value="max" />
-            <span class="toggle-label | pill-shape highlight-border">Max</span>
-          </label>
-        </div>
-        <div class="fn-body | math-font flex">
-          <label>
-            <input
-              form="colorCalculateForm"
-              type="checkbox"
-              name="sortUseWholeImage"
-              checked
-            />
-            <span class="toggle-label | pill-shape highlight-border">
-              <output form="colorCalculateForm" name="sortMetricSymbolP"></output>(I)
-            </span>
-          </label>
-          +
-          <label>
-            <input
-              form="colorCalculateForm"
-              type="checkbox"
-              name="sortUseBestCluster"
-              checked
-            />
-            <span class="toggle-label | pill-shape highlight-border">
-              <output form="colorCalculateForm" name="sortMetricSymbolB"></output>(B)
-            </span>
-          </label>
-          ⋅
-          <div class="fn-fraction | flex col no-gap">
+        <!-- Sort Function -->
+        <div
+          class="fn-control | control-block | flex center-items center-content small-gap"
+        >
+          <div id="sort-metric-mount"></div>
+          <div class="fn-minmax | flex col center-items small-gap">
+            <label>
+              <input
+                form="colorSortForm"
+                type="radio"
+                name="sortOrder"
+                value="min"
+                checked
+              />
+              <span class="toggle-label | pill-shape highlight-border">Min</span>
+            </label>
+            <label>
+              <input form="colorSortForm" type="radio" name="sortOrder" value="max" />
+              <span class="toggle-label | pill-shape highlight-border">Max</span>
+            </label>
+          </div>
+          <div class="fn-body | math-font flex center-content center-items">
             <label>
               <input
                 form="colorCalculateForm"
                 type="checkbox"
-                name="sortUseClusterProportion"
+                name="sortUseWholeImage"
+                checked
               />
-              <span class="toggle-label | pill-shape highlight-border">%B</span>
+              <span class="toggle-label | pill-shape highlight-border">
+                <output form="colorCalculateForm" name="sortMetricSymbolP"></output>(I)
+              </span>
             </label>
+            +
             <label>
               <input
                 form="colorCalculateForm"
                 type="checkbox"
-                name="sortUseInvClusterProportion"
+                name="sortUseBestCluster"
                 checked
               />
-              <span class="toggle-label | pill-shape highlight-border">%B</span>
+              <span class="toggle-label | pill-shape highlight-border">
+                <output form="colorCalculateForm" name="sortMetricSymbolB"></output>(B)
+              </span>
             </label>
+            ⋅
+            <div class="fn-fraction | flex col no-gap">
+              <label>
+                <input
+                  form="colorCalculateForm"
+                  type="checkbox"
+                  name="sortUseClusterProportion"
+                />
+                <span class="toggle-label | pill-shape highlight-border">%B</span>
+              </label>
+              <label>
+                <input
+                  form="colorCalculateForm"
+                  type="checkbox"
+                  name="sortUseInvClusterProportion"
+                  checked
+                />
+                <span class="toggle-label | pill-shape highlight-border">%B</span>
+              </label>
+            </div>
           </div>
         </div>
-      </div>
-      <hr />
-      <div id="cls-title" class="emphasis center">Cluster Choice</div>
-      <div id="cls-metric-mount"></div>
-      <!-- Cluster Sort Function -->
-      <div id="cls-fn" class="fn-control | flex small-gap">
-        <div class="fn-minmax | flex col small-gap">
-          <label>
-            <input
-              form="colorCalculateForm"
-              type="radio"
-              name="clusterSortOrder"
-              value="min"
-            />
-            <span class="toggle-label | pill-shape highlight-border">Min</span>
-          </label>
-          <label>
-            <input
-              form="colorCalculateForm"
-              type="radio"
-              name="clusterSortOrder"
-              value="max"
-              checked
-            />
-            <span class="toggle-label | pill-shape highlight-border">Max</span>
-          </label>
-        </div>
-        <div class="fn-body | math-font flex">
-          <span class="toggle-label | pill-shape highlight-border">
-            <output form="colorCalculateForm" name="clusterMetricSymbol"></output>(K)
-          </span>
-          ⋅
-          <div class="fn-fraction | flex col no-gap">
+        <!-- Cluster Function -->
+        <div
+          id="cls-fn"
+          class="fn-control | control-block | flex center-items center-content small-gap"
+        >
+          <div id="cls-metric-mount"></div>
+          <div class="fn-minmax | flex col center-items small-gap">
             <label>
               <input
                 form="colorCalculateForm"
-                type="checkbox"
-                name="clusterUseClusterSize"
-                checked
+                type="radio"
+                name="clusterSortOrder"
+                value="min"
               />
-              <span class="toggle-label | pill-shape highlight-border">N(K)</span>
+              <span class="toggle-label | pill-shape highlight-border">Min</span>
             </label>
             <label>
               <input
                 form="colorCalculateForm"
-                type="checkbox"
-                name="clusterUseInvClusterSize"
+                type="radio"
+                name="clusterSortOrder"
+                value="max"
+                checked
               />
-              <span class="toggle-label | pill-shape highlight-border">N(K)</span>
+              <span class="toggle-label | pill-shape highlight-border">Max</span>
             </label>
           </div>
+          <div class="fn-body | math-font flex center-content center-items">
+            <span class="toggle-label | pill-shape highlight-border">
+              <output form="colorCalculateForm" name="clusterMetricSymbol"></output>(K)
+            </span>
+            ⋅
+            <div class="fn-fraction | flex col no-gap">
+              <label>
+                <input
+                  form="colorCalculateForm"
+                  type="checkbox"
+                  name="clusterUseClusterSize"
+                  checked
+                />
+                <span class="toggle-label | pill-shape highlight-border">N(K)</span>
+              </label>
+              <label>
+                <input
+                  form="colorCalculateForm"
+                  type="checkbox"
+                  name="clusterUseInvClusterSize"
+                />
+                <span class="toggle-label | pill-shape highlight-border">N(K)</span>
+              </label>
+            </div>
+          </div>
         </div>
       </div>
+      <div id="color-results" class="flex wrap"></div>
       <hr />
-      <div class="flex col small-gap">
-        <div class="emphasis center">Name Search</div>
+      <div id="name-search-controls" class="flex wrap center-items small-gap">
         <input
+          id="nameSearchInput"
           form="nameSearchForm"
           class="pill-shape highlight-border"
           type="text"
           autocomplete="off"
           name="input"
+          aria-label="Search By Name"
+          placeholder="Search By Name"
         />
-        <button form="nameSearchForm" type="button" name="random">Random Pokemon</button>
-        <button form="nameSearchForm" type="button" name="clear">Clear</button>
+        <button
+          title="Randomize"
+          class="icon-button | material-symbols-outlined"
+          form="nameSearchForm"
+          type="button"
+          name="random"
+        >
+          shuffle
+        </button>
+        <button
+          title="Clear"
+          class="icon-button | material-symbols-outlined"
+          form="nameSearchForm"
+          type="button"
+          name="clear"
+        >
+          clear
+        </button>
         <button form="nameSearchForm" type="button" name="all">Show All (slow)</button>
       </div>
-    </div>
-
-    <main class="section flow">
-      <div class="emphasis">By Color</div>
-      <div id="color-results" class="flex wrap"></div>
-      <hr />
-      <div class="emphasis">By Name</div>
       <div id="name-results" class="flex wrap"></div>
     </main>
 

+ 7 - 6
web/main.js

@@ -140,7 +140,8 @@ const pokemonDisplayLookup = Object.fromEntries(
         .replace(/-m$/, "")
         .replace(/-f$/, "-female")
         .replaceAll(/['%]+/g, "")
-        .replaceAll(/[:.\s]+/g, "-");
+        .replaceAll(/[:.\s]+/g, "-")
+        .replace(/-+$/, "");
     }
 
     const linkName = species.replace(/[':.]/, "").replace(" ", "-");
@@ -253,7 +254,6 @@ const rootStyle = document.querySelector(":root").style;
 const colorSearchResultsTarget = document.getElementById("color-results");
 const nameSearchResultsTarget = document.getElementById("name-results");
 const prevColorsSidebar = document.getElementById("prevColors");
-const clusterRankingTitle = document.getElementById("cls-title");
 const clusterMetricSection = document.getElementById("cls-metric-mount");
 const clusterFunctionSection = document.getElementById("cls-fn");
 
@@ -648,10 +648,11 @@ Array.from(colorCalculateForm.elements).forEach(el =>
   el.addEventListener("change", () => {
     const { sortUseBestCluster, sortUseClusterProportion, sortUseInvClusterProportion } =
       Object.fromEntries(new FormData(colorCalculateForm).entries());
-    clusterRankingTitle.dataset.faded =
-      clusterMetricSection.dataset.faded =
-      clusterFunctionSection.dataset.faded =
-        !(sortUseBestCluster || sortUseClusterProportion || sortUseInvClusterProportion);
+    clusterMetricSection.dataset.faded = clusterFunctionSection.dataset.faded = !(
+      sortUseBestCluster ||
+      sortUseClusterProportion ||
+      sortUseInvClusterProportion
+    );
     model.calculateObjective();
   })
 );

+ 75 - 40
web/styles.css

@@ -68,6 +68,18 @@ body {
   gap: var(--gap, 1rem);
 }
 
+.iflex {
+  display: inline-flex;
+}
+
+.center-content {
+  justify-content: center;
+}
+
+.center-items {
+  align-items: center;
+}
+
 .even {
   justify-content: space-between;
   align-items: stretch;
@@ -98,6 +110,10 @@ body {
   --gap: 0px;
 }
 
+.smaller-gap {
+  --gap: 0.125rem;
+}
+
 .small-gap {
   --gap: 0.5rem;
 }
@@ -111,8 +127,8 @@ body {
 }
 
 .section {
-  padding-block-start: var(--flow-space, 1rem);
-  padding-inline: var(--flow-space-inline, 1ch);
+  padding-block-start: 0.5rem;
+  padding-inline: 1ch;
 }
 
 /* Utility */
@@ -180,7 +196,7 @@ body {
   transition: accent-color 250ms, color 250ms, background-color 250ms;
 
   display: grid;
-  grid-template-columns: 22ch 1fr 12ch;
+  grid-template-columns: 1fr 12ch;
 }
 
 body > * + :not(:last-child) {
@@ -224,22 +240,6 @@ button.color-select:hover {
   margin-block-end: 0.5ch;
 }
 
-.color-inputs input[type="text"] {
-  min-width: 0px;
-}
-
-.color-inputs input[type="color"] {
-  flex: 0 0 2rem;
-}
-
-.color-inputs input[type="radio"] {
-  display: none;
-}
-
-input[name="resultsToDisplay"] {
-  width: 18ch;
-}
-
 #cls-title,
 #cls-fn,
 #cls-metric-mount {
@@ -247,15 +247,9 @@ input[name="resultsToDisplay"] {
 }
 
 #cls-fn {
-  justify-content: center;
-  align-items: center;
   margin: 0;
 }
 
-#cls-fn .fn-minmax {
-  align-items: center;
-}
-
 [data-faded="true"] {
   opacity: 25%;
 }
@@ -266,7 +260,8 @@ input[name="resultsToDisplay"] {
 }
 
 .toggle-label {
-  padding: 0 0.625ch 0.125rem;
+  white-space: nowrap;
+  padding: 0 0.625ch;
   opacity: 50%;
   transition: opacity 200ms, color 200ms, border-color 200ms, background-color 200ms;
 }
@@ -291,7 +286,6 @@ input[name="resultsToDisplay"] {
 
 .pkmn-tile .pkmn-title {
   justify-content: space-between;
-  align-items: center;
 }
 
 .pkmn-tile .pkmn-info-icon {
@@ -316,13 +310,9 @@ input[name="resultsToDisplay"] {
 
 .pkmn-tile .pkmn-info-main {
   flex: 1;
-  --gap: 0.125rem;
 }
 
 .pkmn-tile .cluster-buttons {
-  --gap: 0.125rem;
-  justify-content: center;
-
   /* but here we put the block-start padding back to
      fix the vertical centering of the cluster buttons */
   margin-block-start: var(--tile-block-padding);
@@ -335,9 +325,6 @@ input[name="resultsToDisplay"] {
 
 .pkmn-tile a {
   height: 64px;
-  display: inline-flex;
-  justify-content: center;
-  align-items: center;
 }
 
 .pkmn-tile img {
@@ -347,7 +334,6 @@ input[name="resultsToDisplay"] {
 .pkmn-tile .pkmn-score-row {
   flex-wrap: wrap;
   justify-content: space-around;
-  align-items: center;
 }
 
 .pkmn-tile button {
@@ -428,17 +414,52 @@ input[name="resultsToDisplay"] {
   }
 }
 
+/* Sort Controls */
+
+.icon-button {
+  width: 2rem;
+  height: 2rem;
+}
+
+.control-block {
+  max-width: fit-content;
+  padding-block: 0.25rem;
+  background-color: var(--shadow);
+  border-radius: 8px;
+}
+
+#sort-inputs input[type="text"] {
+  min-width: 0px;
+  max-width: 12ch;
+  padding-block: 0.625rem;
+}
+
+#sort-inputs input[type="color"] {
+  flex: 0 0 2rem;
+  height: 2rem;
+  align-self: center;
+}
+
+#name-search-controls {
+  align-items: stretch;
+}
+
+#name-search-controls button[name="all"] {
+  padding-inline: 1ch;
+}
+
 /* Sort Function Controls */
 
+.fn-control.control-block {
+  padding-inline: 1ch;
+}
+
 .fn-control .fn-minmax label span {
   padding: 0.125rem 0.75ch;
 }
 
 .fn-control .fn-body {
   --gap: 0.25ch;
-  margin-block: 0.5rem;
-  justify-content: center;
-  align-items: center;
 }
 
 .fn-control :is(input[type="checkbox"], input[type="radio"]) {
@@ -472,6 +493,20 @@ input[name="resultsToDisplay"] {
 }
 
 .metric-fields select {
-  width: 100%;
-  padding: 0.25rem 1ch;
+  width: 18ch;
+  align-self: stretch;
+  padding-inline: 1ch;
+}
+
+/* Other Controls */
+
+input[name="resultsToDisplay"] {
+  max-width: 16ch;
+  margin-inline: 1ch;
+}
+
+#filter-toggles {
+  align-items: stretch;
+  --gap: 0.25rem;
+  padding-inline-end: 1ch;
 }