slot_machine_effect 0.0.3
slot_machine_effect: ^0.0.3 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.
slot_machine_effect #
A slot machine reel for Flutter. Spins up, runs, drifts to a stop on the value you ask for, and rocks into place with a small bounce.
Usage #
SlotMachineReel(
height: 125,
width: 300,
values: const [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
target: 7,
itemBuilder: (value) => Center(child: Text('$value')),
)
values is everything on the reel, in order. target names one of those
entries — not an index — so the values need not be 0-9, contiguous, or
sorted.
The reel spins whenever target changes. It does not spin on load — it sits
on target until something moves it.
Starting on a placeholder #
Park the reel on a neutral face until a result arrives, with placeholder:
SlotMachineReel(
height: 125,
width: 300,
values: const [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1], // -1 is the blank
placeholder: -1, // shown until the first spin
target: result,
itemBuilder: (value) =>
Center(child: Text(value == -1 ? '?' : '$value')),
)
Without placeholder, the reel rests on target.
Several reels #
Stagger delay so they stop one after another, like a real machine:
Row(
children: [
for (var i = 0; i < digits.length; i++)
SlotMachineReel(
height: 100,
width: 60,
values: const [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
target: digits[i],
delay: Duration(milliseconds: 200 * i),
itemBuilder: (value) => Center(child: Text('$value')),
),
],
)
Custom symbols #
The values are just labels for the faces — map them to whatever you draw:
const cherry = 0, lemon = 1, bell = 2, seven = 3;
SlotMachineReel(
height: 100,
width: 100,
values: const [cherry, lemon, bell, seven],
target: bell,
itemBuilder: (value) => Icon(switch (value) {
cherry => Icons.star,
lemon => Icons.favorite,
bell => Icons.notifications,
_ => Icons.bolt,
}),
)
Properties #
| Property | Default | Description |
|---|---|---|
height, width |
required | Viewport size. height is also each item's extent. |
values |
required | Everything on the reel, in order. |
target |
required | Which entry of values to land on. Changing it spins the reel. |
itemBuilder |
required | Builds the widget for each entry of values. |
placeholder |
target |
Entry of values the reel rests on before its first spin. |
delay |
0ms |
Wait before spinning. Stagger this across reels. |
spinRate |
1.0 |
Speed multiplier. 2.0 is twice as fast. How long a spin takes follows from this and spins. |
spins |
3 |
Extra full loops before landing. |
reverse |
false |
Spin towards decreasing values instead. |
bounceExtent |
0.20 |
Overshoot past the target, as a fraction of height. 0 disables it. |
bounceDuration |
260ms |
How long the reel rocks back into place. |
diameterRatio |
4 |
Wheel curvature. Higher looks flatter. |
physics |
none | Scroll physics, if you want the reel draggable. |
onSpinStart |
— | Called when a spin begins, including the delay. |
onSettled |
— | Called once the reel rests on target. |
Notes #
- Spins are triggered by
targetchanging. Assigning the value it already holds is a no-op, so to land on the same symbol twice you need the value to change in between. The reel never spins on its own, including on load. - Spamming is safe. Requests arriving during a spin are ignored, so the
motion always runs to completion. Use
onSpinStart/onSettledto disable a button while it runs. - You set the pace, not the deadline.
spinRatefixes the speed andspinsfixes the distance, so the time a spin takes falls out of those two. Every reel then visibly moves at the same speed whatever its target, and a reel with further to go simply takes longer. If you need to know when a spin ends, useonSettledrather than assuming a duration.
Motion #
The spin is one continuous velocity profile integrated into position, rather than separate animations chained together, so there is no speed discontinuity between phases. Both ramps use smoothstep, which has zero slope at each end, so acceleration is continuous too. The wind-down carries slightly past the target and arrives at zero speed — where a real reel's overshoot peak is — and the bounce takes over from rest.