Spring
springPhysics-based spring motion driven by mass, stiffness, and damping.
Preview
Installation
Terminal
flutter pub add nib_motionUsage
dart
NibMotion(
initial: NibAnim(opacity: 0, y: 16),
animate: NibAnim(opacity: 1, y: 0),
transition: NibTransition(
spring: NibSpringDescription.wobbly,
),
child: MyWidget(),
)Examples
Spring Entrance
Physics-based spring entrance using mass, stiffness, and damping instead of a fixed duration.
dart
class SpringEntranceExample extends StatefulWidget {
const SpringEntranceExample({super.key});
@override
State<SpringEntranceExample> createState() => _SpringEntranceExampleState();
}
class _SpringEntranceExampleState extends State<SpringEntranceExample> {
final _signal = NibMotionReplaySignal();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF0D1117),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
NibMotionReplayScope(
signal: _signal,
child: NibMotion(
initial: const NibAnim(y: 60),
animate: const NibAnim(y: 0),
transition: NibTransition.springGentle,
child: Container(
width: 200,
height: 100,
decoration: BoxDecoration(
color: const Color(0xFF1C2537),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFF54C5F8).withAlpha(50)),
),
child: const Center(
child: Text(
'Spring Gentle',
style: TextStyle(color: Color(0xFFEDF2F7), fontSize: 16, fontWeight: FontWeight.w600),
),
),
),
),
),
const SizedBox(height: 24),
TextButton.icon(
onPressed: _signal.replay,
icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
),
],
),
),
);
}
}Wobbly Bounce
springWobbly overshoots and oscillates — great for playful UI like FABs or confirmations.
dart
class WobblyBounceExample extends StatefulWidget {
const WobblyBounceExample({super.key});
@override
State<WobblyBounceExample> createState() => _WobblyBounceExampleState();
}
class _WobblyBounceExampleState extends State<WobblyBounceExample> {
final _signal = NibMotionReplaySignal();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF0D1117),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
NibMotionReplayScope(
signal: _signal,
child: NibMotion(
initial: const NibAnim(scale: 0.0),
animate: const NibAnim(scale: 1.0),
transition: NibTransition.springWobbly,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: const Color(0xFF54C5F8),
borderRadius: BorderRadius.circular(20),
),
child: const Center(
child: Icon(Icons.check_rounded, color: Color(0xFF07080D), size: 40),
),
),
),
),
const SizedBox(height: 24),
TextButton.icon(
onPressed: _signal.replay,
icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
),
],
),
),
);
}
}Custom Spring
Full control over mass, stiffness, and damping with NibSpringDescription.
dart
class CustomSpringExample extends StatefulWidget {
const CustomSpringExample({super.key});
@override
State<CustomSpringExample> createState() => _CustomSpringExampleState();
}
class _CustomSpringExampleState extends State<CustomSpringExample> {
final _signal = NibMotionReplaySignal();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF0D1117),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
NibMotionReplayScope(
signal: _signal,
child: NibMotion(
initial: const NibAnim(y: 80),
animate: const NibAnim(y: 0),
transition: const NibTransition(
spring: NibSpringDescription(
mass: 1.0,
stiffness: 200.0,
damping: 16.0,
),
),
child: Container(
width: 200,
height: 100,
decoration: BoxDecoration(
color: const Color(0xFF1C2537),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFF54C5F8).withAlpha(50)),
),
child: const Center(
child: Text(
'Custom Spring',
style: TextStyle(color: Color(0xFFEDF2F7), fontSize: 15, fontWeight: FontWeight.w600),
),
),
),
),
),
const SizedBox(height: 8),
const Text(
'mass: 1.0 stiffness: 200 damping: 16',
style: TextStyle(color: Color(0xFF718096), fontSize: 11, fontFamily: 'monospace'),
),
const SizedBox(height: 16),
TextButton.icon(
onPressed: _signal.replay,
icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
),
],
),
),
);
}
}API Reference
API class
NibSpringDescriptionAPI Properties
massstiffnessdamping