slot_machine_effect 0.0.5
slot_machine_effect: ^0.0.5 copied to clipboard
A slot machine reel for Flutter. Spins up, drifts to a stop on the value you ask for, and rocks into place with a small bounce.
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:slot_machine_effect/slot_machine_effect.dart';
void main() => runApp(const ExampleApp());
/// The blank face the reel parks on before the first spin. Not a digit, so
/// it cannot be confused with a result.
const _blank = -1;
/// Everything on the reel: the ten digits, plus the blank.
const _reelValues = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _blank];
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Slot Machine Effect',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const SlotMachineDemoPage(),
);
}
}
class SlotMachineDemoPage extends StatefulWidget {
const SlotMachineDemoPage({super.key});
@override
State<SlotMachineDemoPage> createState() => _SlotMachineDemoPageState();
}
class _SlotMachineDemoPageState extends State<SlotMachineDemoPage> {
final _random = Random();
// The reel shows the blank until the first spin.
final _controller = SlotMachineReelController(initialValue: _blank);
bool _spinning = false;
bool _spunOnce = false;
void _spin() {
setState(() => _spunOnce = true);
_controller.spin(_random.nextInt(10));
}
String get _status {
if (_spinning) return 'Spinning to ${_controller.value}…';
return _spunOnce ? 'Landed on ${_controller.value}' : 'Tap spin to start';
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Slot Machine Effect')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SlotMachineReel(
height: 125,
width: 300,
values: _reelValues,
controller: _controller,
bounceDuration: const Duration(milliseconds: 888),
onSpinStart: () => setState(() => _spinning = true),
onSettled: () => setState(() => _spinning = false),
itemBuilder: (e) => Container(
margin: const EdgeInsets.symmetric(vertical: 10),
height: 118.96,
width: 241,
alignment: Alignment.center,
decoration: const BoxDecoration(color: Colors.blue),
child: Text(
e == _blank ? '?' : '$e',
style: Theme.of(context).primaryTextTheme.headlineLarge
?.copyWith(color: Colors.white),
),
),
),
const SizedBox(height: 24),
Text(_status),
const SizedBox(height: 12),
ElevatedButton(
onPressed: _spinning ? null : _spin,
child: const Text('Spin'),
),
],
),
),
);
}
}