Web component

<motioness-img> is a self-contained custom element. Works in any HTML page, no framework or bundler needed.

Install

Either import from npm:

bash
npm install @motioness/proxy-client
ts
import '@motioness/proxy-client/element';

Or use the prebuilt CDN script:

html
<script type="module" src="https://motioness.com/proxy-client/element.js"></script>

The element registers itself on import.

Basic use

html
<motioness-img project-key="pk_abc" src="https://cdn.acme.com/hero.png"></motioness-img>

That's it. The element renders an internal <video> with the proxy mp4, poster jpg, and autoplay muted loop playsinline defaults. You'll get a square aspect (matching the source) at the element's natural width.

Attributes

AttributeDescription
project-keyRequired. Your pk_….
srcRequired. Full source URL with scheme.
motionsubtle / medium / kinetic
modeloop / animate-in / animate-on-hover
dur-secondsOutput length, 2-8
promptOverride prompt (≤500 chars)
seedDeterministic seed
aspect1:1 / 16:9 / 9:16 / preserve
idempotency-keyForce distinct asset from same source
wait-msLong-poll deadline, 0-10000
signatureHMAC for signed mode
expUnix seconds expiry for signed mode
loadinglazy defers mp4 load until in viewport
originOverride proxy origin (default https://motioness.com)

Modes

html
<!-- Loops forever --><motioness-img project-key="pk_..." src="..." mode="loop" /><!-- Plays once on mount --><motioness-img project-key="pk_..." src="..." mode="animate-in" /><!-- Pauses until hover --><motioness-img project-key="pk_..." src="..." mode="animate-on-hover" />

animate-on-hover resets to the first frame on mouseleave, so leaving + re-entering replays from the start.

Styling

The element renders a <video> internally. Use standard CSS:

html
<motioness-img project-key="pk_abc" src="..." style=" width: 100%; max-width: 800px; aspect-ratio: 16/9; border-radius: 16px; overflow: hidden; "/>

To target the inner <video> specifically:

css
motioness-img::part(video) { object-fit: cover;}

Events

ts
const el = document.querySelector('motioness-img')!;el.addEventListener('motioness-ready', (e) => { console.log('mp4 loaded', (e as CustomEvent).detail);});el.addEventListener('motioness-error', (e) => { console.error((e as CustomEvent).detail);});

Programmatic update

The element observes attribute changes — set new attributes and the URL rebuilds.

ts
const el = document.querySelector('motioness-img')!;el.setAttribute('motion', 'kinetic');el.setAttribute('seed', '42');// New URL is constructed; <video> reloads

Server rendering

The element progressively enhances. SSR'd HTML works — when the script loads, it upgrades. Until then the element is invisible (the custom element CSS sets display: block on upgrade).

For a fallback while the script is in flight:

html
<motioness-img project-key="pk_abc" src="..." style="aspect-ratio: 16/9; background: #111"> <img slot="fallback" src="..." alt="..." style="width: 100%" /></motioness-img>

(The slot="fallback" content is replaced once the element upgrades.)

Ask a question... ⌘I