import 'package:cue/cue.dart'; import 'package:flutter/material.dart'; class SmoothSwitch extends StatefulWidget { const SmoothSwitch({super.key}); @override State createState() => _SmoothSwitchState(); } class _SmoothSwitchState extends State { bool _toggled = false; @override Widget build(BuildContext context) { final theme = Theme.of(context); final height = 44.0; final width = height * 2; final trackColor = Colors.grey.shade800; final thumbColor = theme.colorScheme.onSurface; const duration = Duration(milliseconds: 300); return Cue.onToggle( toggled: _toggled, motion: .linear(duration), child: GestureDetector( onTap: () { setState(() { _toggled = !_toggled; }); }, child: Actor( acts: [ ScaleAct.keyframed( frames: .fractional([ .key(1.1, at: .4), .key(1.1, at: .6), .key(1.0, at: 1.0), ]), ), ], child: Container( width: width, height: height, decoration: BoxDecoration( color: trackColor, borderRadius: .circular(32), boxShadow: [ BoxShadow( color: theme.colorScheme.shadow.withValues(alpha: .1), blurRadius: 12, offset: Offset(0, 6), ), ], ), child: Stack( fit: .expand, children: [ PositionedActor.keyframed( frames: .fractional([ .key(Position.fill(end: .5), at: .0), .key(Position.fill(end: 0, top: .15, bottom: .15), at: .45), .key(Position.fill(end: 0, top: .15, bottom: .15), at: .55), .key(Position.fill(start: .5), at: 1.0), ]), relativeTo: Size(width, height), child: DecoratedBox( decoration: BoxDecoration( color: thumbColor, borderRadius: .circular(32), ), ), ), Row( children: [ Expanded( child: DecoratedBoxActor( shape: .circle, color: .tween(trackColor, thumbColor), motion: .linear(duration * .5), reverse: .mirror(delay: duration * .5), child: SizedBox.square(dimension: width * .16), ), ), Expanded( child: Center( child: DecoratedBoxActor( color: .tween(thumbColor, trackColor), borderRadius: .tween(.circular(width * .2), .circular(width * .2)), motion: .linear(duration * .5), delay: duration * .5, child: SizedBox(width: width * .08, height: width * .22), ), ), ), ], ), ], ), ), ), ), ); } }