gesture_physics_animator 0.1.1
gesture_physics_animator: ^0.1.1 copied to clipboard
Velocity-seeded spring physics for draggable widgets: real momentum, elastic boundary bouncing, and configurable damping — not a tween-based "snap back."
import 'package:flutter/material.dart';
import 'app_theme.dart';
import 'pages/bounded_page.dart';
import 'pages/free_drag_page.dart';
import 'pages/snap_dock_page.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'gesture_physics_animator',
debugShowCheckedModeBanner: false,
theme: AppTheme.light(),
darkTheme: AppTheme.dark(),
home: const _Home(),
);
}
}
class _Home extends StatefulWidget {
const _Home();
@override
State<_Home> createState() => _HomeState();
}
class _HomeState extends State<_Home> {
int _index = 0;
static const _pages = [FreeDragPage(), BoundedPage(), SnapDockPage()];
static const _titles = ['Free drag', 'Bounded', 'Snap dock'];
@override
Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [scheme.primary, scheme.tertiary],
),
),
child: const Icon(Icons.blur_on, size: 18, color: Colors.white),
),
const SizedBox(width: 12),
Text(_titles[_index]),
],
),
),
body: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [scheme.surface, scheme.surfaceContainerLow],
),
),
child: IndexedStack(index: _index, children: _pages),
),
bottomNavigationBar: NavigationBar(
selectedIndex: _index,
onDestinationSelected: (i) => setState(() => _index = i),
destinations: const [
NavigationDestination(
icon: Icon(Icons.open_with_outlined),
selectedIcon: Icon(Icons.open_with),
label: 'Free drag',
),
NavigationDestination(
icon: Icon(Icons.crop_free_outlined),
selectedIcon: Icon(Icons.crop_free),
label: 'Bounded',
),
NavigationDestination(
icon: Icon(Icons.dock_outlined),
selectedIcon: Icon(Icons.dock),
label: 'Snap dock',
),
],
),
);
}
}