1

Import Libraries

Import the necessary libraries. dart:math provides random functions, and flutter/material.dart is essential for building Flutter UI components.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

import 'dart:math' as math;
import 'package:flutter/material.dart';
                                
2

Create the Main SwipeAndWin Widget

Define the main SwipeAndWin widget as a StatefulWidget to handle dynamic state changes during user interactions.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

class SwipeAndWin extends StatefulWidget {
    const SwipeAndWin({Key? key}) : super(key: key);
    
    @override
    State<SwipeAndWin> createState() => _SwipeAndWinState();
    }
3

Define the State and Animation Controller

Create private state variables to track drag position, game status, score, and messages. The AnimationController handles animations when the user interacts.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

class _SwipeAndWinState extends State<SwipeAndWin> with SingleTickerProviderStateMixin {
    late AnimationController _controller;
    double _dragPosition = 0;
    bool _isWon = false;
    int _score = 0;
    String _message = '';
    }
4

Initialize the Animation Controller

In initState, initialize _controller with an 800ms animation duration and add a listener to rebuild the widget whenever animation values change.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

@override
void initState() {
    super.initState();
    _controller = AnimationController(
    duration: const Duration(milliseconds: 800),
    vsync: this,
    );
    _controller.addListener(() => setState(() {}));
}
5

Dispose of the Animation Controller

Dispose of _controller in dispose() to release resources when the widget is removed from the widget tree.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

@override
void dispose() {
    _controller.dispose();
    super.dispose();
}
6

Handle User Dragging and Animation Triggering

_onDragUpdate updates _dragPosition while ensuring it’s within a range.
_onDragEnd checks if the drag was far enough to trigger the win condition, then randomly determines a win or loss. It also resets the drag position after animation.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

void _onDragUpdate(DragUpdateDetails details) {
    setState(() {
        _dragPosition += details.delta.dx;
        _dragPosition = _dragPosition.clamp(-180.0, 180.0); // Limit drag range
    });
    }
    
    void _onDragEnd(DragEndDetails details) {
    if (_dragPosition.abs() > 100) {
        final bool won = math.Random().nextBool();
        setState(() {
        _isWon = won;
        if (_isWon) {
            _score += 10;
            _message = 'πŸŽ‰ WIN! πŸŽ‰';
        } else {
            _message = math.Random().nextInt(3) == 0 ? 'Better luck next time!' : '😒 Try Again!';
        }
        });
        _controller.forward(from: 0.0);
    
        Future.delayed(const Duration(milliseconds: 800), () {
        if (mounted) {
            setState(() {
            _dragPosition = 0;
            });
        }
        });
    } else {
        setState(() {
        _dragPosition = 0;
        });
    }
    }
    

7

Build the UI Layout

Use Scaffold to set the background color and organize UI elements.
Add a GestureDetector to capture horizontal drag gestures and apply a 3D transformation based on _dragPosition.
An AnimatedBuilder widget dynamically animates the size and opacity changes based on the _controller values.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

@override
Widget build(BuildContext context) {
    return Scaffold(
    backgroundColor: Colors.blue[100],
    body: Center(
        child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
            Text(
            'Score: $_score',
            style: const TextStyle(
                fontSize: 20,
                fontWeight: FontWeight.bold,
                color: Colors.blue,
            ),
            ),
            const SizedBox(height: 10),
            const Text(
            'Swipe to Try Your Luck!',
            style: TextStyle(
                fontSize: 24,
                fontWeight: FontWeight.bold,
                color: Colors.blue,
            ),
            ),
            const SizedBox(height: 40),
            GestureDetector(
            onHorizontalDragUpdate: _onDragUpdate,
            onHorizontalDragEnd: _onDragEnd,
            child: Transform(
                transform: Matrix4.identity()
                ..setEntry(3, 2, 0.001)
                ..rotateY(_dragPosition / 180 * math.pi),
                alignment: Alignment.center,
                child: AnimatedBuilder(
                animation: _controller,
                builder: (context, child) {
                    return Transform.scale(
                    scale: 1.0 + (_controller.value * 0.2),
                    child: Opacity(
                        opacity: 1.0 - (_controller.value * 0.5),
                        child: Container(
                        width: 200,
                        height: 300,
                        decoration: BoxDecoration(
                            color: Colors.white,
                            borderRadius: BorderRadius.circular(16),
                            boxShadow: [
                            BoxShadow(
                                color: Colors.black.withOpacity(0.2),
                                blurRadius: 10,
                                offset: const Offset(0, 5),
                            ),
                            ],
                        ),
                        child: Center(
                            child: _controller.value > 0
                                ? Text(
                                    _message,
                                    style: TextStyle(
                                    fontSize: 24,
                                    fontWeight: FontWeight.bold,
                                    color: _isWon ? Colors.green : Colors.red,
                                    ),
                                )
                                : const Icon(
                                    Icons.card_giftcard,
                                    size: 80,
                                    color: Colors.blue,
                                ),
                        ),
                        ),
                    ),
                    );
                },
                ),
            ),
            ),
        ],
        ),
    ),
    );
}
                            
8

Run the App

Set up main() to run the SwipeAndWin widget inside MaterialApp and display it. This launches the swipe-to-win app.

πŸ’‘ Tip: Use the button on the right side to easily copy the code.

void main() {
    runApp(const MaterialApp(
        home: SwipeAndWin(),
    ));
    }                        
 
Step 1 of 8