Play .df in Runtime
Overview
Runtime playback is split into two layers:
@designful/df-runtime-corefor deterministic playback and state machine evaluation@designful/df-runtime-core/runtimefor tree-shakeable runtime-only embedding@designful/df-player-webfor browser controls and rendering (konvaby default,canvas2dfallback)
Script-related note:
- Editor script authoring APIs (
createScript,runScriptHook, script diagnostics) are documented under/help/animation/script-*. - Exported
.dfmanifests preserve validated script metadata atmanifest.runtime.animationScriptsfor parity and tooling inspection. .dfruntime currently focuses on timeline/state-machine playback; script authoring hooks are not a runtime public API in this page.
Low-level Runtime
import { createRuntimeInstance, loadDf } from '@designful/df-runtime-core'
const document = await loadDf('/assets/sample.df')
const runtime = createRuntimeInstance(document, { autoplay: false, loop: true })
runtime.play()
runtime.setInput('machine-main', 'hover', true)
runtime.fireTrigger('machine-main', 'click')
setInput and fireTrigger evaluate transition eligibility immediately, so state-machine transitions can start even while playback is paused. A later click trigger can also drive a return transition (for example toggling active style back to idle/hover on second click) when your state machine defines it.
When .df contains embedded buffers, loadDf hydrates image assets referenced by bufferId into runtime data URLs automatically.
This allows loading embedded-image .df binaries in offline/sandboxed environments without external image fetch.
Web Player
import { DfPlayer } from '@designful/df-player-web'
const player = DfPlayer.mount(container, { autoplay: false, fit: 'contain' })
await player.load('/assets/sample.df')
player.play()
player.seek(500)
container.addEventListener('pointerenter', () => {
player.setInput('machine-main', 'hover', true)
})
container.addEventListener('pointerleave', () => {
player.setInput('machine-main', 'hover', false)
})
container.addEventListener('click', () => {
player.fireTrigger('machine-main', 'click')
})
Script Tag (UMD)
For no-build-tool integration, use the vanilla UMD bundle from @designful/df-player-web:
<div id="player" style="width: 480px; height: 320px;"></div>
<script src="/path/to/vanilla.umd.js"></script>
<script>
const player = window.DesignfulDfPlayer.DfPlayer.mount(
document.getElementById('player'),
{ autoplay: false, fit: 'contain' },
)
player.load('/assets/sample.df')
</script>
You can also open the standalone no-build demo at /demos/df-player-vanilla.html.
Lifecycle option layering:
mount(container, createOptions)configures renderer/layout/interaction baseline.player.load(src, loadOptions)applies source-scoped playback defaults.player.reset(resetOptions)applies seek/playback reset behavior without remounting.
Interaction policy precedence:
- Runtime updates via
player.setInteractionPolicy(...) mount(..., { interaction })- Asset defaults from
manifest.runtime.interactionDefaults - Built-in fallback defaults
Enable render hooks and debug HUD:
const player = DfPlayer.mount(container, {
autoplay: false,
debugOverlay: true,
renderHooks: {
beforeRender: ({ state }) => console.log('before', state.currentTimeMs),
afterRender: ({ state }) => console.log('after', state.currentTimeMs),
},
})
Select a specific timeline explicitly:
const player = DfPlayer.mount(container, {
timelineId: 'timeline-main',
autoplay: false,
fit: 'contain',
})
Force legacy Canvas2D mode:
const player = DfPlayer.mount(container, {
renderer: 'canvas2d',
autoplay: false,
fit: 'contain',
})
Update layout through immutable copyWith-style API:
player.setLayout({
fit: 'cover',
alignX: 'end',
alignY: 'center',
})
Runtime Events
You can subscribe to:
loadreadyassetProgressstateChangediagnosticsloopcompleteerror
loop and complete are emitted for both standalone timelines and state-machine-driven playback (derived from the active state timeline duration).
assetProgress emits error for image assets that cannot produce a loadable source (for example missing src and unresolved bufferId) so callers can surface fallback UI.
Rendering Visibility Behavior
When the document is hidden (or player container is offscreen), runtime rendering is paused automatically while playback state is preserved. Rendering resumes when visibility returns.
Deprecation Aliases
Temporary migration aliases (with one-time warning):
dispose()->destroy()startRenderLoop()->startRendering()stopRenderLoop()->stopRendering()
Migration notes template: /help/animation/df-runtime-migration-notes-template
Docs Demo Quick Capture
In /docs/api/managers/df-runtime, the runtime demo toolbar includes:
Export .dfto save current loaded runtime sourceExport PNGandExport WebPfor current canvas frame snapshotsExport WebMfor a short recorded preview segment- runtime diagnostics summary + itemized table (
level/code/message/path)- includes unresolved image asset diagnostics (
IMAGE_ASSET_NOT_FOUND,IMAGE_ASSET_TYPE_MISMATCH)
- includes unresolved image asset diagnostics (
Current Runtime Scope (V1)
Supported today:
- timeline sampling and easing in runtime core
- state machine inputs/transitions in runtime core
- Konva renderer reusing editor
NodeFactoryfor higher playback parity - Canvas2D fallback renderer for
frame,text,image,pen-path, andshapevariants (rect,circle,ellipse,line,arrow,polygon,star,path,arc) - hierarchy transform inheritance (
groupas container node) - frame clipping (
frame.clipContent) in Canvas2D fallback - blend mode mapping (
blendMode->globalCompositeOperation) in Canvas2D fallback - image asset preload + crop support in Canvas2D fallback
- font preload via browser
document.fonts(both renderers); URL font assets useFontFacewhen available - image loading/error placeholder rendering in Canvas2D fallback (missing assets do not crash playback)
- font fallback chain in Canvas2D fallback (
fontFamily -> sans-serif) with warning logs on load failures
Current limits:
- advanced visual effects still have lower parity in Canvas2D adapter (use Konva renderer path for full parity)
- runtime does not re-run editor auto-layout; playback uses exported transforms/sizes
Canvas2D Compatibility Diagnostics
When renderer: 'canvas2d', player runs load-time feature checks and appends warnings to diagnostics when capability gaps are detected.
| Feature | Diagnostic code | Runtime impact |
|---|---|---|
Path2D unavailable for path shapes | CANVAS2D_PATH2D_UNSUPPORTED | Path rendering can be incomplete |
advanced text metrics unavailable (actualBoundingBox*) | CANVAS2D_TEXT_METRICS_LIMITED | Text wrapping/alignment can differ by browser |
| blend mode composite operation unsupported | CANVAS2D_BLEND_MODE_UNSUPPORTED | Blend mode falls back to source-over |
Image URL CORS Requirements
For URL-backed image assets (asset.src):
- player loads images with
crossOrigin='anonymous' - image host must allow your app origin with CORS headers (or
*when credentials are not required) - if CORS blocks fetch/decode,
assetProgressreportsstatus='error'and runtime draws placeholders
For portable or offline playback, prefer embedded image assets (bufferId) from exporter.
Default timeline resolution:
- with
timelineId: use that timeline - without
timelineId+ state machines: use state-machine timelines - without
timelineId+ no state machines: first timeline with tracks (fallback first timeline)
Debugging
- Use
player.getState()to inspect current timeline time and active machine state. - Enable
debugOverlay: trueto display time/state/fit data directly on canvas. - Use
runtime.getDiagnostics()to inspect format/runtime warnings and errors. - Use
@designful/df-validatorbefore load to fail fast on invalid binaries/documents. - CI includes runtime perf smoke checks (medium
.dfload budget, playback loop budget, tick+render average frame budget, simulated 5-minute heap growth stability). - CI also includes runtime package boundary checks (no runtime-package dependency cycles, no dependency on editor UI package).