import 'dart:math'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../providers/settings_provider.dart'; class ShakeWidget extends StatefulWidget { final Widget child; final double shakeOffset; final int shakeCount; final Duration duration; const ShakeWidget({ super.key, required this.child, this.shakeOffset = 30.0, this.shakeCount = 3, this.duration = const Duration(milliseconds: 400), }); @override ShakeWidgetState createState() => ShakeWidgetState(); } class ShakeWidgetState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController(vsync: this, duration: widget.duration); _controller.addStatusListener((status) { if (status == AnimationStatus.completed) { _controller.reset(); } }); } @override void dispose() { _controller.dispose(); super.dispose(); } void shake() { _controller.forward(); } @override Widget build(BuildContext context) { // Read settings from provider (listen: false because we only read in build, // actually we want to listen to updates if settings change while looking at it? // But usually ShakeWidget is in BattleScreen. // However, the previous implementation used `widget.shakeCount` and `widget.shakeOffset`. // We should prefer provider values if available, or allow overrides? // The prompt says "shakeWidget에서 shakeCount, shakeOffset을 settings에서 설정할 수 있게 globalOption으로 설정해야해." // So we use Provider values. final settings = context.watch(); final shakeCount = settings.shakeCount; final shakeOffset = settings.shakeOffset; return AnimatedBuilder( animation: _controller, builder: (context, child) { final double sineValue = sin(shakeCount * 2 * pi * _controller.value); return Transform.translate( offset: Offset(sineValue * shakeOffset, 0), child: child, ); }, child: widget.child, ); } }