Guides

The web component

<field-root> is the keystone — a custom element that drops into any framework (or plain HTML) unchanged. "Every element is a body" is a web-components-shaped idea.

Install

npm i @field-ui/elements

Set up the field

Import the package once to register the element, then drop a single <field-root> anywhere. It mounts a fixed, full-viewport canvas behind your page and runs the engine. It's decorative, so it marks itself aria-hidden automatically.

HTML
<script type="module">
  import '@field-ui/elements';
</script>

<field-root accent="#4da3ff"></field-root>

Mark elements as bodies

The field reacts to every [data-body] element on the page (the field-reacts law). Forces compose, space-separated; each force reads only the attributes it uses.

HTML
<!-- one force -->
<a data-body="attract" data-strength="0.9" data-range="320">pull me</a>

<!-- composed forces + a condition gate + density write-back -->
<button
  data-body="repel swirl"
  data-strength="1.2"
  data-range="240"
  data-spin="1"
  data-when="active"
  data-feedback
>swirl</button>
Rescan after DOM changes. The engine reads bodies on mount. If you add or remove [data-body] elements later (a route change, a list update), call field.scan() so it picks them up.

Attributes

Set these on the <field-root> element:

  • accent — the travelling accent colour (a hex string).
  • density — particle-count multiplier (default 1).
  • waves — draw the background Currents (default on; "false" to disable).
  • renderdots · trails · links · metaballs · voronoi · streamlines.
  • paletteours · heatmap · infrared · spectrum.
  • attention — opt into conserved attention (one finite strength budget).
  • causality — opt into cross-boundary causality (density spills to neighbours).

Full details in the options reference.

Methods

The full FieldHandle is proxied onto the element, so any page can drive the field after it mounts:

JavaScript
const field = document.querySelector('field-root');

field.scan();                    // after adding/removing [data-body] elements
field.setFormation('wells');     // global field bias
field.setAttention(true);        // conserved attention (one strength budget)
field.setCausality(true);        // density spills to neighbours
field.setRender('streamlines');  // draw the force field itself
field.setPalette('heatmap');     // swap the accent colour template
field.burst(x, y, '#fff');       // a one-shot shove + heat near a point

The Field Cell

For a small, in-frame, single-force demo (instead of the page-wide field), use <field-cell> — a container-sized canvas that runs one force with its own particle pool. It pauses off-screen (IntersectionObserver), re-fits on resize, and honours reduced motion. It's the embeddable unit behind the Manual's per-concept demos.

HTML
<field-cell force="swirl" color="#2dd4bf"></field-cell>
swirl live — move your cursor through the frame
Supported forces. The cell is a simplified poster engine — it runs attract, repel, swirl, gravity, stream, buoyancy, and tether. For the full catalog of 34 against the canonical math, use the page field or the Lab.