Files
Ensemble/lib/utils/page_transitions.dart
Your NameandClaude b6eaf01af5 perf: optimize animation curves for smoother hero transitions
- Upgrade fade animation curves: easeOut → easeOutCubic, easeIn → easeInCubic
- Upgrade forward slide curve to easeOutCubic for natural motion
- Upgrade reverse slide curve to easeInCubic for smooth deceleration

Cubic curves provide more natural, premium-feeling motion that better
matches Material Design 3 guidelines and apps like Symphonium.

Expected impact: Noticeably smoother and more natural page transitions
and hero animations

Implements AN-1 from performance audit

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 06:32:01 +00:00

65 lines
2.3 KiB
Dart

import 'package:flutter/material.dart';
/// A page route optimized for hero animations.
///
/// On forward navigation: fade in + slight slide from right
/// On back navigation: quick fade out + slide down
class FadeSlidePageRoute<T> extends PageRouteBuilder<T> {
final Widget child;
FadeSlidePageRoute({
required this.child,
}) : super(
pageBuilder: (context, animation, secondaryAnimation) => child,
transitionDuration: const Duration(milliseconds: 300),
reverseTransitionDuration: const Duration(milliseconds: 200), // Quick back animation
transitionsBuilder: (context, animation, secondaryAnimation, child) {
// Fade transition - uses optimized cubic curves for smoother hero animations
final fadeAnimation = CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
reverseCurve: Curves.easeInCubic,
);
// Check direction for slide
final isReverse = animation.status == AnimationStatus.reverse;
if (isReverse) {
// Back navigation: slide DOWN with easeInCubic for smooth deceleration
final slideAnimation = Tween<Offset>(
begin: const Offset(0, 0.08), // Slide down 8%
end: Offset.zero,
).animate(CurvedAnimation(
parent: animation,
curve: Curves.easeInCubic,
));
return FadeTransition(
opacity: fadeAnimation,
child: SlideTransition(
position: slideAnimation,
child: child,
),
);
} else {
// Forward navigation: slide from RIGHT with easeOutCubic for natural motion
final slideAnimation = Tween<Offset>(
begin: const Offset(0.05, 0), // Slide from right 5%
end: Offset.zero,
).animate(CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
));
return FadeTransition(
opacity: fadeAnimation,
child: SlideTransition(
position: slideAnimation,
child: child,
),
);
}
},
);
}