morphLandingBump function

({Offset kick, double scaleX, double scaleY}) morphLandingBump({
  1. required double value,
  2. required Offset impactAxis,
  3. required double bumpScale,
  4. required double bumpRecoil,
})

The landing bump: one set of formulas for every consumer (the MorphTag content transform and the liquid-skin rect deformation). Full-wave: it lives on the FULL spring value - a dip below zero gives squash along the impact axis, a slight stretch across it, and a recoil kick; the return into positive plays the reverse. A degenerate axis falls back to vertical.

Implementation

({double scaleX, double scaleY, Offset kick}) morphLandingBump({
  required double value,
  required Offset impactAxis,
  required double bumpScale,
  required double bumpRecoil,
}) {
  final Offset axis = impactAxis.distance < 1 ? const Offset(0, 1) : impactAxis;
  final bool vertical = axis.dy.abs() >= axis.dx.abs();
  final double along = 1 + value * bumpScale;
  final double across = 1 - value * bumpScale * 0.45;
  final Offset unit = axis / axis.distance;
  return (
    scaleX: vertical ? across : along,
    scaleY: vertical ? along : across,
    kick: unit * (-value * bumpRecoil),
  );
}