Motion
A standalone Blazor motion engine. A closed-form spring solver runs in C#, bakes physics into CSS linear() easings, and the result animates on the compositor. Physics authored in .NET, zero per-frame interop.
What it is
Blazor cannot tick animation frames from C#: interop latency (and Server round-trips) rule out per-frame work on the .NET side. So Navius Motion moves the whole boundary. C# is the authoring and compiling surface: SpringSolver evaluates a damped harmonic oscillator statelessly, LinearEasingBaker samples it into a linear(...) easing string plus a real settle duration, and that crosses into the browser once. From there a plain CSS transition or a single element.animate() call runs the motion, hardware accelerated, with no JavaScript animation library and no rendering on the .NET side.
The same spring formulas are implemented on both sides (C# and the JS executor) so a curve baked at build time and a curve re-baked mid-interruption agree exactly. That is what makes velocity-preserving retargeting possible without an interop round trip.
Two tiers
Reach for the lightest tier that does the job.
- Generated CSS presets (
navius-motion.css). Springs baked tolinear()at build time and shipped as plain classes:.motion-pop,.motion-fade-up,.motion-press. No JavaScript at all. Ideal for enter/exit presence and press/hover micro-interactions. - The runtime path (
MotionJsInteropovernavius-motion.js). A thin WAAPI executor for cases CSS cannot express: interruption handling with velocity carry-over (RetargetAsync), gesture callbacks back to C#, and reduced-motion policy per call.
Both tiers consume the same preset definitions, so a component can start on the CSS tier and graduate to the runtime tier without a visual change.
Standalone by design
Navius Motion holds no reference to the primitives package. It is usable on its own in any Blazor app. Where it does integrate with Navius primitives, the coupling is by contract, not by reference: the presence presets key off the same discrete state attributes every primitive already emits (data-open, data-closed, data-starting-style, data-ending-style). Drop motion-pop onto a Dialog popup or a Collapsible panel and the primitive's existing deferred-unmount timing drives the exit animation.
Install
Reference the package, then link the generated stylesheet from your host page for the CSS tier.
<ItemGroup>
<PackageReference Include="Navius.Motion" Version="*" />
</ItemGroup><link href="_content/Navius.Motion/navius-motion.css" rel="stylesheet" />The runtime tier needs no manual script tag: MotionJsInterop imports navius-motion.js on first use from the same content root.
@using Navius.Motion
@* CSS tier: a preset class on any element with the state-attribute contract. *@
<NaviusDialogPopup class="motion-pop">...</NaviusDialogPopup>
@* CSS tier: the insert-only enter helper, splatted onto your own element. *@
<div @attributes="Motion.Enter(Preset.FadeUp)">...</div>