Support for pointer events in presentations

Author: NiikelionCreated May 25, 2025Updated May 31, 2026
Labelsb-enhancement

Description I'm aware that this project was created primarily for video creation, but I believe it have a lot of potential in presentation and interactive animation space. That being said, interactive elements/snippets would allow us to make even better presentations and could help with creating interactive widgets for learning tools since motion canvas animations can be embedded in the websites.

Proposed solution Add createInteractionEffect(handler: (interaction: Interaction) => void): void hook that runs callback on every input received. This would also require adding events to the visible canvas. Keep in mind, that in editor there are overlays over the canvas that need to be accounted for.

Considered alternatives This can be accomplished already by creating editor plugin/manually adding events to canvas and passing dispatcher as variable when embedding.

Additional context I needed this change for a long time but hesitated to post the issue since it seemed like a big feature that may not be very important to the maintainers of this project. In the meantime I managed to create editor plugin and a hook that allowed me to implement draggable elements in the presentation mode. I'm going to publish the plugin but I still believe this could be a part of the core package.

Example hook implementation that requires SubscribableEvent<Interaction> as a scene variable:

typescript
export function createInteractionEffect(handler: (interaction: Interaction) => void) {
    const interactionSource = useScene().variables.get<SubscribableEvent<Interaction> | null>(interactionSourceVariableKey, null)

    const interactions = createSignal<Interaction[]>([])

    function storeInteraction(interaction: Interaction) {
        interactions([...interactions(), interaction])
    }

    interactionSource().subscribe(storeInteraction)

    createDeferredEffect(() => {
        for (const interaction of interactions()) handler(interaction)
        if (interactions().length > 0) interactions([])
    })
}

Source: motion-canvas/motion-canvas