Skip to content

repeat, yoyo, steps easing, and a declarative camera shake #330

Description

@LeadcodeDev

Part of #326. Batch 2 — depends on #336 for TimePoint.

Reproducing the reel's camera shake took 155 sampled camera keyframes, generated by a Python loop evaluating a damped sine. GSAP writes the same motion as {x: 7, duration: .035, repeat: 11, yoyo: true}. AnimationTiming.repeat is a bool with no count, there is no yoyo, and EasingType has no steps, so a blinking caret and an oscillating offset both have to be spelled out keyframe by keyframe.

Owned files

  • crates/rustmotion-core/src/schema/animation.rs (EasingType::Steps, repeat widening)
  • crates/rustmotion-core/src/schema/video.rs (AnimationTiming)
  • crates/rustmotion-core/src/schema/shake.rs (new), crates/rustmotion-core/src/engine/shake.rs (new)
  • crates/rustmotion-core/src/engine/animator.rs (modifier resolution — coordinate with Animate scalars that other attributes derive from #329, which owns variable tracks in the same file)

Do NOT write: schema/scenario.rs (#336 registers Scene.shake), cli/commands/geometry.rs (#334).

Deliverables

  1. repeat: n — an integer count, with true still meaning infinite. This widens an existing bool, so the deserializer accepts both forms and nothing breaks.

  2. yoyo: bool and repeat_delay, on any animation rather than on a fixed set of presets.

  3. EasingType::Steps(n) — the blinking caret and anything else that must jump rather than interpolate.

  4. Scene.shake — { impacts: [{ at, amplitude }], decay, frequency, rotation }, where at is a TimePoint so impacts can be written on the beat grid. Additive over camera, so a pan and a shake coexist rather than fighting over the same keyframe track.

  5. PostEffect::Flash { at, color, intensity, duration }, which costs almost nothing once impacts exist and is what the reference reel pairs with every impact.

Acceptance

  • A six-impact shake written as six {at, amplitude} pairs replaces 155 hand-generated keyframes and renders the same motion
  • repeat: true on an existing scenario behaves exactly as it does today
  • A caret on steps(1) holds each state rather than fading between them

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions