Animations, portals, and media

Animations, portals, and media are grouped together because they all involve runtime-owned behavior that is declared during component conversion.
That does not make them hidden. It means the widget tree describes what should exist, then the runtime tracks the transient state needed to make it behave across frames.

Animation contract

Animation in Fission is runtime-owned motion requested against stable widget identity.
Type
Purpose
Notes
AnimationPropertyId
Identifies which visual property is animated
Examples include opacity, position, scale, or other supported properties.
AnimationStartValue
Describes where the animation begins
Lets an animation start from a known value instead of guessing from current rendering.
AnimationRequest
Full request for one animation
Contains property, target, timing, easing, and related metadata.
EasingFunction
Timing curve
Controls how progress moves from start to end.
WidgetId
Stable target identity
Required when the runtime needs to track an animation across reconversions.
Widgets request animation through ctx.request_animation_for(...) or ctx.anim_for(id).request(...). The runtime stores the active animation state and exposes current values through ViewHandle.
Do not store per-frame animation progress in GlobalState. App state should hold durable facts such as "the panel is open" or "the item was selected." The runtime can animate from the old visual state to the new visual state.

Portal contract

A portal is the runtime mechanism for content that should render outside the normal parent layout while still belonging to the same app model.
Type
Purpose
Notes
PortalLayer
Ordered overlay layer
Keeps modal, flyout, toast, and other overlays predictable.
PortalEntry
One registered portal item
Holds the content and layer identity for runtime composition.
WidgetId
Stable authoring identity
Used by flyouts, popovers, and layout-aware overlays.
Use portals when content genuinely belongs above the main tree: modals, drawers, flyouts, popovers, menus, tooltips, and toasts. Do not use portals to avoid learning normal layout. Ordinary rows, columns, stacks, and scroll regions should remain inline.
Higher-level widgets such as Modal, Drawer, Popover, Tooltip, Menu, and Toast exist so most apps do not need to register low-level portal entries directly.

Media and embed registration

Some widgets represent host-backed or specialized surfaces rather than ordinary paint-only content.
Registration
Used by
What it tells the runtime
VideoRegistration
Video
A video surface exists at this widget identity, with source and sizing metadata.
WebRegistration
WebView
An embedded browser surface exists at this widget identity, with requested URL and metadata.
Terminal session state
TerminalView
A terminal surface needs host process, cell buffer, focus, input, and scrollback coordination.
3D scene data
Scene3D and chart 3D paths
A scene needs 3D primitives, camera, lighting, and renderer support.
The runtime keeps these registrations tied to layout identity and host presentation. The shell still owns the platform-specific implementation: video decoding, embedded browser engine, terminal process integration, or graphics backend details.

Runtime-owned state

The runtime tracks several kinds of state that usually should not live in GlobalState directly:
Runtime-owned state
Why it stays out of product state
Active animation progress
It is transient frame state derived from durable product state.
Hover, press, focus, and gesture tracking
It describes current input interaction, not product truth.
Scroll offsets
It belongs to the visible runtime surface unless the product explicitly saves a scroll position.
Portal layering and placement
It is layout/runtime composition around the widget tree.
Video/web/terminal surface state
It is host integration state around a registered surface.
Hero-position bookkeeping
It connects prior and current layout geometry for a visual transition.
Store the durable decision in app state; let the runtime manage the transient mechanics.

Common mistakes

Do not start side effects in component conversion to drive animation or media. Declare the desired widget tree and registrations, then let the runtime and shell handle frame progression.
Do not put a modal or popover's open state inside a local widget field. Store show_settings, active_menu, or similar product-visible state in GlobalState and let the widget tree include or exclude the overlay from that state.
Do not use WebView as a substitute for building normal Fission screens. It is for embedded web content that genuinely needs a browser surface.
Do not expect every media surface to have identical behavior on every host without validation. Video, embedded browsers, terminal sessions, and 3D graphics live close to platform capabilities and deserve target-specific tests.
For the component conversion contract, see Widget authoring boundary. For the guide-level explanation, read Media, animation, portals, and 3D. For concrete media widgets, see Media and custom surfaces.
Fission
A cross-platform, GPU-accelerated user interface framework for Rust. MIT licensed.
Copyright (c) 2026 Fission
Ready to use today. Widget APIs are expected to remain stable; some runtime and shell APIs may change before 1.0.0.
Fission 0.7.0