lerp static method

Linearly interpolates between two partial overrides.

Because every field is an optional override, interpolation has to respect the meaning of null ("use the widget's own default") rather than treating it as zero:

  • When a field is non-null on both sides it is smoothly interpolated.
  • When a field is null on either side it switches discretely at the midpoint (t < 0.5 keeps a's value, otherwise b's). Interpolating against an unknown widget default would produce a visible flash through zero.
  • specularSharpness and lensModel are enums and always switch at the midpoint.

Returns null when both a and b are null. Used by GlassThemeVariant.lerp to cross-fade between light and dark theme variants during content-aware brightness flips.

Implementation

static GlassThemeSettings? lerp(
  GlassThemeSettings? a,
  GlassThemeSettings? b,
  double t,
) {
  if (identical(a, b)) return a;
  if (a == null || b == null) return t < 0.5 ? a : b;
  return GlassThemeSettings(
    visibility: _lerpDoubleField(a.visibility, b.visibility, t),
    glassColor: _lerpColorField(a.glassColor, b.glassColor, t),
    thickness: _lerpDoubleField(a.thickness, b.thickness, t),
    blur: _lerpDoubleField(a.blur, b.blur, t),
    frost: _lerpDoubleField(a.frost, b.frost, t),
    frostOpacity: _lerpDoubleField(a.frostOpacity, b.frostOpacity, t),
    frostClamp: _lerpDoubleField(a.frostClamp, b.frostClamp, t),
    frostWeight: _lerpDoubleField(a.frostWeight, b.frostWeight, t),
    blurWeight: _lerpDoubleField(a.blurWeight, b.blurWeight, t),
    chromaticAberration:
        _lerpDoubleField(a.chromaticAberration, b.chromaticAberration, t),
    lightAngle: _lerpDoubleField(a.lightAngle, b.lightAngle, t),
    lightIntensity: _lerpDoubleField(a.lightIntensity, b.lightIntensity, t),
    ambientStrength:
        _lerpDoubleField(a.ambientStrength, b.ambientStrength, t),
    fresnelStrength:
        _lerpDoubleField(a.fresnelStrength, b.fresnelStrength, t),
    refractiveIndex:
        _lerpDoubleField(a.refractiveIndex, b.refractiveIndex, t),
    saturation: _lerpDoubleField(a.saturation, b.saturation, t),
    specularSharpness: t < 0.5 ? a.specularSharpness : b.specularSharpness,
    edgeAbsorption: _lerpDoubleField(a.edgeAbsorption, b.edgeAbsorption, t),
    rimShade: _lerpDoubleField(a.rimShade, b.rimShade, t),
    rimShadeEnds: _lerpDoubleField(a.rimShadeEnds, b.rimShadeEnds, t),
    rimLight: _lerpDoubleField(a.rimLight, b.rimLight, t),
    bodyShade: _lerpDoubleField(a.bodyShade, b.bodyShade, t),
    lensModel: t < 0.5 ? a.lensModel : b.lensModel,
  );
}