Media Fx Pro

ProShowcase & MediaWebGLpowered by @vectorvesper/motion

A shader-based effects layer for images and video — a library of named effects with per-effect parameters, a single intensity control, and optional depth-map input for parallax displacement.

Media Fx Pro

Included with membership

Members install Media Fx Pro with one command and get the full source, the usage code and the Framer remix, licensed for client work. One membership covers the whole library and the CLI.

When to use it

One hero image or video that should not sit flat. It is a per-element treatment, not a page background — put it on the thing you want looked at. The effect reads as a property of the picture, so a page with several of these stops feeling deliberate quickly.

  • Give the wrapper a real width and height. The canvas sizes itself from its container, and a container with no height collapses to nothing.
  • Ship an image close to the size it is drawn at — the effect samples the full resolution every frame.
  • Pass depthSrc when using depth-parallax; without it that effect has no depth to displace and looks flat.
  • Set alt. The fallback image stays in the tree and is what a screen reader reads.

Avoid:

  • Do not use it as a full-page background. It redraws continuously while visible, and at viewport size that is the most expensive thing on the page.
  • Do not raise intensity to make a weak image interesting — the effect exaggerates what is there, including compression artefacts.
  • Do not host the media somewhere that omits CORS headers. The pixels have to be read back, and a cross-origin file without them leaves the canvas blank behind the fallback image, with nothing in the console.

Props

One tag that puts a heavier distortion over an image or a video — liquid colour, water rings, parallax depth, or a shattered-glass break-up. Depth parallax can use a real depth map, so a flat photo gains actual dimension as the cursor moves.

<MediaFxPro />

The media and its effect. Fills its container.

PropTypeDefaultDescription
src*string—Image or video to show. Required.
isVideobooleaninferred from srcForces the source to be treated as a video. Set it when the URL has no file extension to give the guess away.
altstring""Alternative text. Set it unless the media is decorative.
effectMediaFxEffect"liquid-chromatic"Which distortion runs. See the four below.
intensitynumber1How strong that effect is. 0 leaves the media untouched.
depthSrcstring—A depth map for the `depth-parallax` effect — lighter areas read as nearer. Without one the effect estimates depth from the image itself, which is softer and less accurate.
params[number, number, number, number]—Four spare values handed to the effect's shader, for fine-tuning.
crossOrigin"anonymous" | "use-credentials""anonymous" for media on another domainHow the media and the depth map are fetched. The effect has to read the pixels back, which the browser only permits on a cross-origin file that was requested this way — so anything served from another domain gets it by default. Set it yourself only when the host needs credentials.
classNamestring""Applied to the wrapper.
dprnumberthe screen's, capped at 2Pixel ratio the effect is drawn at, before the quality tier scales it.
disableAdaptiveQualitybooleanfalseDraws at full resolution on every device. By default the effect is scaled to 0.85 on a mid tier and 0.7 on the most constrained one; set this and the tier is ignored.
mount"auto" | "eager""eager"When to build the effect. The default builds it on mount. Set "auto" to wait until the element is near the viewport and the page has frame headroom, which defers compiling the effect and uploading the media to the graphics card. Neither setting takes it off the shared frame loop or overrides the reduced-motion preference. A scene running its own loop would be invisible to the scheduler, so it could not be set aside under load, and it would slow every other animation on the page rather than only itself.

Presets

PresetDescriptionKey Overrides
"liquid-chromatic"Colour separates and drifts like oil on water. The default.—
"water-ripple"Rings spread out from the cursor across the surface.—
"depth-parallax"Layers shift against each other as the cursor moves. Best with depthSrc.—
"glass-shards"The image breaks into angular facets that catch the light.—
The effects respond to the cursor and keep running under reduced motion. Pass intensity={0} when the preference is set — the media still shows, without the distortion.
Media on another domain needs crossOrigin and a permissive CORS header at the source. Without both, the effect cannot read the pixels and the element renders blank rather than erroring.
depth-parallax with a depth map loads two images and samples both every frame — the heaviest of the four. The others are a single pass.
Client component. It opens a GPU drawing context on mount — import it dynamically with ssr: false if your route renders on the server.
It draws on the shared frame loop rather than starting one of its own, so putting several animated components on a page costs one callback, not one each, and the scheduler can set decorative work aside when frames get tight. Effect strength and resolution follow the device tier. If the browser takes the drawing context away — which it does under memory pressure, and more often on a page with several of these — the component reports it and rebuilds once the context comes back, instead of leaving a permanently black rectangle.
Back to all components