A small model controlling crosshair spread for an FPS UI. It uses a SpringFloat to animate a spread value 0..1, exposes CurrentGap for rendering, allows setting sustained spread and adding transient kick on fire, and advances animation via Tick.
using System;
using Goo.Animation;
namespace Goo.FpsUI;
// Crosshair spread logic: a spring 0..1 settling toward a sustained target (movement) with
// transient kicks on fire. The view reads CurrentGap. Engine-free.
public sealed class CrosshairModel
{
public float Gap = 6f; // base center gap in px (still, no spread)
public float SpreadScale = 14f; // px added at full spread (0 = fixed-gap crosshair)
SpringFloat _spread = new( 0f, 12f, 0.7f ); // 0..1 spread amount
public float Spread => Math.Clamp( _spread.Current, 0f, 1.5f ); // animated spread 0..1
public float CurrentGap => Gap + Spread * SpreadScale; // gap the view draws with
public void SetSpread( float t ) => _spread.Target = Math.Clamp( t, 0f, 1f ); // sustained (e.g. while moving)
public void Fire() => _spread.Current = MathF.Min( 1.5f, _spread.Current + 0.5f ); // transient kick
public bool Tick( float dt ) => _spread.Tick( dt );
}