Skip to content

Commit 27d1e24

Browse files
committed
🔧 Update Pack 2 #15
1 parent 8df9b36 commit 27d1e24

File tree

7 files changed

+99
-148
lines changed

7 files changed

+99
-148
lines changed

example/lib/main.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import 'package:hyper_effects_demo/stories/counter_app.dart';
1010
import 'package:hyper_effects_demo/stories/group_animation.dart';
1111
import 'package:hyper_effects_demo/stories/one_shot_reset_animation.dart';
1212
import 'package:hyper_effects_demo/stories/rolling_app_bar_animation.dart';
13-
import 'package:hyper_effects_demo/stories/rolling_widget_animation.dart';
14-
import 'package:hyper_effects_demo/stories/scroll_phase_transition.dart';
15-
import 'package:hyper_effects_demo/stories/scroll_wheel_blur.dart';
13+
import 'package:hyper_effects_demo/stories/rolling_pictures_animation.dart';
14+
import 'package:hyper_effects_demo/stories/scroll_phase_slide.dart';
15+
import 'package:hyper_effects_demo/stories/scroll_phase_blur.dart';
1616
import 'package:hyper_effects_demo/stories/scroll_wheel_transition.dart';
1717
import 'package:hyper_effects_demo/stories/shake_and_spring_animation.dart';
1818
import 'package:hyper_effects_demo/stories/success_card_animation.dart';

example/lib/stories/rolling_app_bar_animation.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class _RollingAppBarAnimationState extends State<RollingAppBarAnimation> {
3939
showSearchView = true;
4040
setState(() {});
4141
},
42+
onTapOutside: (event) {
43+
showSearchView = false;
44+
setState(() {});
45+
},
4246
),
4347
),
4448
KeyedSubtree(
@@ -59,8 +63,6 @@ class _RollingAppBarAnimationState extends State<RollingAppBarAnimation> {
5963
showSearchView ? AxisDirection.right : AxisDirection.left,
6064
slideOutDirection:
6165
showSearchView ? AxisDirection.right : AxisDirection.left,
62-
rollInBuilder: (context, child) => child.fadeIn(),
63-
rollOutBuilder: (context, child) => child.fadeOut(),
6466
)
6567
.clip(0)
6668
.animate(
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:hyper_effects/hyper_effects.dart';
3+
4+
class RollingWidgetAnimation extends StatefulWidget {
5+
const RollingWidgetAnimation({super.key});
6+
7+
@override
8+
State<RollingWidgetAnimation> createState() => _RollingWidgetAnimationState();
9+
}
10+
11+
class _RollingWidgetAnimationState extends State<RollingWidgetAnimation> {
12+
int counter = 0;
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return Center(
17+
child: Column(
18+
children: [
19+
(counter % 9 == 8
20+
? null
21+
: Image.asset(
22+
'assets/fashion/fashion_${counter % 9}.jpg',
23+
key: ValueKey(counter),
24+
height: 500 + (counter % 2 == 0 ? 0 : 100),
25+
cacheHeight: 500 + (counter % 2 == 0 ? 0 : 100),
26+
))
27+
.roll(
28+
slideInDirection: AxisDirection.up,
29+
slideOutDirection: AxisDirection.left,
30+
)
31+
.clip(0)
32+
.animate(
33+
trigger: counter,
34+
curve: Curves.easeInOutQuart,
35+
duration: const Duration(milliseconds: 500),
36+
),
37+
Align(
38+
alignment: Alignment.topCenter,
39+
child: ElevatedButton(
40+
onPressed: () {
41+
setState(() {
42+
counter++;
43+
});
44+
},
45+
child: const Text('Roll'),
46+
),
47+
),
48+
],
49+
),
50+
);
51+
}
52+
}

example/lib/stories/rolling_widget_animation.dart

Lines changed: 0 additions & 59 deletions
This file was deleted.
File renamed without changes.
File renamed without changes.

lib/src/effects/roll/roll_effect.dart

Lines changed: 40 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ typedef RollBuilder = Widget Function(
88
Widget child,
99
);
1010

11-
Widget _defaultRollInBuilder(BuildContext context, Widget child) => child;
12-
13-
Widget _defaultRollOutBuilder(BuildContext context, Widget child) => child;
14-
1511
/// Provides a extension method to apply an [RollEffect] to a [Widget].
1612
extension RollEffectExtension on Widget? {
1713
/// Applies an [RollEffect] to a [Widget] with the given [slideInDirection],
@@ -20,10 +16,7 @@ extension RollEffectExtension on Widget? {
2016
AxisDirection slideInDirection = AxisDirection.up,
2117
AxisDirection slideOutDirection = AxisDirection.up,
2218
double multiplier = 1,
23-
bool useSnapshots = true,
24-
bool rollInitially = false,
25-
RollBuilder? rollInBuilder,
26-
RollBuilder? rollOutBuilder,
19+
bool useSnapshots = false,
2720
}) =>
2821
EffectWidget(
2922
end: RollEffect(
@@ -32,9 +25,6 @@ extension RollEffectExtension on Widget? {
3225
slideOutDirection: slideOutDirection,
3326
multiplier: multiplier,
3427
useSnapshots: useSnapshots,
35-
rollInitially: rollInitially,
36-
rollInBuilder: rollInBuilder ?? _defaultRollInBuilder,
37-
rollOutBuilder: rollOutBuilder ?? _defaultRollOutBuilder,
3828
),
3929
child: this,
4030
);
@@ -63,28 +53,13 @@ class RollEffect extends Effect {
6353
/// may be sensitive.
6454
final bool useSnapshots;
6555

66-
/// Determines whether this effect starts from no widget and immediately rolls
67-
/// in the passed [child] immediately once triggered, or if this roll effect
68-
/// should only trigger if the [child] passed has changed from its initial
69-
/// or last state.
70-
final bool rollInitially;
71-
72-
/// The builder to use when rolling in the [Widget].
73-
final RollBuilder rollInBuilder;
74-
75-
/// The builder to use when rolling out the [Widget].
76-
final RollBuilder rollOutBuilder;
77-
7856
/// Creates a [RollEffect] with the given parameters.
7957
const RollEffect({
8058
required this.child,
8159
this.slideInDirection = AxisDirection.up,
8260
this.slideOutDirection = AxisDirection.up,
8361
this.multiplier = 1,
84-
this.useSnapshots = true,
85-
this.rollInitially = false,
86-
this.rollInBuilder = _defaultRollInBuilder,
87-
this.rollOutBuilder = _defaultRollOutBuilder,
62+
this.useSnapshots = false,
8863
});
8964

9065
@override
@@ -96,9 +71,6 @@ class RollEffect extends Effect {
9671
slideOutDirection: slideOutDirection,
9772
multiplier: multiplier,
9873
useSnapshots: useSnapshots,
99-
rollInitially: rollInitially,
100-
rollInBuilder: rollInBuilder,
101-
rollOutBuilder: rollOutBuilder,
10274
child: child,
10375
);
10476

@@ -109,9 +81,6 @@ class RollEffect extends Effect {
10981
slideOutDirection,
11082
multiplier,
11183
useSnapshots,
112-
rollInitially,
113-
rollInBuilder,
114-
rollOutBuilder,
11584
];
11685
}
11786

@@ -137,18 +106,6 @@ class RollingEffectWidget extends StatefulWidget {
137106
/// may be sensitive.
138107
final bool useSnapshots;
139108

140-
/// Determines whether this effect starts from no widget and immediately rolls
141-
/// in the passed [child] once triggered, or if this roll effect
142-
/// should only trigger if the [child] passed has changed from its initial
143-
/// or last state.
144-
final bool rollInitially;
145-
146-
/// The builder to use when rolling in the [Widget].
147-
final RollBuilder rollInBuilder;
148-
149-
/// The builder to use when rolling out the [Widget].
150-
final RollBuilder rollOutBuilder;
151-
152109
/// Creates a [RollingEffectWidget] with the given parameters.
153110
const RollingEffectWidget({
154111
super.key,
@@ -157,9 +114,6 @@ class RollingEffectWidget extends StatefulWidget {
157114
this.slideOutDirection = AxisDirection.up,
158115
this.multiplier = 1,
159116
this.useSnapshots = false,
160-
this.rollInitially = false,
161-
this.rollInBuilder = _defaultRollInBuilder,
162-
this.rollOutBuilder = _defaultRollOutBuilder,
163117
});
164118

165119
@override
@@ -173,16 +127,14 @@ class _RollingEffectWidgetState extends State<RollingEffectWidget> {
173127
int retainedWidgets = 0;
174128
Widget? oldChild;
175129

176-
late bool isInitialRoll = widget.rollInitially;
177-
178-
bool get canRoll => isInitialRoll || oldChild != null;
130+
bool canRoll = false;
179131

180132
@override
181133
void didUpdateWidget(covariant RollingEffectWidget oldWidget) {
182134
super.didUpdateWidget(oldWidget);
183135

184136
if (oldWidget.child?.key != widget.child?.key) {
185-
isInitialRoll = false;
137+
canRoll = true;
186138
if (widget.useSnapshots) {
187139
oldChild = SnapshotWidget(
188140
key: ValueKey(retainedWidgets++),
@@ -228,26 +180,18 @@ class _RollingEffectWidgetState extends State<RollingEffectWidget> {
228180
AxisDirection.left || AxisDirection.right => Offset(slideOutTime, 0),
229181
};
230182

231-
final child = widget.child == null
183+
final Widget? child = widget.child;
184+
185+
late final Widget? oldRoll = oldChild == null
232186
? null
233-
: widget.rollInBuilder(
234-
context,
235-
widget.child!,
187+
: FractionalTranslation(
188+
transformHitTests: false,
189+
translation: slideOutOffset * widget.multiplier,
190+
child: oldChild,
236191
);
237192

238-
final oldRoll = FractionalTranslation(
239-
transformHitTests: false,
240-
translation: slideOutOffset * widget.multiplier,
241-
child: oldChild == null
242-
? null
243-
: widget.rollOutBuilder(
244-
context,
245-
oldChild!,
246-
),
247-
);
248-
249-
late final double clampedTime = timeValue.clamp(0, 1);
250-
late final double reverseClampedTime = 1 - clampedTime;
193+
final double clampedTime = timeValue.clamp(0, 1);
194+
final double reverseClampedTime = 1 - clampedTime;
251195

252196
return AnimatedSize(
253197
duration: query?.duration ?? Duration.zero,
@@ -257,23 +201,35 @@ class _RollingEffectWidgetState extends State<RollingEffectWidget> {
257201
clipBehavior: Clip.none,
258202
alignment: Alignment.center,
259203
children: [
260-
if (oldChild != null)
261-
child == null
262-
? Align(
263-
heightFactor: reverseClampedTime,
264-
widthFactor: reverseClampedTime,
204+
if (oldRoll != null)
205+
// If the main child is null, then we can't use a Positioned.fill
206+
// widget to fill the entire space with the old roll because a stack
207+
// must have at least one non-positioned child. Use an Align widget
208+
// instead. The stack's size will be determined by the size of the
209+
// old rolling widget.
210+
if (child == null)
211+
Align(
212+
heightFactor: reverseClampedTime,
213+
widthFactor: reverseClampedTime,
214+
child: oldRoll,
215+
)
216+
else
217+
// If the main child is not null, then we can use a
218+
// Positioned.fill widget to fill the entire space with the old
219+
// roll. The stack's size will be determined by the size of the
220+
// main child, while this old roll is de-transitioned.
221+
// The FittedBox ensures that the oldRoll is laid out as if it
222+
// were the main child, unaffected by the main child's size.
223+
Positioned.fill(
224+
child: Align(
225+
heightFactor: reverseClampedTime,
226+
widthFactor: reverseClampedTime,
227+
child: FittedBox(
228+
fit: BoxFit.none,
265229
child: oldRoll,
266-
)
267-
: Positioned.fill(
268-
child: Align(
269-
heightFactor: reverseClampedTime,
270-
widthFactor: reverseClampedTime,
271-
child: FittedBox(
272-
fit: BoxFit.none,
273-
child: oldRoll,
274-
),
275-
),
276230
),
231+
),
232+
),
277233
if (child != null)
278234
FractionalTranslation(
279235
transformHitTests: false,

0 commit comments

Comments
 (0)