Code/Demos/AnimationShowcase/Sections/FadePulseSection.cs
using Goo;
using Goo.Animation;
using Sandbox.UI;
using static Sandbox.DemoTokens;

namespace Sandbox.AnimationShowcase;

// Simplest case: one Timeline drives one property. Caller reads sample.Value
// and ignores SegmentIndex - the segment dispatch is internal to the choreography.
public class FadePulseSection
{
    const float BarW = 480f;
    const float BarH = 24f;

    static readonly Timeline FadePulse = Timeline.Sequence(
        new Tween( Easing.EaseOut, duration: 0.6f ),
        new Tween( t => 1f,        duration: 0.4f ),    // degenerate easing = hold at 1
        new Tween( Easing.EaseIn,  duration: 0.6f ).Reverse() );

    TimelineAnimator _anim = new( FadePulse ) { Elapsed = 999f };   // start past-end (settled)

    public void Update( float dt ) => _anim.Update( dt );

    public Container Build()
    {
        var sample = _anim.Sample;
        return Section.Build(
            "fade pulse - Fade in --> Hold --> Fade out",
            new Container
            {
                FlexDirection = FlexDirection.Column,
                Gap           = Space3,
                AlignItems    = Align.FlexStart,
                Children =
                {
                    ProgressBar.Build( BarW, BarH, sample.Value, Accent ),
                    CtrlButton.Build( "replay", _ => _anim.Restart() ),
                },
            } );
    }
}