buildJellyTransform static method
Creates a jelly transform matrix based on velocity.
Applies organic squash and stretch effects that create a satisfying "jelly" animation:
- Squashes in the direction of movement
- Stretches perpendicular to movement
- Intensity scales with velocity magnitude
This creates the iOS-style elastic effect seen when dragging indicators.
Parameters:
velocity: Direction and speed of movement as an OffsetmaxDistortion: Maximum distortion factor 0-1 (default: 0.7)velocityScale: Scale factor for velocity; higher = less distortion (default: 1000.0)
Returns: A Matrix4 transform that can be applied to a widget.
Example:
Transform(
alignment: Alignment.center,
transform: DraggableIndicatorPhysics.buildJellyTransform(
velocity: Offset(velocityX, 0),
maxDistortion: 0.8,
velocityScale: 10,
),
child: indicator,
)
Implementation
static Matrix4 buildJellyTransform({
required Offset velocity,
double maxDistortion = 0.7,
double velocityScale = 1000.0,
}) {
final speed = velocity.distance;
if (speed == 0) return Matrix4.identity();
// Normalize velocity direction
final direction = velocity / speed;
// Calculate distortion intensity based on speed
final distortionFactor =
(speed / velocityScale).clamp(0.0, 1.0) * maxDistortion;
// Squash in direction of movement
final squashX = 1.0 - (direction.dx.abs() * distortionFactor * 0.5);
final squashY = 1.0 - (direction.dy.abs() * distortionFactor * 0.5);
// Stretch perpendicular to movement
final stretchX = 1.0 + (direction.dy.abs() * distortionFactor * 0.3);
final stretchY = 1.0 + (direction.dx.abs() * distortionFactor * 0.3);
// Combine effects
final scaleX = squashX * stretchX;
final scaleY = squashY * stretchY;
return Matrix4.identity()..scale(scaleX, scaleY);
}