@@ -105,6 +105,8 @@ class FortuneBar extends StatefulWidget implements FortuneWidget {
105105class _FortuneBarState extends State <FortuneBar >
106106 with SingleTickerProviderStateMixin {
107107 late FortuneAnimationManager _animationManager;
108+ double _scrollWeightOffset = 0 ;
109+ int _previousIndex = 0 ;
108110
109111 @override
110112 void initState () {
@@ -118,15 +120,58 @@ class _FortuneBarState extends State<FortuneBar>
118120 onAnimationEnd: () => widget.onAnimationEnd? .call (),
119121 );
120122
123+ _animationManager.selectedIndex.addListener (_handleSelectionChange);
124+
121125 if (widget.animateFirst) {
122126 WidgetsBinding .instance! .addPostFrameCallback ((_) {
123127 _animationManager.animate ();
124128 });
125129 }
126130 }
127131
132+ void _handleSelectionChange () {
133+ final oldIndex = _previousIndex;
134+ final newIndex = _animationManager.selectedIndex.value;
135+
136+ final currentRotation = _animationManager.animation.value;
137+ final totalWeight = _getTotalWeight ();
138+
139+ final oldTarget = _getItemCenterWeight (oldIndex);
140+ final oldTotalWeight = widget.rotationCount * totalWeight + oldTarget;
141+
142+ // Use previous interpolation logic to reconstruct where we are.
143+ // oldScrollWeight = _scrollWeightOffset * (1 - t) + t * oldTotalWeight
144+
145+ final oldScrollWeight = _scrollWeightOffset * (1 - currentRotation) + currentRotation * oldTotalWeight;
146+
147+ final newTarget = _getItemCenterWeight (newIndex);
148+ // newTotalWeight = widget.rotationCount * totalWeight + newTarget;
149+ // newScrollWeight(0) = _newOffset * (1-0) + 0 * ... = _newOffset.
150+
151+ // We want oldScrollWeight = newScrollWeight(0) = _newOffset.
152+
153+ _scrollWeightOffset = oldScrollWeight;
154+ _previousIndex = newIndex;
155+ }
156+
157+ double _getTotalWeight () {
158+ return widget.items.fold <double >(0 , (p, e) => p + e.weight);
159+ }
160+
161+ double _getItemCenterWeight (int index) {
162+ if (index < 0 || index >= widget.items.length) return 0 ;
163+
164+ double targetCenterWeight = 0 ;
165+ for (int i = 0 ; i < index; i++ ) {
166+ targetCenterWeight += widget.items[i].weight;
167+ }
168+ targetCenterWeight += widget.items[index].weight / 2 ;
169+ return targetCenterWeight;
170+ }
171+
128172 @override
129173 void dispose () {
174+ _animationManager.selectedIndex.removeListener (_handleSelectionChange);
130175 _animationManager.dispose ();
131176 super .dispose ();
132177 }
@@ -164,8 +209,7 @@ class _FortuneBarState extends State<FortuneBar>
164209 );
165210
166211 // Calculate weights and dimensions
167- final totalWeight =
168- widget.items.fold <double >(0 , (p, e) => p + e.weight);
212+ final totalWeight = _getTotalWeight ();
169213 final avgWeight = totalWeight / widget.items.length;
170214 final visibleWeight = widget.visibleItemCount * avgWeight;
171215 final unitWidth = size.width / visibleWeight;
@@ -179,11 +223,7 @@ class _FortuneBarState extends State<FortuneBar>
179223 builder: (context, _) {
180224 // Calculate Target
181225 final selectedIndex = _animationManager.selectedIndex.value;
182- double targetCenterWeight = 0 ;
183- for (int i = 0 ; i < selectedIndex; i++ ) {
184- targetCenterWeight += widget.items[i].weight;
185- }
186- targetCenterWeight += widget.items[selectedIndex].weight / 2 ;
226+ final targetCenterWeight = _getItemCenterWeight (selectedIndex);
187227
188228 final targetTotalScrollWeight =
189229 widget.rotationCount * totalWeight + targetCenterWeight;
@@ -198,8 +238,11 @@ class _FortuneBarState extends State<FortuneBar>
198238 final isAnimatingPanFactor = isAnimating ? 0 : 1 ;
199239
200240 // Current Scroll Weight
201- final currentScrollWeight = _animationManager.animation.value *
202- targetTotalScrollWeight +
241+ // Logic: _scrollWeightOffset * (1 - t) + t * targetTotalScrollWeight
242+
243+ final animationValue = _animationManager.animation.value;
244+ final currentScrollWeight = _scrollWeightOffset * (1 - animationValue) +
245+ animationValue * targetTotalScrollWeight +
203246 panWeight * isAnimatingPanFactor;
204247
205248 final scrollOffset = currentScrollWeight * unitWidth;
0 commit comments