Foundry Virtual Tabletop Version 14 introduces a new Visual Effects (VFX) framework exposed under foundry.canvas.vfx. The framework is experimental in V14 and must be explicitly opted-in (details below). It provides abstraction layers for systems and modules to create timeline-driven and composable animations for anything from projectile attacks, spell effects, and more. This framework is extensible by registering options to CONFIG.Canvas.vfx.
The underlying engine uses the animejs library https://animejs.com/ which is now bundled as a core dependency. It's fairly lightweight, only adding +118KB to our vendor.mjs bundle size. The bundled animejs v4 library is exposed as globalThis.animejs. Timelines are driven by the PIXI.Ticker rather animejs managing a separate loop.
Opt-in
The framework is inactive by default. Enable it during init if your module or system plans to use it.
play(references={}) - resolves references, then loads, draws, attaches, and plays all components
stop() - gracefully stops all components; the returned promise resolves true
cancel() - immediately cancels all components; the returned promise resolves false
clone(data={}) - builds a fresh instance from the original unresolved source, optionally merging overrides
VFXComponent
foundry.canvas.vfx.VFXComponent is an abstract base class for a single visual or audio unit that can be composed into effects. The framework initially ships with a number of built-in components. Available components are registered (and can be extended by modules) at CONFIG.Canvas.vfx.components.
singleAttack
Full charge-fly-impact projectile animation. Moves a sprite from an origin to a destination along a path, with optional charge, projectile, and impact phases each supporting their own texture, sound, duration, scale, and animation presets.
singleImpact
Simpler alternative for a single sprite + sound at a fixed position. No path traversal.
foundry.canvas.vfx.VFXPath constructs a multi-segment path for animation of projectiles or particles that allows continuous interpolation of points, elevation, rotation, and sorting at every point along the path. Predefined path types are available under CONFIG.Canvas.vfx.paths with built-in options for linear, arc (using hermite spline), and weave (using hermite spline).
VFXComponentAnimation
Effects can be augmented with an arbitrary number of pre-registered animations. Each foundry.VFXComponentAnimation is a plain object specifying some callback methods:
constcustomAnimation = { setup(state, params) {}, // Optional, called once before animation starts animate(t, state, params) {}, // Required, called each tick with progress t in [0,1] tearDown(state, params) {} // Optional, called after animation completes };
These animations are referenced in the CONFIG.Canvas.vfx.animations registry which can be extended by packages to make more animations available.
Storage and Reference Fields
A crucial design cornerstone of this framework is that foundry.canvas.vfx.VFXEffect is serializable which allows it to be stored in the database or transmitted over websocket. This mechanism allows delivery of visually consistent effect playback across multiple clients.
Effects can be predefined using dynamic references that resolve at runtime. For example a projectile attack will have an origin, a target, or projectile speed, but all of these variables can be resolved at runtime through the references passed to the VFXEffect#play method.
At play time, VFXEffect#play(references) resolves these references. This allows a single effect definition to animate between different tokens on each use.
Usage Examples
Example 1 - Ranged attack from one token to another
Custom documentation about the VFX Framework.
Canvas Visual Effects (VFX) Framework
Foundry Virtual Tabletop Version 14 introduces a new Visual Effects (VFX) framework exposed under
foundry.canvas.vfx. The framework is experimental in V14 and must be explicitly opted-in (details below). It provides abstraction layers for systems and modules to create timeline-driven and composable animations for anything from projectile attacks, spell effects, and more. This framework is extensible by registering options toCONFIG.Canvas.vfx.The underlying engine uses the
animejslibrary https://animejs.com/ which is now bundled as a core dependency. It's fairly lightweight, only adding +118KB to ourvendor.mjsbundle size. The bundled animejs v4 library is exposed asglobalThis.animejs. Timelines are driven by thePIXI.Tickerratheranimejsmanaging a separate loop.Opt-in
The framework is inactive by default. Enable it during init if your module or system plans to use it.
Core Concepts
VFXEffect
foundry.canvas.vfx.VFXEffectis afoundry.abstract.DataModelthat groups one or more named components and sequences them on a shared animejs timeline. It is single-use after construction, callfoundry.canvas.vfx.VFXEffect#playonce orfoundry.canvas.vfx.VFXEffect#cloneto repeat it.Key API methods:
play(references={})- resolves references, then loads, draws, attaches, and plays all componentsstop()- gracefully stops all components; the returned promise resolves truecancel()- immediately cancels all components; the returned promise resolves falseclone(data={})- builds a fresh instance from the original unresolved source, optionally merging overridesVFXComponent
foundry.canvas.vfx.VFXComponentis an abstract base class for a single visual or audio unit that can be composed into effects. The framework initially ships with a number of built-in components. Available components are registered (and can be extended by modules) atCONFIG.Canvas.vfx.components.singleAttackFull charge-fly-impact projectile animation. Moves a sprite from an origin to a destination along a path, with optional charge, projectile, and impact phases each supporting their own texture, sound, duration, scale, and animation presets.singleImpactSimpler alternative for a single sprite + sound at a fixed position. No path traversal.positionalSoundPlays a sound at a world position viafoundry.audio.Sound#playAtPosition. Supports all positional audio parameters.scrollingTextFires foundry.canvas.groups.CanvasInterfaceGroup#createScrollingText at the component's scheduled position in the effect timeline.shakeUsesfoundry.canvas.animation.CanvasShakeEffectfor timeline-synchronized canvas shake.particleGeneratorUsesfoundry.canvas.animation.ParticleGeneratorfor managing a particle emitter as part of animation lifecycle.VFXPath
foundry.canvas.vfx.VFXPathconstructs a multi-segment path for animation of projectiles or particles that allows continuous interpolation of points, elevation, rotation, and sorting at every point along the path. Predefined path types are available underCONFIG.Canvas.vfx.pathswith built-in options forlinear,arc(using hermite spline), andweave(using hermite spline).VFXComponentAnimation
Effects can be augmented with an arbitrary number of pre-registered animations. Each
foundry.VFXComponentAnimationis a plain object specifying some callback methods:These animations are referenced in the
CONFIG.Canvas.vfx.animationsregistry which can be extended by packages to make more animations available.Storage and Reference Fields
A crucial design cornerstone of this framework is that
foundry.canvas.vfx.VFXEffectis serializable which allows it to be stored in the database or transmitted over websocket. This mechanism allows delivery of visually consistent effect playback across multiple clients.Effects can be predefined using dynamic references that resolve at runtime. For example a projectile attack will have an
origin, atarget, or projectilespeed, but all of these variables can be resolved at runtime through the references passed to theVFXEffect#playmethod.This is accomplished through a set of special
foundry.data.fields.DataFieldsubclasses:foundry.canvas.vfx.fields.VFXReferenceField- wraps any DataField; resolves a scalar value or object property with an optional numeric deltafoundry.canvas.vfx.fields.VFXReferenceObjectField- for object types; supports per-key deltasfoundry.canvas.vfx.fields.VFXReferencePointField- convenience for objects specifically having{x, y, elevation?}structureComponents accept either concrete values or reference descriptors for positional and numeric inputs. A reference descriptor looks like:
At play time,
VFXEffect#play(references)resolves these references. This allows a single effect definition to animate between different tokens on each use.Usage Examples
Example 1 - Ranged attack from one token to another
Example 2 - Explosion with screen shake and scrolling damage text
Extending the Framework
Register custom components, animations, and path generators during init: