🚧 Glyx is pre-release software. APIs may change before v1.0. Get started →
Documentation
Guides
Animations

Animations

Add a transition prop to any <View> and Glyx interpolates the change instead of snapping to the new value:

<View
  style={{ opacity: visible ? 1 : 0 }}
  transition={{ duration: 200 }}
/>

v1 scope: opacity only. This is the CSS-transition layer, not Framer Motion parity. Transform/scale/color transitions and a full spring/gesture animation API (useAnimatedValue, drag-to-dismiss, staggered lists) are a separate, larger initiative — see the v2 roadmap — and haven't been started.

Why this exists

Before this, animating anything meant hand-rolling it — a setInterval loop pushing new style values from JS each frame, the same pattern used for the auto-rotate demo in model-viewer. That's real per-frame JS work crossing the FFI boundary 60+ times a second, and on QuickJS (no JIT) that cost is higher than on V8. transition avoids it entirely.

How it works

JS declares the transition's intent once — on the render where the style value changes, transitionMs is sent to Rust as a plain node prop. Rust's render loop owns the interpolation from there: it samples an eased value fresh every frame with zero JS re-entry, using an ease-out cubic curve (the same "settle in" feel as most CSS-transition defaults), and only re-renders while a transition is actually in flight — static frames cost nothing extra. This is the same "JS drives state, Rust is a dumb renderer" model used for 2D and GLTF animation playback elsewhere in Glyx, just applied one level lower for this specific case.

API

PropTypeDescription
transition.durationnumberTransition length in milliseconds.
function Panel({ open }: { open: boolean }) {
  return (
    <View
      style={{ opacity: open ? 1 : 0, backgroundColor: '#1A1A26' }}
      transition={{ duration: 250 }}
    >
      <Text>Panel content</Text>
    </View>
  )
}

Only opacity changes are interpolated today — other style properties on the same node update immediately, as before.