Browse Source

First pass at display logic

Kirk Trombley 2 years ago
parent
commit
0b89fb6ec1
3 changed files with 118 additions and 3 deletions
  1. 8 2
      index.html
  2. 93 1
      script.js
  3. 17 0
      styles.css

+ 8 - 2
index.html

@@ -132,9 +132,15 @@
     </template>
 
     <template id="pkmn-template">
-      <div>
+      <div class="pkmn-tile">
         <img bind-to="image" />
         <div bind-to="name"></div>
+        <div bind-to="value"></div>
+        <button bind-to="totalBtn" class="color-select"></button>
+        <button bind-to="cls1Btn" class="color-select"></button>
+        <button bind-to="cls2Btn" class="color-select"></button>
+        <button bind-to="cls3Btn" class="color-select"></button>
+        <button bind-to="cls4Btn" class="color-select"></button>
         <!-- TODO the actual data -->
       </div>
     </template>
@@ -182,7 +188,7 @@
 
     <main class="section">
       <div id="color-results-label">By Color</div>
-      <div id="color-results"></div>
+      <div id="color-results" class="flow"></div>
       <div id="name-results-label">By Name</div>
       <div id="name-results"></div>
     </main>

+ 93 - 1
script.js

@@ -38,7 +38,7 @@ const sortIgnoresCluster = U.obs(() =>
     sortUseClusterSize.value,
     sortUseInverseClusterSize.value,
   ].every((v) => !v)
-  );
+);
 
 // ---- Color Controls ----
 const randomizeTargetColor = () => {
@@ -355,4 +355,96 @@ const colorSearchResults = U.obs(() =>
   sortedResults.value.slice(0, resultsToDisplay.value)
 );
 
+// ---- Pokemon Display ----
+const getSpriteName = (() => {
+  const stripForm = [
+    "flabebe",
+    "floette",
+    "florges",
+    "vivillon",
+    "basculin",
+    "furfrou",
+    "magearna",
+    "alcremie",
+  ];
+  return (pokemon) => {
+    pokemon = pokemon
+      .replace("-alola", "-alolan")
+      .replace("-galar", "-galarian")
+      .replace("-hisui", "-hisuian")
+      .replace("-paldea", "-paldean")
+      .replace("-paldeanfire", "-paldean-fire") // tauros
+      .replace("-paldeanwater", "-paldean-water") // tauros
+      .replace("-phony", "") // sinistea and polteageist
+      .replace("darmanitan-galarian", "darmanitan-galarian-standard");
+    if (stripForm.find((s) => pokemon.includes(s))) {
+      pokemon = pokemon.replace(/-.*$/, "");
+    }
+    return pokemon;
+  };
+})();
+
+const displayPokemon = (pkmnName, target) => {
+  const spriteName = getSpriteName(pkmnName);
+  const formattedName = pkmnName
+    .split("-")
+    .map((part) => part.charAt(0).toUpperCase() + part.substr(1))
+    .join(" ");
+
+  // can be non-reactive since we'll be dicthing the whole list each time
+  const { total, clusters } = currentScores.value[pkmnName][colorSpace.value];
+  const { rankingValues, bestClusterIndices } = currentResults.value;
+  const rankingValue = rankingValues[pkmnName][colorSpace.value];
+  const bestCluster = bestClusterIndices[pkmnName][colorSpace.value];
+
+  U.template(
+    "pkmn-template",
+    ({ image, name, value, totalBtn, cls1Btn, cls2Btn, cls3Btn, cls4Btn }) => {
+      const imageErrHandler = () => {
+        image.removeEventListener("error", imageErrHandler);
+        image.src = `https://img.pokemondb.net/sprites/sword-shield/icon/${spriteName}.png`;
+      };
+      image.addEventListener("error", imageErrHandler);
+      image.src = `https://img.pokemondb.net/sprites/scarlet-violet/icon/${spriteName}.png`;
+
+      name.innerText = image.alt = formattedName;
+      value.innerText = rankingValue.toFixed(2);
+
+      totalBtn.innerText = total.muHex;
+      totalBtn.style = getColorButtonStyle(total.muHex);
+      totalBtn.addEventListener("click", () => {
+        targetColor.value = total.muHex;
+      });
+      totalBtn.dataset.best =
+        sortUseWholeImage.value ||
+        sortUseTotalSize.value ||
+        sortUseInverseTotalSize.value;
+
+      [cls1Btn, cls2Btn, cls3Btn, cls4Btn].forEach((button, index) => {
+        if (index < clusters.length) {
+          const { muHex } = clusters[index];
+          button.innerText = muHex;
+          button.style = getColorButtonStyle(muHex);
+          button.addEventListener("click", () => {
+            targetColor.value = muHex;
+          });
+          button.dataset.best = !sortIgnoresCluster.value && index === bestCluster;
+        } else {
+          button.remove();
+        }
+      });
+
+      return target;
+    }
+  );
+};
+
+const colorSearchResultsTarget = document.getElementById("color-results");
+colorSearchResults.subscribe(() => {
+  colorSearchResultsTarget.innerHTML = "";
+  colorSearchResults.value.forEach((name) =>
+    displayPokemon(name, colorSearchResultsTarget)
+  );
+});
+
 randomizeTargetColor();

+ 17 - 0
styles.css

@@ -179,3 +179,20 @@ hr {
 [data-faded="true"] {
   opacity: 25%;
 }
+
+.pkmn-tile img {
+  height: 64px;
+}
+
+.pkmn-tile button {
+  font-size: 0.85rem;
+  font-weight: 600;
+  padding-inline: 1ch; /* TODO remove this after using grid for layout*/
+}
+
+.pkmn-tile button[data-best="true"]::before {
+  content: "▸";
+  display: inline-block;
+  width: 1ch;
+  margin-inline: 0.25ch;
+}