npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fish-pool-webgl

v1.0.0

Published

A dependency-free interactive WebGL2 koi pond for the web.

Downloads

202

Readme

Fish Pool

A dependency-free interactive koi pond for the web. The water simulation, procedural pond shading, and koi rendering run directly in WebGL2; fish behavior and pointer hit-testing run in TypeScript.

The package does not depend on React, Next.js, Three.js, or a runtime framework. A lightweight Canvas 2D renderer is included as a fallback.

Install

npm install fish-pool-webgl

Quick start

Give the mount element an explicit size, then create the pond:

<div id="pond" style="width: 720px; max-width: 100%; aspect-ratio: 3 / 2"></div>
import { FishPool } from "fish-pool-webgl";

const pond = new FishPool("#pond", {
  fishCount: 5,
  seed: 42069,
});

pond.addRipple(360, 240, { radius: 36, strength: 1.2 });

// When the view is permanently removed:
pond.destroy();

You can also provide an existing canvas:

const canvas = document.querySelector<HTMLCanvasElement>("canvas")!;
const pond = new FishPool(canvas);

Browser script

The package also ships an IIFE build. It exposes FishPoolWebGL on window:

<script src="https://unpkg.com/fish-pool-webgl/dist/fish-pool.min.js"></script>
<script>
  const pond = new FishPoolWebGL.FishPool("#pond", { fishCount: 4 });
</script>

API

new FishPool(target, options?)

target can be a CSS selector, an HTMLElement, or an existing HTMLCanvasElement.

| Option | Type | Default | Description | | --- | --- | --- | --- | | fishCount | number | 4 | Number of original koi, clamped to 1–4. | | pixelRatio | number | 2 | Maximum device-pixel ratio. | | interactive | boolean | true | Enables tap, click, and drag interaction. | | paused | boolean | false | Creates the pond without starting its loop. | | seed | number | 23847 | Repeatable fish placement and colors. | | ariaLabel | string | descriptive label | Accessible canvas label. | | onFallback | (reason: string) => void | — | Reports why Canvas 2D was selected. |

Methods

  • start() and stop() control the animation loop.
  • addRipple(x, y, options?) injects a water impulse in CSS-pixel coordinates.
  • scareAt(x, y) startles a fish under the given point and returns whether one was hit.
  • setFishCount(count) replaces the school with 1–8 seeded fish.
  • resize() manually refreshes sizing. A ResizeObserver already calls it automatically.
  • getStats() returns renderer, size, density, fish count, and running state.
  • destroy() releases observers, listeners, WebGL resources, and the owned canvas.

Local demo

npm install
npm run dev

Open http://localhost:4173.

For a static demo build:

npm run build:demo

Package build

npm run check
npm run build
npm pack --dry-run

Build outputs:

  • dist/index.js — ESM
  • dist/index.cjs — CommonJS
  • dist/fish-pool.min.js — browser IIFE
  • dist/*.d.ts — TypeScript declarations
  • Source maps for the JavaScript builds

prepublishOnly runs type checking and the package build automatically before npm publish.

How it works

  • Twelve render targets separate ripple state, water surface, caustics, floor, relief, plants, fish, fish shadows, blur passes, and the final scene.
  • The original two-band wave equation accepts drops, splashes, and directional body pushes with separate damping values.
  • A 2px water grid refracts caustics across the floor and stones before the scene-composite and film-grain passes.
  • Every koi is a dynamic 64 × 9 mesh driven by a 22-point spine and 160-point movement trail.
  • The fish shader supplies staggered scales, four paired ray fins, a dorsal fin, a forked translucent tail, organic markings, gill shading, eye highlights, and water-driven specular light.
  • The behavior layer preserves goal selection, body-segment avoidance, edge steering, fear propagation, fin folding, tail wakes, pectoral ripples, and centerline hit testing.
  • ResizeObserver, IntersectionObserver, and the Page Visibility API limit unnecessary work.

The visual and interaction reference is the public koi demo on shwn.design. That demo does not load a reusable fish image, video, or 3D model—the koi are generated procedurally—so this package reconstructs the same shader techniques as maintainable source instead of hotlinking an asset or embedding the site's minified application bundle.

For an auditable comparison, the repository also includes:

  • reference/original-pond.compiled.js — the formatted client module exactly as extracted from the current public bundle.
  • reference/original-pond-analysis.md — readable identifier, render-pass, interaction, and network mappings.
  • scripts/extract-reference.mjs and scripts/generate-original-engine.mjs — reproducible extraction and framework-removal scripts.

Browser support

Modern browsers with WebGL2 receive the full renderer. Browsers without WebGL2 or floating-point color-buffer support automatically use the Canvas 2D fallback.

License

MIT