Skip to content

feat: add initialPhase and onPhaseUpdate parameters#35

Open
FinSchuiling wants to merge 2 commits intoben-fornefeld:mainfrom
FinSchuiling:feat/initial-phase-and-on-phase-update
Open

feat: add initialPhase and onPhaseUpdate parameters#35
FinSchuiling wants to merge 2 commits intoben-fornefeld:mainfrom
FinSchuiling:feat/initial-phase-and-on-phase-update

Conversation

@FinSchuiling
Copy link
Copy Markdown

Summary

Adds two optional parameters to AnimatedMeshGradient:

  • initialPhase (double?): When non-null, the animation starts from this phase value instead of 0. Useful for resuming from a previously saved state (e.g. restoring the gradient to exactly where it was when the user navigated away). Ignored if seed is set.

  • onPhaseUpdate (void Function(double)?): Called each tick with the current animation phase. Allows consumers to persist the phase value so they can later restore it via initialPhase, or display a static gradient at the paused position using seed.

Example usage

AnimatedMeshGradient(
  colors: myColors,
  options: myOptions,
  controller: _controller,
  initialPhase: _savedPhase,       // resume from saved position
  onPhaseUpdate: (phase) {
    _savedPhase = phase;           // track current position
  },
)

Note: This PR is based on fix/listener-and-ticker-restart (#34) which fixes listener cleanup and ticker restart bugs.

Test plan

  • Verify initialPhase: 5.0 starts the gradient visually offset (not from 0)
  • Verify onPhaseUpdate fires each tick with increasing phase values
  • Verify both parameters are ignored when seed is set
  • Verify passing neither parameter preserves existing behaviour (starts from 0, no callback)

🤖 Generated with Claude Code

fin and others added 2 commits February 15, 2026 21:52
…start

Two bugs fixed:

1. The anonymous closure added to controller.isAnimating was never removed
   in dispose(), causing stale callbacks (and potential setState-after-dispose
   crashes) when the widget is removed while the controller outlives it.

   Fix: store the listener reference in _controllerListener and remove it
   in dispose().

2. After calling _ticker.stop(), calling _ticker.start() again hits
   Flutter's "Ticker already started" assertion because a stopped Ticker
   cannot be restarted.

   Fix: when the controller requests animation to resume after a stop,
   create a fresh Ticker via _initTicker() instead of calling start() on
   the existing one.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- `initialPhase` (optional double): when non-null, the animation starts
  from this phase value instead of 0. Useful for resuming from a
  previously saved state. Ignored if `seed` is set.

- `onPhaseUpdate` (optional callback): called each tick with the current
  animation phase. Allows consumers to persist the phase so they can
  later restore it via `initialPhase` or display a static gradient at
  the paused position using `seed`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant