GPU interaction engine

Expression in motion

Turn scroll, gestures, time, and sound into movement across images, video, and typography.

TypeScriptWebGL215 independent pluginsMIT licensed

01 / How it works

From input to effect

Drivers read what happens. Mappings decide what changes. Plugins turn those changes into shapes, textures, motion, and color. Connect one input to several effects, or try a different input with the same effect.

  1. 01InputRead an interaction
  2. 02SignalMeasure the change
  3. 03MappingChoose a parameter
  4. 04EffectRender the response

Built to stay in step

One frame scheduler coordinates updates. Visibility checks and adaptive quality help manage the cost of rendering.

Compose what you need

Start with the core, then add individual plugins. Change the driver and reuse the same integration pattern.

02 / The inputs

Change the input
Keep the effect

Seven native drivers. Switch between them to see the same Morph effect connected to a different input.

Same effect, different input
import { comice, scroll } from 'comice'
import { morph } from '@comice/morph'

const shape = morph({ to: 'circle(40%)' })

const handle = comice('#media')
  .use(shape)
  .driver(scroll({ subject: '#scene', range: 'contain' }))

// On component disposal:
// handle.destroy()

Tie progress to a section’s position in the viewport. Scrolling back reverses the morph.

Find media markup, sizing, and cleanup in the setup guide .

03 / The effects

Fifteen plugins
One approach

Import each plugin on its own. Combine effects and control their parameters through the same core API.

Start with Comice

Build your next interaction

Choose an input. Add an effect. Make it part of your page.

In active development. Source, setup, and package guides are on GitHub.