Web component
Drop-in <motioness-img> custom element with no build step required.
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:
bashnpm install @motioness/proxy-client
tsimport '@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
| Attribute | Description |
|---|---|
project-key | Required. Your pk_…. |
src | Required. Full source URL with scheme. |
motion | subtle / medium / kinetic |
mode | loop / animate-in / animate-on-hover |
dur-seconds | Output length, 2-8 |
prompt | Override prompt (≤500 chars) |
seed | Deterministic seed |
aspect | 1:1 / 16:9 / 9:16 / preserve |
idempotency-key | Force distinct asset from same source |
wait-ms | Long-poll deadline, 0-10000 |
signature | HMAC for signed mode |
exp | Unix seconds expiry for signed mode |
loading | lazy defers mp4 load until in viewport |
origin | Override 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:
cssmotioness-img::part(video) { object-fit: cover;}
Events
tsconst 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.
tsconst 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.)