Skip to content
SlashClone

Seeded image crops

@slashclone/seeded-image-crops

Give every card, profile, and page header its own cover from just a few hero images: each item gets a stable crop (a hand-picked framing, nudged per item), the same every time it loads. One small file shared by every card, so a page of cards downloads the images once. Includes a checker that previews how evenly your items spread across the crops.

SkillContentv0.1.0 (latest)Tested
Activity
New: be the first to try it
  1. 1import { cropFor, cropStyle } from "./seeded-crop.ts";
  2. 2
  3. 3/**
  4. 4 * A decorative cover: the light image in the light theme and the dark one in dark, with
  5. 5 * the same crop in both. Lazy by default; pass `priority` above the fold.
  6. 6 * Assumes Tailwind with a `dark:` variant; swap the classes for your own CSS if not.
  7. 7 */
  8. 8export function SeededCover({
  9. 9 seed,
  10. 10 light,
  11. 11 dark,
  12. 12 priority = false,
  13. 13}: {
  14. 14 seed: string;
  15. 15 light: string;
  16. 16 dark?: string;
  17. 17 priority?: boolean;
  18. 18}) {
  19. 19 const style = cropStyle(cropFor(seed));
  20. 20 const img = "absolute inset-0 block h-full w-full object-cover";
  21. 21 return (
  22. 22 <div aria-hidden="true" className="relative h-full w-full overflow-hidden">
  23. 23 <img
  24. 24 src={light}
  25. 25 alt=""
  26. 26 loading={priority ? "eager" : "lazy"}
  27. 27 decoding="async"
  28. 28 className={dark ? `${img} dark:hidden` : img}
  29. 29 style={style}
  30. 30 />
  31. 31 {dark ? (
  32. 32 <img
  33. 33 src={dark}
  34. 34 alt=""
  35. 35 loading={priority ? "eager" : "lazy"}
  36. 36 decoding="async"
  37. 37 className={`${img} hidden dark:block`}
  38. 38 style={style}
  39. 39 />
  40. 40 ) : null}
  41. 41 </div>
  42. 42 );