@ -1,4 +1,5 @@
import ' dart:async ' ;
import ' dart:math ' ;
import ' package:flutter/material.dart ' ;
@ -29,6 +30,9 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
late AnimationController _controller ;
late Animation < Offset > _offsetAnimation ;
late Animation < double > _fadeAnimation ;
final List < Animation < double > > _swayAnimation = [ ] ;
final List < double > _randomSwayOffset = [ ] ;
final List < Offset > _particleTrajectories = [ ] ;
StreamSubscription ? _pointsSubscription ;
int ? get _prevXP = >
@ -37,17 +41,19 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
MatrixState . pangeaController . getAnalytics . constructListModel . totalXP ;
int ? _addedPoints ;
final Random _random = Random ( ) ;
@ override
void initState ( ) {
super . initState ( ) ;
_controller = AnimationController (
duration: const Duration ( seconds: 2 ) ,
duration: const Duration ( milli seconds: 2 000 ) ,
vsync: this ,
) ;
_offsetAnimation = Tween < Offset > (
begin: const Offset ( 0.0 , 0 .0 ) ,
end: const Offset ( 0.0 , - 1.0 ) ,
begin: const Offset ( 0.0 , 0 ) ,
end: const Offset ( 0.0 , - 3 ) ,
) . animate (
CurvedAnimation (
parent: _controller ,
@ -70,6 +76,42 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
. listen ( _showPointsGained ) ;
}
void initParticleTrajectories ( ) {
_particleTrajectories . clear ( ) ;
for ( int i = 0 ; i < ( _addedPoints ? . abs ( ) ? ? 0 ) ; i + + ) {
final angle = _random . nextDouble ( ) * ( pi / 2 ) +
pi / 4 ; / / Random angle in the V - shaped range .
const baseSpeed = 20 ; / / Initial base speed .
const exponentialFactor = 30 ; / / Factor for exponential growth .
final speedMultiplier = _random . nextDouble ( ) ; / / Random speed multiplier .
final speed = baseSpeed *
pow ( exponentialFactor , speedMultiplier ) ; / / Exponential speed .
_particleTrajectories
. add ( Offset ( speed * cos ( angle ) , - speed * sin ( angle ) ) ) ;
}
}
void initSwayAnimations ( ) {
_swayAnimation . clear ( ) ;
_randomSwayOffset . clear ( ) ;
initParticleTrajectories ( ) ;
for ( int i = 0 ; i < ( _addedPoints ? ? 0 ) ; i + + ) {
_swayAnimation . add (
Tween < double > (
begin: 0.0 ,
end: 2 * pi ,
) . animate (
CurvedAnimation (
parent: _controller ,
curve: Curves . linear ,
) ,
) ,
) ;
_randomSwayOffset . add ( _random . nextDouble ( ) * 2 * pi ) ;
}
}
@ override
void dispose ( ) {
_controller . dispose ( ) ;
@ -81,6 +123,7 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
if ( update . origin ! = widget . origin ) return ;
setState ( ( ) = > _addedPoints = ( _currentXP ? ? 0 ) - ( _prevXP ? ? 0 ) ) ;
if ( _prevXP ! = _currentXP ) {
initSwayAnimations ( ) ;
_controller . reset ( ) ;
_controller . forward ( ) ;
}
@ -98,19 +141,41 @@ class PointsGainedAnimationState extends State<PointsGainedAnimation>
final textColor = _addedPoints ! > 0 ? widget . gainColor : widget . loseColor ;
final plusWidget = Text (
_addedPoints ! > 0 ? " + " : " - " ,
style: BotStyle . text (
context ,
big: true ,
setColor: textColor = = null ,
existingStyle: TextStyle (
color: textColor ,
) ,
) ,
) ;
return SlideTransition (
position: _offsetAnimation ,
child: FadeTransition (
opacity: _fadeAnimation ,
child: Text (
' ${ _addedPoints ! > 0 ? ' + ' : ' ' } $ _addedPoints ' ,
style: BotStyle . text (
context ,
big: true ,
setColor: textColor = = null ,
existingStyle: TextStyle (
color: textColor ,
) ,
child: IgnorePointer (
ignoring: _controller . isAnimating ,
child: Stack (
children: List . generate ( _addedPoints ! . abs ( ) , ( index ) {
return AnimatedBuilder (
animation: _controller ,
builder: ( context , child ) {
final progress = _controller . value ;
final trajectory = _particleTrajectories [ index ] ;
return Transform . translate (
offset: Offset (
trajectory . dx * pow ( progress , 2 ) ,
trajectory . dy * pow ( progress , 2 ) ,
) ,
child: plusWidget ,
) ;
} ,
) ;
} ) ,
) ,
) ,
) ,