VSTDOCSv0.0.34

DOCS / UI REFERENCE

Animation

Tweens run on the host timer (16ms ticks through the C++ scheduler) and set React state, so every animated style flows through the normal setProps → repaint path — no separate animation system to learn.

CSS-style transitions (since 0.0.26)

The declarative path: put transition classes on a node and its style changes tween from the currently displayed values instead of jumping — mid-flight re-renders retarget smoothly, exactly like the web.

TSX
<View
  className={cx(
    "h-2 rounded-full transition-colors duration-300 ease-out",
    hot ? "bg-red-500" : "bg-zinc-700",
  )}
/>
  • transition animates opacity, colors, transforms, and blur; transition-all/colors/opacity/transform/none scope it.
  • duration-* and delay-* are literal milliseconds; ease-linear/in/out/in-out pick the curve.
  • Since 0.0.27, transitionEasing also accepts any CSS cubic-bezier(x1,y1,x2,y2) spec alongside the four named curves — set it via the style prop, e.g. style={{ transitionEasing: "cubic-bezier(0.34, 1.56, 0.64, 1)" }}. Parsed curves are cached by their string; malformed specs fall back to ease-in-out.
  • Keyframe presets: animate-spin, animate-pulse, and animate-bounce loop until the class comes off.
  • Honest limit: native hover:/active:/focus: merges apply in C++ without a JS round-trip, so they can't transition — animate hover with onMouseEnter state when you need it smooth.

useTween

a splash entrance
import { useTween, lerp, Easing } from "@vsreact/core";

function Splash() {
  const t = useTween({ duration: 600, delay: 150, easing: Easing.outExpo });

  return (
    <View
      className="items-center justify-center"
      style={{ opacity: t, marginTop: lerp(24, 0, t) }}
    >
      <Text className="text-2xl font-bold">STASHTRACK</Text>
    </View>
  );
}
  • useTween({duration, delay?, easing?, onComplete?}) — eased progress 0→1, starting on mount. Remount (via key) to replay.
  • Easing — linear, outCubic, inOutCubic, outExpo, outBack, outQuint, or any (t) => t function.
  • lerp(from, to, t) — map progress onto any numeric style value.

useSpring

For interactive motion where a fixed-duration tween feels wrong — toggle thumbs, drawers, meters chasing levels — useSpring gives you a value that physically springs toward its target whenever the target changes:

TSX
import { useSpring } from "@vsreact/core";

function Drawer({ open }: { open: boolean }) {
  const x = useSpring(open ? 0 : -240, { stiffness: 220, damping: 26 });

  return <View className="absolute inset-y-0 w-[240]" style={{ left: x }} />;
}
  • useSpring(target, {stiffness?, damping?, mass?, restDelta?}) — defaults 170 / 24 / 1. Lower damping bounces; higher snaps.
  • Retargeting mid-flight keeps the current velocity — motion stays continuous when the user toggles quickly. The built-in Toggle animates its thumb this way.
  • springStep(position, velocity, target, options, dtMs) — the pure integrator, exported for driving springs from your own loops.

Staggered sequences

Compose entrances by giving each element its own delay — the StashTrack splash staggers logo, wordmark, and status line this way:

TSX
const logo = useTween({ duration: 500, easing: Easing.outBack });
const word = useTween({ duration: 500, delay: 120, easing: Easing.outCubic });
const line = useTween({ duration: 400, delay: 260 });

Timers

setTimeout and setInterval work inside the engine — they are backed by the same native scheduler, so a polling loop or a debounce behaves exactly like on the web. useTween is built on them.