Image Trail <mv-image-trail>
Image trail for mouse and pen: every few dozen pixels along the pointer path, the next child image drops exactly on the path, is carried a little by the stroke's momentum, then shrinks away, so fast strokes leave evenly spaced prints; rotate and fall variants.
| Category | Cursors |
|---|---|
| Type | Web Component (<mv-image-trail>) |
| Status | stable |
| Keywords | safe-rewrite, image, trail, cursor, gallery, hover, portfolio |
When to use
- A portfolio or studio hero should leave a trail of project images behind the cursor
- A playful hover zone with images that lean into the stroke or tumble away suits an editorial landing page
- Fast pointer strokes should still leave evenly spaced images rather than scattered jumps
Avoid when
- Visitors must actually browse the images; the trail is decorative and never runs on touch → use Mosaic Gallery instead
- Mobile-first pages where most visitors never hover with a mouse or pen
Install
node scripts/add.mjs image-trail --out ./src/marvelousAI agent with the Marvelous UI MCP server: install_components({ slugs: ["image-trail"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Files copied (dependencies included): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, components/image-trail/image-trail.js, components/image-trail/image-trail.css.
Usage
Canonical markup, to start from and customize with attributes, data-* and CSS variables:
<mv-image-trail threshold="70" style="height:100%;min-height:340px;border-radius:var(--mv-radius-xl);background:var(--mv-bg-subtle);border:1px solid var(--mv-border)">
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20240%20300%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22oklch(0.82%200.12%2070)%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22oklch(0.62%200.18%2030)%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22240%22%20height%3D%22300%22%20fill%3D%22url(%23g)%22%2F%3E%3Ccircle%20cx%3D%22160%22%20cy%3D%2295%22%20r%3D%2238%22%20fill%3D%22oklch(0.95%200.08%2090)%22%20opacity%3D%22.92%22%2F%3E%3Cpath%20d%3D%22M0%20210%20Q60%20170%20120%20205%20T240%20190%20V300%20H0z%22%20fill%3D%22oklch(0.4%200.12%2020)%22%20opacity%3D%22.75%22%2F%3E%3Cpath%20d%3D%22M0%20250%20Q80%20225%20150%20250%20T240%20245%20V300%20H0z%22%20fill%3D%22oklch(0.4%200.12%2020)%22%2F%3E%3Ctext%20x%3D%2218%22%20y%3D%22282%22%20font-family%3D%22Segoe%20UI%2C%20Helvetica%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2217%22%20font-weight%3D%22700%22%20letter-spacing%3D%223%22%20fill%3D%22white%22%3ELISBON%3C%2Ftext%3E%3C%2Fsvg%3E" alt="">
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20240%20300%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22oklch(0.88%200.06%2020)%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22oklch(0.7%200.14%200)%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22240%22%20height%3D%22300%22%20fill%3D%22url(%23g)%22%2F%3E%3Ccircle%20cx%3D%2280%22%20cy%3D%22110%22%20r%3D%2246%22%20fill%3D%22oklch(0.97%200.03%2060)%22%20opacity%3D%22.92%22%2F%3E%3Cpath%20d%3D%22M0%20220%20Q60%20190%20120%20210%20T240%20200%20V300%20H0z%22%20fill%3D%22oklch(0.35%200.08%20330)%22%20opacity%3D%22.75%22%2F%3E%3Cpath%20d%3D%22M0%20250%20Q80%20225%20150%20250%20T240%20245%20V300%20H0z%22%20fill%3D%22oklch(0.35%200.08%20330)%22%2F%3E%3Ctext%20x%3D%2218%22%20y%3D%22282%22%20font-family%3D%22Segoe%20UI%2C%20Helvetica%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2217%22%20font-weight%3D%22700%22%20letter-spacing%3D%223%22%20fill%3D%22white%22%3EKYOTO%3C%2Ftext%3E%3C%2Fsvg%3E" alt="">
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20240%20300%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22oklch(0.75%200.08%20220)%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22oklch(0.45%200.12%20260)%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22240%22%20height%3D%22300%22%20fill%3D%22url(%23g)%22%2F%3E%3Ccircle%20cx%3D%22120%22%20cy%3D%2280%22%20r%3D%2230%22%20fill%3D%22oklch(0.95%200.04%20200)%22%20opacity%3D%22.92%22%2F%3E%3Cpath%20d%3D%22M0%20200%20Q60%20150%20120%20190%20T240%20175%20V300%20H0z%22%20fill%3D%22oklch(0.25%200.05%20250)%22%20opacity%3D%22.75%22%2F%3E%3Cpath%20d%3D%22M0%20250%20Q80%20225%20150%20250%20T240%20245%20V300%20H0z%22%20fill%3D%22oklch(0.25%200.05%20250)%22%2F%3E%3Ctext%20x%3D%2218%22%20y%3D%22282%22%20font-family%3D%22Segoe%20UI%2C%20Helvetica%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2217%22%20font-weight%3D%22700%22%20letter-spacing%3D%223%22%20fill%3D%22white%22%3EICELAND%3C%2Ftext%3E%3C%2Fsvg%3E" alt="">
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20240%20300%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22oklch(0.8%200.14%2060)%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22oklch(0.6%200.19%2040)%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22240%22%20height%3D%22300%22%20fill%3D%22url(%23g)%22%2F%3E%3Ccircle%20cx%3D%22170%22%20cy%3D%22100%22%20r%3D%2242%22%20fill%3D%22oklch(0.93%200.1%2095)%22%20opacity%3D%22.92%22%2F%3E%3Cpath%20d%3D%22M0%20215%20Q60%20180%20120%20200%20T240%20185%20V300%20H0z%22%20fill%3D%22oklch(0.42%200.14%2035)%22%20opacity%3D%22.75%22%2F%3E%3Cpath%20d%3D%22M0%20250%20Q80%20225%20150%20250%20T240%20245%20V300%20H0z%22%20fill%3D%22oklch(0.42%200.14%2035)%22%2F%3E%3Ctext%20x%3D%2218%22%20y%3D%22282%22%20font-family%3D%22Segoe%20UI%2C%20Helvetica%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2217%22%20font-weight%3D%22700%22%20letter-spacing%3D%223%22%20fill%3D%22white%22%3EMARRAKECH%3C%2Ftext%3E%3C%2Fsvg%3E" alt="">
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20240%20300%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22oklch(0.85%200.07%20160)%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22oklch(0.55%200.1%20180)%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22240%22%20height%3D%22300%22%20fill%3D%22url(%23g)%22%2F%3E%3Ccircle%20cx%3D%2270%22%20cy%3D%2290%22%20r%3D%2234%22%20fill%3D%22oklch(0.97%200.03%20120)%22%20opacity%3D%22.92%22%2F%3E%3Cpath%20d%3D%22M0%20190%20Q60%20140%20120%20185%20T240%20170%20V300%20H0z%22%20fill%3D%22oklch(0.3%200.06%20200)%22%20opacity%3D%22.75%22%2F%3E%3Cpath%20d%3D%22M0%20250%20Q80%20225%20150%20250%20T240%20245%20V300%20H0z%22%20fill%3D%22oklch(0.3%200.06%20200)%22%2F%3E%3Ctext%20x%3D%2218%22%20y%3D%22282%22%20font-family%3D%22Segoe%20UI%2C%20Helvetica%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2217%22%20font-weight%3D%22700%22%20letter-spacing%3D%223%22%20fill%3D%22white%22%3EDOLOMITES%3C%2Ftext%3E%3C%2Fsvg%3E" alt="">
<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20240%20300%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22oklch(0.8%200.1%20250)%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22oklch(0.55%200.17%20280)%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22240%22%20height%3D%22300%22%20fill%3D%22url(%23g)%22%2F%3E%3Ccircle%20cx%3D%22150%22%20cy%3D%2285%22%20r%3D%2240%22%20fill%3D%22oklch(0.96%200.05%2080)%22%20opacity%3D%22.92%22%2F%3E%3Cpath%20d%3D%22M0%20225%20Q60%20200%20120%20215%20T240%20205%20V300%20H0z%22%20fill%3D%22oklch(0.95%200.01%20250)%22%20opacity%3D%22.75%22%2F%3E%3Cpath%20d%3D%22M0%20250%20Q80%20225%20150%20250%20T240%20245%20V300%20H0z%22%20fill%3D%22oklch(0.95%200.01%20250)%22%2F%3E%3Ctext%20x%3D%2218%22%20y%3D%22282%22%20font-family%3D%22Segoe%20UI%2C%20Helvetica%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2217%22%20font-weight%3D%22700%22%20letter-spacing%3D%223%22%20fill%3D%22white%22%3ESANTORINI%3C%2Ftext%3E%3C%2Fsvg%3E" alt="">
<div style="display:grid;place-items:center;align-content:center;gap:.5rem;height:100%;min-height:340px;text-align:center;pointer-events:none;padding:1rem">
<p style="margin:0;font:600 .75rem/1 var(--mv-font-sans);letter-spacing:.2em;text-transform:uppercase;color:var(--mv-accent-fg)">Travel journal · 2026</p>
<p style="margin:0;font:800 clamp(2rem,5vw,3.6rem)/1 var(--mv-font-sans);letter-spacing:-.04em">Six getaways<br>for this winter</p>
<p style="margin:0;font-size:.85rem;color:var(--mv-fg-muted)">Move your cursor to flip through the posters.</p>
</div>
</mv-image-trail>API
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
threshold | number | 80 | Spacing between two images along the pointer path (px, 10 minimum). |
duration | number | 1100 | Lifetime of an image: enter, hold, exit (ms, 300 minimum). |
variant | rotate | fall | rotate: images lean with the horizontal speed of the stroke; fall: images drop and spin away when they leave. | |
data-over | boolean | Images above the content (below by default). | |
disabled | boolean | Turns the trail off. |
Content structure
| Name | Description |
|---|---|
img (direct children) | The trail images (hidden, cloned into a pool of 6 to 16 copies; srcset and sizes are kept). |
(other children) | Area content, laid over the images. |
CSS classes
| Name | Description |
|---|---|
mv-image-trail-item | Each cloned image in the trail. |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-image-trail-width | 170px | Image width (height follows their aspect ratio). |
--mv-image-trail-radius | var(--mv-radius-lg) | Image radius. |
Accessibility
Decorative: the image layer is aria-hidden and its clones have an empty alt; the source <img> elements stay in the DOM but hidden, so important information belongs in the content. Mouse and pen only (touch drags keep scrolling the page). Reduced motion: no images appear. Forced colors: each image gets a system outline. Web Animations only, no rAF loop.