flutter_physics_ui 0.1.0 copy "flutter_physics_ui: ^0.1.0" to clipboard
flutter_physics_ui: ^0.1.0 copied to clipboard

Physics-based UI elements that respond to touch and gravity

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_physics_ui/flutter_physics_ui.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(final BuildContext context) => MaterialApp(
        title: 'Flutter Physics UI Demo',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
          useMaterial3: true,
        ),
        home: const PhysicsFeaturesPage(),
      );
}

class PhysicsFeaturesPage extends StatelessWidget {
  const PhysicsFeaturesPage({super.key});

  @override
  Widget build(final BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('Physics UI Features'),
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        ),
        body: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            // 1. Gravity Container (Moved to Top)
            const SectionHeader(title: '1. Gravity Container'),
            const SizedBox(height: 8),
            Container(
              height: 300,
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey.shade300),
                borderRadius: BorderRadius.circular(8),
              ),
              padding: const EdgeInsets.all(
                1,
              ), // Padding to keep physics inside border
              child: ClipRect(
                child: PhysicsContainer(
                  physics:
                      const PhysicsProperties(gravity: 300, restitution: 0.5),
                  child: Container(
                    width: 60,
                    height: 60,
                    decoration: const BoxDecoration(
                      color: Colors.purpleAccent,
                      shape: BoxShape.circle,
                    ),
                    child: const Center(
                      child: Icon(Icons.arrow_downward, color: Colors.white),
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(height: 8),
            const Text(
              'The circle interacts with the physics world defined by the '
              'container.',
              style: TextStyle(fontSize: 12, color: Colors.grey),
              textAlign: TextAlign.center,
            ),

            const Divider(height: 48),

            // 2. Physics Button
            const SectionHeader(
              title: '2. Physics Button (Restitution/Bounce)',
            ),
            const SizedBox(height: 8),
            Center(
              child: SizedBox(
                height: 120, // Providing height for the button to jump
                width: 200, // Constraining width
                child: PhysicsButton(
                  onPressed: () => debugPrint('Button Tapped'),
                  // Gravity enabled so it falls back down after jumping
                  physics:
                      const PhysicsProperties(restitution: 0.5, gravity: 300),
                  child: Container(
                    alignment: Alignment.center,
                    padding: const EdgeInsets.symmetric(
                      horizontal: 24,
                      vertical: 12,
                    ),
                    decoration: BoxDecoration(
                      color: Colors.blue, // Standard button color
                      borderRadius:
                          BorderRadius.circular(30), // Stadium/Pill shape
                      boxShadow: [
                        BoxShadow(
                          color: Colors.blue.withValues(alpha: 0.3),
                          blurRadius: 8,
                          offset: const Offset(0, 4),
                        ),
                      ],
                    ),
                    child: const Text(
                      'Bounce Me!',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
              ),
            ),

            const Divider(height: 48),

            // 3. Draggable Card
            const SectionHeader(title: '3. Draggable Card (Friction)'),
            const SizedBox(height: 8),
            Center(
              child: Container(
                // Visible Physics World
                width: 300,
                height: 200,
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey.shade400, width: 2),
                  borderRadius: BorderRadius.circular(12),
                  color: Colors.grey.shade50,
                ),
                padding: const EdgeInsets.all(
                  2,
                ), // Padding to keep physics inside border
                child: PhysicsCard(
                  // Gravity 0 for top-down view.
                  // High Restitution (0.9) to make it bounce off the walls!
                  physics: const PhysicsProperties(
                    friction: 0.05, // Low friction for sliding
                    mass: 5,
                    gravity: 0,
                    restitution: 0.9, // BOUNCE!
                  ),
                  child: Container(
                    width: 140, // Smaller card to have room to move
                    height: 90,
                    decoration: BoxDecoration(
                      color: Colors.orangeAccent,
                      borderRadius: BorderRadius.circular(16),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black.withValues(alpha: 0.2),
                          blurRadius: 10,
                          offset: const Offset(0, 5),
                        ),
                      ],
                    ),
                    child: const Center(
                      child: Text(
                        'Throw Me!',
                        style: TextStyle(
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      );
}

class SectionHeader extends StatelessWidget {
  const SectionHeader({required this.title, super.key});
  final String title;

  @override
  Widget build(final BuildContext context) => Text(
        title,
        style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
      );
}
2
likes
160
points
147
downloads

Publisher

verified publisherbechattaoui.dev

Weekly Downloads

Physics-based UI elements that respond to touch and gravity

Repository (GitHub)
View/report issues

Topics

#physics #ui #animation #widget #interaction

Documentation

API reference

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

flutter, flutter_physics_animation, meta

More

Packages that depend on flutter_physics_ui