moonbit-motion-lab

    Motion-curve quality assurance and deterministic timeline compilation for MoonBit

    motion
    animation
    sampling
    timeline
    diagnostics
    quality-assurance
    Download zip
    Version
    0.1.2
    License
    Apache-2.0
    Last updated
    1 hour ago
    Downloads
    6

    #MoonBit Motion Lab

    MoonBit Motion Lab is a motion-curve quality-assurance and deterministic timeline toolkit for MoonBit. It starts after an application has selected a curve, whether the function was written locally or supplied by a separate easing package.

    It deliberately does not publish named easing equations, CSS easing presets, spring/back formulas, or a cubic-Bezier curve factory. That is the responsibility of an easing library. Motion Lab evaluates the resulting MotionFn against product constraints, generates reproducible numeric fixtures, and compiles renderer-independent value timelines.

    #What it provides

    • the shared MotionFn function contract for caller-owned curves
    • deterministic sampling, interpolation, local velocity, monotonicity, and overshoot measurements
    • CurveReport numerical diagnostics: min/max, maximum speed, peak-speed time, monotonicity, and endpoint error
    • CurvePolicy and check for explicit acceptance requirements: endpoint tolerance, monotonicity, overshoot, and speed limits
    • MotionTimeline for sequential value transitions and fixed-rate frame generation

    #Quick start

    let smoothstep = fn(t : Double) -> Double { t * t * (3.0 - 2.0 * t) }
    let policy = @motion.CurvePolicy::strict()
    let result = @motion.check(smoothstep, 120, policy)

    let timeline = @motion.MotionTimeline::new()
    timeline.append(0.0, 100.0, 0.6, smoothstep)
    timeline.append(100.0, 160.0, 0.4, smoothstep)
    let frames = timeline.frames(60)

    The function may instead come from another package:

    let selected_curve = fn(t : Double) -> Double { /* invoke an external easing function */ t }
    let report = @motion.profile(selected_curve, 120)

    #Project boundary

    Zlj6566/moonbit-easing and comparable packages own the selection and implementation of easing formulas. Motion Lab owns curve inspection, acceptance checking, deterministic numeric output, and timeline compilation. It is therefore useful when a project needs to prove a selected curve meets a product constraint or needs reproducible values for a renderer, golden test, or offline pipeline.

    Out of scope:

    • standard or named easing-function catalogues
    • CSS ease, ease-in, ease-out, or ease-in-out aliases
    • spring, back, bounce, elastic, or cubic-Bezier formula implementations
    • DOM manipulation, rendering, animation scheduling, or runtime loops

    #Verification

    moon fmt --check moon check moon test moon build moon run ./examples/basic

    #License

    Apache-2.0. See LICENSE.

    MotionFn

    type MotionFn = (Double) -> Double

    A normalized motion curve supplied by the caller.

    Motion Lab does not provide a catalogue of easing equations. An application or another package can pass any function mapping normalized progress to a value for sampling, profiling, and timeline compilation.

    CurveCheck

    pub struct CurveCheck {
    report : CurveReport
    overshoot : Double
    endpoints_ok : Bool
    monotonic_ok : Bool
    overshoot_ok : Bool
    speed_ok : Bool
    passed : Bool
    }

    Deterministic result of checking a curve against a CurvePolicy.

    CurvePolicy

    pub struct CurvePolicy {
    endpoint_tolerance : Double
    require_monotonic : Bool
    max_overshoot : Double
    max_speed : Double
    }

    Acceptance limits for a motion curve.

    A negative max_speed disables the speed limit. max_overshoot is the largest permitted distance outside the normalized [0, 1] range.

    CurvePolicy::strict

    fn CurvePolicy::strict() -> CurvePolicy

    A practical default for curves that must stay in range and finish exactly.

    CurveReport

    pub struct CurveReport {
    min_value : Double
    max_value : Double
    max_speed : Double
    time_of_max_speed : Double
    monotonic : Bool
    endpoint_error : Double
    }

    Numerical summary of a normalized motion curve.

    MotionSegment

    pub struct MotionSegment {
    start : Double
    end : Double
    duration : Double
    motion : (Double) -> Double
    }

    One value transition in a sequential motion timeline.

    MotionTimeline

    pub struct MotionTimeline {
    segments : Array[MotionSegment]
    }

    A deterministic, renderer-independent sequence of motion segments.

    MotionTimeline::append

    fn MotionTimeline::append(self : MotionTimeline, start : Double, end : Double, duration : Double, motion : (Double) -> Double) -> Unit

    Add a segment. Non-positive durations are ignored during playback.

    MotionTimeline::duration

    fn MotionTimeline::duration(self : MotionTimeline) -> Double

    Sum the usable durations in this timeline.

    MotionTimeline::frames

    fn MotionTimeline::frames(self : MotionTimeline, fps : Int) -> Array[Double]

    Produce timeline values at a fixed frame rate.

    MotionTimeline::new

    Create an empty motion timeline.

    MotionTimeline::value_at

    fn MotionTimeline::value_at(self : MotionTimeline, time : Double) -> Double

    Evaluate the timeline at elapsed time. An empty timeline evaluates to zero.

    check

    fn check(motion : (Double) -> Double, samples : Int, policy : CurvePolicy) -> CurveCheck

    Check a curve against explicit product requirements.

    clamp01

    fn clamp01(value : Double) -> Double

    Clamp a value to the normalized animation interval.

    frames

    fn frames(start : Double, end : Double, count : Int, motion : (Double) -> Double) -> Array[Double]

    Generate interpolated application values from a motion curve.

    interpolate

    fn interpolate(start : Double, end : Double, t : Double, motion : (Double) -> Double) -> Double

    Map normalized motion progress onto an application value range.

    is_monotonic

    fn is_monotonic(motion : (Double) -> Double, samples : Int) -> Bool

    Check whether sampled values never decrease.

    max_overshoot

    fn max_overshoot(motion : (Double) -> Double, samples : Int) -> Double

    Return the largest amount by which a curve exceeds [0, 1].

    profile

    fn profile(motion : (Double) -> Double, samples : Int) -> CurveReport

    Profile a curve using a deterministic number of samples.

    sample

    fn sample(motion : (Double) -> Double, count : Int) -> Array[Double]

    Sample a motion curve at evenly spaced points, including both endpoints.

    stitch

    fn stitch(first : (Double) -> Double, second : (Double) -> Double, split : Double) -> ((Double) -> Double)

    Join two normalized motions at split.

    velocity

    fn velocity(motion : (Double) -> Double, t : Double, epsilon : Double) -> Double

    Estimate local velocity with a centered finite difference.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io