button_punch.dart 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:trackoffical_app/generated/assets.dart';
  4. import 'package:trackoffical_app/service/app.dart';
  5. import 'package:trackoffical_app/view/ingame/in_game_controller.dart';
  6. import 'package:rive/rive.dart';
  7. import 'package:vibration/vibration.dart';
  8. class ButtonPunch extends StatefulWidget {
  9. const ButtonPunch({
  10. super.key,
  11. required this.onPressed,
  12. required this.isWarn,
  13. });
  14. final VoidCallback? onPressed;
  15. final bool isWarn;
  16. @override
  17. State<StatefulWidget> createState() {
  18. return ButtonPunchState();
  19. }
  20. }
  21. class ButtonPunchState extends State<ButtonPunch>
  22. with SingleTickerProviderStateMixin {
  23. late AnimationController _animationController;
  24. late Animation<Color?> _animation;
  25. var _isActive = true;
  26. @override
  27. void initState() {
  28. super.initState();
  29. _animationController = AnimationController(
  30. vsync: this,
  31. duration: const Duration(milliseconds: 500),
  32. reverseDuration: const Duration(milliseconds: 500),
  33. )..repeat(reverse: true);
  34. _animation = ColorTween(begin: Colors.white, end: Colors.red)
  35. .animate(_animationController)
  36. ..addListener(() {
  37. setState(() {
  38. // The state that has changed here is the animation object’s value.
  39. });
  40. });
  41. loopVibration();
  42. }
  43. Future<void> loopVibration() async{
  44. final c = Get.find<InGameController>();
  45. while(_isActive){
  46. await Future.delayed(500.milliseconds);
  47. if(widget.isWarn && c.isEnableGameVibrate.value){
  48. if (await Vibration.hasCustomVibrationsSupport()==true) {
  49. Vibration.vibrate(duration: 100, repeat: 1);
  50. } else {
  51. Vibration.vibrate();
  52. }
  53. }
  54. }
  55. }
  56. @override
  57. void didUpdateWidget(covariant ButtonPunch oldWidget) {
  58. super.didUpdateWidget(oldWidget);
  59. final oldEnabled = oldWidget.onPressed != null;
  60. final newEnabled = widget.onPressed != null;
  61. if (oldEnabled != newEnabled) {
  62. if (newEnabled) {
  63. _animationController.repeat(reverse: true);
  64. } else {
  65. _animationController.stop();
  66. }
  67. }
  68. }
  69. @override
  70. void dispose() {
  71. _animationController.dispose();
  72. _isActive=false;
  73. super.dispose();
  74. }
  75. @override
  76. Widget build(BuildContext context) {
  77. final image = widget.onPressed != null? 'assets/images/btn_punch.png': 'assets/images/btn_punch_disable.png';
  78. final boxShadow = <BoxShadow>[];
  79. final children = <Widget>[];
  80. if(widget.isWarn){
  81. boxShadow.add(BoxShadow(
  82. color: Colors.red.withAlpha(150),
  83. offset: const Offset(0.0, 0.0), //阴影y轴偏移量
  84. blurRadius: 6, //阴影模糊程度
  85. spreadRadius: widget.onPressed!= null? 2: 1 //阴影扩散程度
  86. ));
  87. children.add(const RiveAnimation.asset(Assets.imagesAmPunchButtonFlash, fit: BoxFit.fill));
  88. }else{
  89. boxShadow.add(BoxShadow(
  90. color: Colors.grey.withAlpha(150),
  91. offset: const Offset(2.0, 2.0), //阴影y轴偏移量
  92. blurRadius: 6, //阴影模糊程度
  93. spreadRadius: widget.onPressed!= null? 5: 1 //阴影扩散程度
  94. ));
  95. }
  96. children.add(GestureDetector(
  97. onTap: widget.onPressed,
  98. child: Container(
  99. width: 56,
  100. height: 56,
  101. decoration: BoxDecoration(
  102. color: Colors.white,
  103. image: DecorationImage(
  104. image: AssetImage(image)),
  105. borderRadius: BorderRadius.circular(28),
  106. boxShadow: boxShadow,
  107. ),
  108. ),
  109. ));
  110. return SizedBox(height: 90, width: 90, child: Stack(
  111. alignment: Alignment.center,
  112. children: children,
  113. ) ) ;
  114. // return GestureDetector(
  115. // onTap: widget.onPressed,
  116. // child: Container(
  117. // width: 56,
  118. // height: 56,
  119. // decoration: BoxDecoration(
  120. // color: Colors.white,
  121. // image: DecorationImage(
  122. // image: AssetImage(image)),
  123. // borderRadius: BorderRadius.circular(28),
  124. // boxShadow: [
  125. // BoxShadow(
  126. // color: widget.isWarn? _animation.value ?? Colors.grey: Colors.grey.withAlpha(150),
  127. // offset: widget.isWarn? const Offset(0, 0):const Offset(2.0, 2.0), //阴影y轴偏移量
  128. // blurRadius: 6, //阴影模糊程度
  129. // spreadRadius: widget.onPressed!= null? 5: 1 //阴影扩散程度
  130. // )
  131. // ],
  132. // ),
  133. // ),
  134. // );
  135. }
  136. }
  137. void main() async {
  138. runApp(Container(
  139. color: Colors.white,
  140. child: Column(
  141. children: [
  142. const Spacer(),
  143. ButtonPunch(
  144. onPressed: () { },
  145. isWarn: false,
  146. )
  147. ],
  148. ) )
  149. ) ;
  150. }