@ljhaesler/microbiome
v1.0.6
Published
Microbiome module for the 'Spamalaxy' project
Readme
@ljhaesler/microbiome
A PixiJS v8 visualization for the Spamalaxy project. Renders clusters of soft, gooey "metaball" blobs that orbit the screen, drift apart under repulsion, and respond to click-and-drag.
Installation
npm install @ljhaesler/microbiomeQuick start
import { Microbiome, ColorHandler } from "@ljhaesler/microbiome";
// 1. Set up colours: map association names to one or more colours each.
const colorHandler = new ColorHandler();
colorHandler.setOptions({
anger: "ff5500, ffaa00",
jealousy: "00aaff, 0055ff, 00ff00",
});
// 2. Create the app and initialise the Pixi canvas.
const microbiome = new Microbiome(colorHandler);
await microbiome.quickInit();
// 3. Create MetaballSets
const angerSet1 = microbiome.addMetaballSet("anger");
const angerSet2 = microbiome.addMetaballSet("anger");
const jealousySet = microbiome.addMetaballSet("jealousy");
// 4. Populate MetaballSet with Metaballs
// the set is populated with as many metaballs as there are colours
angerSet1.addMetaballs({ metaballRadius: 120, metaballRatio: 1.2 });
angerSet2.addMetaballs({ metaballRadius: 200, metaballRatio: 0.8 });
jealousySet.addMetaballs({ metaballRadius: 150, metaballRatio: 1.1 });
// will not work (make a new set instead):
// jealousySet.addMetaballs({ metaballRadius: 150, metaballRatio: 1.1 });
// 5. Drive the animation loop.
microbiome.ticker.add((ticker) => {
microbiome.tick(ticker.lastTime * 0.001, /* orbitalSpeed */ 0.5);
});API
Microbiome
Extends pixi.js Application. The entry point: owns the renderer/stage, holds the metaball sets, and advances the animation each frame.
new Microbiome(colorHandler)
| Parameter | Type | Description |
| -------------- | -------------- | -------------------------------------------- |
| colorHandler | ColorHandler | Provides the colour set for each association |
colorHandler is required. Does not initialise the renderer — call quickInit() first.
await microbiome.quickInit()
Initialises the Pixi application (black background, full-window, antialiased), appends the canvas to document.body, and installs the metaball fusion filter on the stage. Must be called before adding content.
For different init options, call the inherited
Application.init()yourself, then apply the filter and mount the canvas manually.
microbiome.addMetaballSet(association)
Creates a MetaballSet, adds it to the stage, and returns it. Its colours are resolved from the ColorHandler.
| Parameter | Type | Description |
| ------------- | -------- | -------------------------------------- |
| association | string | A key registered in the ColorHandler |
microbiome.metaballSets
Getter. Returns all sets created via addMetaballSet, in creation order.
microbiome.tick(t, orbitalSpeed)
Advances one animation frame. Call this inside your ticker.
| Parameter | Type | Description |
| -------------- | -------- | ----------------------------------------------- |
| t | number | Elapsed time, drives per-blob skew wobble |
| orbitalSpeed | number | Angular speed at which unclicked clusters orbit |
Each frame, every unclicked cluster orbits the screen centre while updateChildren() applies the intra-cluster physics and each blob's skew wobbles from t.
MetaballSet
Extends pixi.js Container. A single cluster of metaballs sharing one colour association. Obtain one via Microbiome.addMetaballSet rather than constructing it directly. The cluster lives in a fixed 128×128 coordinate space that governs centre attraction.
metaballSet.addMetaballs({ metaballRadius, metaballRatio })
Populates the cluster with one Metaball per colour in the association, each smaller than the last, so an association renders as a few nested blobs of graduated size.
| Property | Type | Description |
| ---------------- | -------- | ------------------------------------------------------------------------------------------ |
| metaballRadius | number | Base radius for the first blob; also used as the physics minDistance |
| metaballRatio | number | How quickly blobs shrink: blob i has radius metaballRadius / (metaballRatio * (i + 1)) |
Each blob gets a radial-gradient texture from the association's colour and its own drag listeners.
metaballSet.updateChildren()
Runs one physics step: pairs of blobs closer than minDistance repel, then integration applies centre attraction, friction, position updates, and edge bounces. Called for you by Microbiome.tick.
Properties
| Property | Type | Description |
| --------------- | ---------------- | ------------------------------------------------ |
| association | string | The colour association key for this cluster |
| colors | Color[] | The colour set resolved from the ColorHandler |
| renderer | Renderer | The Pixi renderer, used to bake blob textures |
| containerSize | number | The cluster's coordinate space (128) |
| fillGradients | FillGradient[] | One radial gradient per colour |
| rotationSpeed | number | Per-cluster spin applied during orbit |
| clicked | boolean | true while pressed; pauses the cluster's orbit |
Metaball
Extends pixi.js Sprite. A single blob, created by MetaballSet.addMetaballs. Spawns at a random point inside its cluster and carries the per-blob animation state: velocity (vx, vy), skew wobble (skewSpeed, skewPhaseX, skewPhaseY), and rotationSpeed.
metaball.addEventListeners()
Enables click-and-drag. While pressed, the blob follows the pointer and its clicked flag excludes it from the physics until released. Called for you by MetaballSet.addMetaballs.
ColorHandler
Extends Map. Maps association names to arrays of pixi.js Color objects. Microbiome uses it to resolve the colours for each cluster.
Re-exported from the
@ljhaesler/color-handlerpackage, which@ljhaesler/microbiomedepends on. You can import it directly from either package.
| Method | Description |
| ----------------------------- | ------------------------------------------------------------------------------ |
| setOptions(object) | Register associations and colours together ({ name: "c1, c2", … } or arrays) |
| setAssociations(str\|array) | Set the association names (comma-separated string or array) |
| setColors(str\|array) | Set the colour sets ("a,b / c,d" string, or array of arrays) |
| getColorSet(association) | Return the Color[] for an association |
| reorder(str\|array) | Reorder the associations; length must match the number of colour sets |
| associations | Getter. The current list of association names |
See the @ljhaesler/color-handler package for full details.
The metaball filter
quickInit() installs a custom WebGL fragment shader (modules/Filters.js) on the stage. It hard-thresholds the accumulated alpha coverage of overlapping blobs — coverage ≥ 0.9 becomes opaque, ≤ 0.88 transparent, with a smooth band between — so separate blobs merge into organic shapes where they overlap while keeping their colour.
Notes & requirements
- Browser only. Uses
window(forresizeTo) anddocument.body(to mount the canvas). - PixiJS v8. Built against
pixi.js^8.19.0, includingpixi.js/advanced-blend-modes. - You own the ticker.
Microbiomedoes not start its own loop — calltick()each frame.
