feat: distinguish fish by visual family
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
---
|
||||
const { name, size = 92 } = Astro.props as { name: string; size?: number };
|
||||
const variant = [...name].reduce((sum, char) => sum + (char.codePointAt(0) ?? 0), 0) % 3;
|
||||
import { fishVisualFamily, type FishVisualFamily } from "../lib/fish-visuals";
|
||||
const { name, size = 92, family: familyOverride } = Astro.props as { name: string; size?: number; family?: FishVisualFamily };
|
||||
const family = familyOverride ?? fishVisualFamily(name);
|
||||
---
|
||||
<svg class="fish-silhouette" width={size} height={Math.round(size * .48)} viewBox="0 0 120 58" aria-hidden="true">
|
||||
{variant === 0 && <><path d="M22 29C38 7 78 8 101 29 78 50 38 51 22 29Z"/><path d="m25 29-22-18v36Z"/><path d="M55 14 69 2l8 15M57 44l15 11 8-16"/><circle cx="91" cy="25" r="2.4" class="fish-eye"/></>}
|
||||
{variant === 1 && <><path d="M19 30C39 14 80 13 104 29 80 45 39 47 19 30Z"/><path d="M22 30 3 17v28Z"/><path d="m48 17 11-14 13 13M47 44l12 11 13-12"/><path d="M101 29h15"/><circle cx="94" cy="25" r="2.4" class="fish-eye"/></>}
|
||||
{variant === 2 && <><path d="M20 30C34 3 79 4 103 29 79 54 34 55 20 30Z"/><path d="M23 30 2 8v44Z"/><path d="m52 10 8-9 14 10M52 49l9 8 14-10"/><circle cx="92" cy="24" r="2.4" class="fish-eye"/></>}
|
||||
<svg class="fish-silhouette" data-family={family} width={size} height={Math.round(size * .48)} viewBox="0 0 120 58" aria-hidden="true">
|
||||
{family === "pike" && <><path d="M19 30C35 16 70 15 94 24l22 1-7 9-15 1C70 45 35 44 19 30Z"/><path d="M22 30 2 15v30Z"/><path d="m49 18 12-14 15 12M49 42l13 12 15-13"/><circle cx="105" cy="28" r="2.2" class="fish-eye"/></>}
|
||||
{family === "salmonid" && <><path d="M20 30C39 12 79 12 103 28 81 46 40 47 20 30Z"/><path d="M23 30 3 13v34Z"/><path d="m50 16 11-13 15 12M51 43l11 12 14-12"/><path d="m80 17 7-7 5 9"/><circle cx="94" cy="25" r="2.2" class="fish-eye"/></>}
|
||||
{family === "cyprinid" && <><path d="M22 29C38 5 77 5 101 29 77 53 38 53 22 29Z"/><path d="M25 29 3 9v40Z"/><path d="M52 10 68 1l12 13M53 48l16 9 12-14"/><circle cx="91" cy="24" r="2.2" class="fish-eye"/></>}
|
||||
{family === "perch" && <><path d="M20 31C39 13 79 14 103 29 80 47 39 49 20 31Z"/><path d="M23 31 3 16v31Z"/><path d="m42 18 7-15 7 13 8-13 8 14 8-10 5 13M52 45l13 11 15-13"/><circle cx="94" cy="25" r="2.2" class="fish-eye"/></>}
|
||||
{family === "catfish" && <><path d="M17 31C37 17 78 17 104 29 81 45 38 47 17 31Z"/><path d="M21 31 2 18v28Z"/><path d="M47 20 65 7l13 13M48 43l17 11 14-13"/><path class="fish-detail" d="M99 31c9 1 13 5 18 10M99 33c8 4 9 9 12 15"/><circle cx="94" cy="27" r="2.2" class="fish-eye"/></>}
|
||||
{family === "eel" && <><path d="M5 35c20-29 42 14 69-10 17-15 33-7 42 1-20-4-24 17-43 17C43 43 30 22 5 45Z"/><path d="m105 24 12-9-2 13"/><circle cx="106" cy="26" r="1.8" class="fish-eye"/></>}
|
||||
{family === "flatfish" && <><path d="M18 31C37 4 80 6 108 29 80 52 37 54 18 31Z"/><path d="M21 31 3 17v29Z"/><path d="m53 12 13-10 13 11M54 49l13 8 13-10"/><circle cx="91" cy="23" r="2.1" class="fish-eye"/><circle cx="97" cy="26" r="1.7" class="fish-eye"/></>}
|
||||
{family === "marine" && <><path d="M18 30C40 14 78 15 101 28l16-5-6 10 5 8-16-5C76 45 39 45 18 30Z"/><path d="M22 30 2 12v36Z"/><path d="m54 17 13-13 12 13M54 43l13 11 12-12"/><circle cx="94" cy="26" r="2.1" class="fish-eye"/></>}
|
||||
{family === "generic" && <><path d="M21 29C38 9 78 10 103 29 78 48 38 49 21 29Z"/><path d="m24 29-21-17v35Z"/><path d="M54 15 68 3l10 14M55 44l14 11 10-15"/><circle cx="93" cy="25" r="2.2" class="fish-eye"/></>}
|
||||
</svg>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
export type FishVisualFamily = "pike" | "salmonid" | "cyprinid" | "perch" | "catfish" | "eel" | "flatfish" | "marine" | "generic";
|
||||
|
||||
const FAMILY_TERMS: Array<[FishVisualFamily, RegExp]> = [
|
||||
["pike", /щук|судак|pike|pickerel|zander|hecht/i],
|
||||
["salmonid", /форел|лосос|сёмг|голец|таймен|хариус|trout|salmon|char|grayling|forelle|lachs|saibling/i],
|
||||
["cyprinid", /карп|карась|лещ|плотв|линь|язь|жерех|голав|усач|амур|толстолоб|carp|bream|roach|tench|barbel|karpfen|brasse/i],
|
||||
["perch", /окун|ёрш|perch|ruff|barsch/i],
|
||||
["catfish", /сом|catfish|wels/i],
|
||||
["eel", /угор|миног|eel|lamprey|aal/i],
|
||||
["flatfish", /камбал|палтус|скат|flounder|halibut|ray|rochen/i],
|
||||
["marine", /сельд|треск|скумбр|тунец|акул|сардин|herring|cod|mackerel|tuna|shark|hering|kabeljau/i],
|
||||
];
|
||||
|
||||
export function fishVisualFamily(name: string): FishVisualFamily {
|
||||
return FAMILY_TERMS.find(([, pattern]) => pattern.test(name))?.[0] ?? "generic";
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
.fish-silhouette{fill:currentColor;color:#315f63;pointer-events:none}.fish-silhouette .fish-eye{fill:var(--paper)}.spot-main{position:relative}.spot-main>.fish-silhouette{position:absolute;right:2px;top:38px;opacity:.075}.catalog-grid>a{position:relative;overflow:hidden}.catalog-grid>a>.fish-silhouette{position:absolute;right:34px;bottom:-3px;opacity:.07;transform:rotate(-4deg)}@media(max-width:720px){.spot-main>.fish-silhouette{width:68px;right:0;opacity:.055}}
|
||||
.fish-silhouette{fill:currentColor;color:#315f63;pointer-events:none}.fish-silhouette .fish-eye{fill:var(--paper)}.fish-silhouette .fish-detail{fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}.spot-main{position:relative}.spot-main>.fish-silhouette{position:absolute;right:2px;top:38px;opacity:.075}.catalog-grid>a{position:relative;overflow:hidden}.catalog-grid>a>.fish-silhouette{position:absolute;right:20px;bottom:12px;opacity:.12;transform:rotate(-4deg);transition:opacity var(--motion-base) var(--ease-out),transform var(--motion-base) var(--ease-out)}.catalog-grid>a:hover>.fish-silhouette{opacity:.2;transform:rotate(-2deg) translateX(-2px)}@media(max-width:720px){.spot-main>.fish-silhouette{width:68px;right:0;opacity:.055}}
|
||||
|
||||
Reference in New Issue
Block a user