123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- const getSprite = (() => {
- const stripForm = [
- "flabebe",
- "floette",
- "florges",
- "vivillon",
- "basculin",
- "furfrou",
- "magearna",
- "alcremie",
- ];
- return (pokemon) => {
- pokemon = pokemon
- .replace("-alola", "-alolan")
- .replace("-galar", "-galarian")
- .replace("-phony", "") // sinistea and polteageist
- .replace("darmanitan-galarian", "darmanitan-galarian-standard");
- if (stripForm.find((s) => pokemon.includes(s))) {
- pokemon = pokemon.replace(/-.*$/, "");
- }
- return `https://img.pokemondb.net/sprites/sword-shield/icon/${pokemon}.png`;
- };
- })();
- const renderStatPair = (lbl, val, valueClass = "value") => `
- <span class="pkmn-tile_label">${lbl}</span>
- <span class="pkmn-tile_${valueClass}">${val}</span>
- `;
- const renderStatRow = (lines) => `
- <div class="pkmn-tile_row">
- ${lines.join("\n")}
- </div>
- `;
- const renderPokemonTileCluster = (area, { mu, nu, proportion }, scores) => {
- const textColor = getContrastingTextColor(mu.hex);
- return `
- <div
- class="pkmn-tile_stats"
- style="grid-area: ${area}; color: ${textColor}; background-color: ${
- mu.hex
- };"
- >
- <div class="pkmn-tile_row" style="justify-content: center;">
- ${(100 * proportion).toFixed(2)}% ${mu.hex}
- </div>
- <div class="toggle-on">
- ${[
- ["α =", scores.alpha.toFixed(3)],
- ["σ =", scores.sigma.toFixed(3)],
- ["Θ =", scores.bigTheta.toFixed(3)],
- ["θ =", scores.theta.toFixed(3) + "°"],
- ["ϕ =", scores.phi.toFixed(3) + "°"],
- ["δ =", scores.delta.toFixed(3)],
- ["M =", scores.manhattan.toFixed(3)],
- ["Ч =", scores.ch.toFixed(3)],
- ["ℓ =", scores.lightnessDiff.toFixed(3)],
- ]
- .map(([lbl, val]) => renderStatPair(lbl, val))
- .map((ls) => renderStatRow([ls]))
- .join("\n")}
- <hr style="width: 80%; color: ${textColor}"/>
- ${[
- ["μ =", `(${mu.vector[0].toFixed(2)},`],
- ["", mu.vector[1].toFixed(2) + ","],
- ["", mu.vector[2].toFixed(2) + ")"],
- ["ν =", `(${nu[0].toFixed(2)},`],
- ["", nu[1].toFixed(2) + ","],
- ["", nu[2].toFixed(2) + ")"],
- ["I =", scores.inertia.toFixed(2)],
- ["V =", scores.variance.toFixed(2)],
- ["Φ =", scores.muNuAngle.toFixed(2) + "°"],
- ["N =", scores.size],
- ["L =", scores.lightness.toFixed(2)],
- ["C =", scores.chroma.toFixed(2)],
- ["β = ", scores.importance.toFixed(2)],
- ]
- .map(([lbl, val]) => renderStatPair(lbl, val))
- .map((ls) => renderStatRow([ls]))
- .join("\n")}
- </div>
- </div>
- `;
- };
- const clusterToggles = {};
- const renderPokemonTile = (
- kind,
- name,
- { total: { mu, nu, size }, clusters },
- scores,
- bestClusterIndex
- ) => {
- const clusterToggleId = `${name}-${kind}-pkmn-expand-toggle`;
- const textColor = getContrastingTextColor(mu.hex);
- return `
- <div class="pkmn-tile toggle-box">
- <input
- autocomplete="off"
- type="checkbox"
- ${clusterToggles?.[clusterToggleId] ? "checked" : ""}
- id="${clusterToggleId}"
- onchange="clusterToggles['${clusterToggleId}'] = event.target.checked"
- class="toggle-button"
- role="button"
- >
- <label for="${clusterToggleId}" style="grid-area: togg; text-align: center; align-self: start;">
- <div class="toggle-off">►</div>
- <div class="toggle-on">▼</div>
- </label>
- <img style="grid-area: icon" src="${getSprite(name)}" />
- <span style="grid-area: name">
- ${name
- .split("-")
- .map((part) => part.charAt(0).toUpperCase() + part.substr(1))
- .join(" ")}
- </span>
- <div
- class="pkmn-tile_stats"
- style="grid-area: totl; color: ${textColor}; background-color: ${
- mu.hex
- };"
- >
- <div class="pkmn-tile_row" style="justify-content: center;">
- ${mu.hex}
- </div>
- <div class="toggle-on">
- ${renderStatRow(
- [
- ["α =", scores.total.alpha.toFixed(3)],
- ["σ =", scores.total.sigma.toFixed(3)],
- ["Θ =", scores.total.bigTheta.toFixed(3)],
- ["θ =", scores.total.theta.toFixed(3) + "°"],
- ["ϕ =", scores.total.phi.toFixed(3) + "°"],
- ].map(([lbl, val]) => renderStatPair(lbl, val))
- )}
- ${renderStatRow(
- [
- ["δ =", scores.total.delta.toFixed(3)],
- ["M =", scores.total.manhattan.toFixed(3)],
- ["Ч =", scores.total.ch.toFixed(3)],
- ["ℓ =", scores.total.lightnessDiff.toFixed(3)],
- ].map(([lbl, val]) => renderStatPair(lbl, val))
- )}
- <hr style="width: 80%; color: ${textColor}"/>
- ${renderStatRow(
- [
- [
- "μ =",
- `(${mu.vector.map((c) => c.toFixed(2)).join(", ")})`,
- "vector",
- ],
- ["ν =", `(${nu.map((c) => c.toFixed(2)).join(", ")})`, "vector"],
- ].map(([lbl, val, cls]) => renderStatPair(lbl, val, cls))
- )}
- ${renderStatRow(
- [
- ["I =", scores.total.inertia.toFixed(2)],
- ["V =", scores.total.variance.toFixed(2)],
- ["Φ =", scores.total.muNuAngle.toFixed(2) + "°"],
- ["N =", size],
- ["L =", scores.total.lightness.toFixed(2)],
- ["C =", scores.total.chroma.toFixed(2)],
- ].map(([lbl, val, cls]) => renderStatPair(lbl, val, cls))
- )}
- ${
- bestClusterIndex < 0
- ? ""
- : `<hr style="width: 80%; color: ${textColor}"/>`
- }
- ${renderStatRow([
- `<span class="pkmn-tile_indicator">${
- bestClusterIndex === 0 ? "▼" : ""
- }</span>`,
- `<span class="pkmn-tile_indicator">${
- bestClusterIndex === 1 ? "▼" : ""
- }</span>`,
- `<span class="pkmn-tile_indicator">${
- bestClusterIndex === 2 ? "▼" : ""
- }</span>`,
- `<span class="pkmn-tile_indicator">${
- bestClusterIndex === 3 ? "▼" : ""
- }</span>`,
- ])}
- </div>
- </div>
- ${clusters
- .map((c, i) =>
- renderPokemonTileCluster(`cls${i + 1}`, c, scores.clusters[i])
- )
- .join("\n")}
- </div>
- `;
- };
|