Skip to content

Commit 14adaac

Browse files
committed
🔧 Update Pack 2 #6
1 parent 3bfbe9b commit 14adaac

35 files changed

+914
-195
lines changed

example/lib/main.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:flutter/services.dart';
77
import 'package:flutter_box_transform/flutter_box_transform.dart';
88
import 'package:hyper_effects_demo/stories/color_filter_scroll_transition.dart';
99
import 'package:hyper_effects_demo/stories/counter_app.dart';
10+
import 'package:hyper_effects_demo/stories/group_animation.dart';
1011
import 'package:hyper_effects_demo/stories/one_shot_reset_animation.dart';
1112
import 'package:hyper_effects_demo/stories/rolling_widget_animation.dart';
1213
import 'package:hyper_effects_demo/stories/scroll_phase_transition.dart';
@@ -81,6 +82,10 @@ class Storyboard extends StatefulWidget {
8182

8283
class _StoryboardState extends State<Storyboard> with WidgetsBindingObserver {
8384
final List<Story> animationStories = [
85+
const Story(
86+
title: 'Group Animation',
87+
child: GroupAnimation(),
88+
),
8489
const Story(
8590
title: 'Text Rolling Animations',
8691
child: TextAnimation(),

example/lib/stories/counter_app.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ class _CounterAppState extends State<CounterApp> {
3434
'You have pushed the button this many times:',
3535
),
3636
Text(
37-
'${max(0, _counter - 1)}',
37+
'$_counter',
3838
style: Theme.of(context).textTheme.headlineMedium,
39-
).roll('$_counter').animate(trigger: _counter),
39+
).roll().animate(trigger: _counter),
4040
],
4141
),
4242
),
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:hyper_effects/hyper_effects.dart';
3+
4+
class GroupAnimation extends StatefulWidget {
5+
const GroupAnimation({super.key});
6+
7+
@override
8+
State<GroupAnimation> createState() => _GroupAnimationState();
9+
}
10+
11+
class _GroupAnimationState extends State<GroupAnimation> {
12+
int counter = 0;
13+
14+
final List<String> tags1 = [
15+
'family',
16+
'friends',
17+
'work',
18+
'school',
19+
'sports',
20+
'hobbies',
21+
];
22+
final List<String> tags2 = [
23+
'family',
24+
'friends',
25+
'sports',
26+
'work',
27+
];
28+
29+
@override
30+
Widget build(BuildContext context) {
31+
final tags = counter % 2 == 0 ? tags1 : tags2;
32+
return Center(
33+
child: Column(
34+
mainAxisSize: MainAxisSize.min,
35+
children: [
36+
Container(
37+
height: 40,
38+
decoration: BoxDecoration(
39+
color: Theme.of(context).colorScheme.surface,
40+
borderRadius: BorderRadius.circular(20),
41+
),
42+
// clipBehavior: Clip.antiAlias,
43+
child: AnimatedGroup(
44+
builder: (context, children) => Row(children: children),
45+
valueGetter: (child, i) => tags[i],
46+
children: [
47+
for (int i = 0; i < tags.length; i++)
48+
Padding(
49+
key: ValueKey(tags[i]),
50+
padding: const EdgeInsets.symmetric(horizontal: 8),
51+
child: TagChip(
52+
tag: tags[i],
53+
selected: false,
54+
),
55+
)
56+
],
57+
),
58+
),
59+
ElevatedButton(
60+
onPressed: () {
61+
setState(() {
62+
counter++;
63+
});
64+
},
65+
child: const Text('Switch'),
66+
),
67+
],
68+
),
69+
);
70+
}
71+
}
72+
73+
class TagChip extends StatefulWidget {
74+
final String tag;
75+
final bool selected;
76+
final VoidCallback? onTap;
77+
final bool compact;
78+
final Widget? suffix;
79+
80+
const TagChip({
81+
super.key,
82+
required this.tag,
83+
required this.selected,
84+
this.onTap,
85+
this.compact = false,
86+
this.suffix,
87+
});
88+
89+
@override
90+
State<TagChip> createState() => _TagChipState();
91+
}
92+
93+
class _TagChipState extends State<TagChip> {
94+
@override
95+
Widget build(BuildContext context) {
96+
return Container(
97+
decoration: BoxDecoration(
98+
color: widget.selected
99+
? Theme.of(context).colorScheme.primary.withOpacity(0.1)
100+
: Theme.of(context).colorScheme.onSurface.withOpacity(0.1),
101+
borderRadius: BorderRadius.circular(6),
102+
),
103+
clipBehavior: Clip.none,
104+
child: InkWell(
105+
borderRadius: BorderRadius.circular(6),
106+
onTap: widget.onTap,
107+
child: Padding(
108+
padding: const EdgeInsets.only(left: 6, right: 8, top: 4, bottom: 4),
109+
child: Row(
110+
mainAxisSize: MainAxisSize.min,
111+
children: [
112+
Icon(
113+
widget.selected ? Icons.check_circle : Icons.tag,
114+
size: 16,
115+
color: widget.selected
116+
? Theme.of(context).colorScheme.primary
117+
: Theme.of(context).colorScheme.onSurface,
118+
),
119+
const SizedBox(width: 6),
120+
Text(
121+
widget.tag,
122+
style: TextStyle(
123+
color: widget.selected
124+
? Theme.of(context).colorScheme.primary
125+
: Theme.of(context).colorScheme.onSurface,
126+
),
127+
),
128+
if (widget.suffix case Widget suffix) ...[
129+
const SizedBox(width: 4),
130+
suffix,
131+
],
132+
],
133+
),
134+
),
135+
),
136+
);
137+
}
138+
}

example/lib/stories/rolling_widget_animation.dart

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,26 @@ class _RollingWidgetAnimationState extends State<RollingWidgetAnimation> {
1717
child: Column(
1818
children: [
1919
ClipRect(
20-
child: Stack(
21-
key: ValueKey(counter),
22-
alignment: Alignment.center,
23-
children: [
24-
Image.asset(
25-
'assets/fashion/fashion_${counter % 8}.jpg',
26-
height: 500,
27-
cacheHeight: 500,
28-
),
29-
// const Positioned.fill(child: Center(child: CircularProgressIndicator())),
30-
],
31-
)
32-
.rollWidget(
33-
slideInDirection: SlideDirection.left,
34-
slideOutDirection: SlideDirection.left,
20+
// clipBehavior: Clip.none,
21+
child: (counter % 9 == 8
22+
? null
23+
: Stack(
24+
key: ValueKey(counter),
25+
alignment: Alignment.center,
26+
children: [
27+
Image.asset(
28+
'assets/fashion/fashion_${counter % 9}.jpg',
29+
height: 500 + (counter % 2 == 0 ? 0 : 100),
30+
cacheHeight: 500 + (counter % 2 == 0 ? 0 : 100),
31+
),
32+
const Positioned.fill(
33+
child:
34+
Center(child: CircularProgressIndicator())),
35+
],
36+
))
37+
.roll(
38+
slideInDirection: AxisDirection.up,
39+
slideOutDirection: AxisDirection.left,
3540
)
3641
.animate(
3742
trigger: counter,

example/lib/stories/text_animation.dart

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,26 @@ class _EmojiLineState extends State<EmojiLine> {
103103
borderRadius: BorderRadius.circular(32),
104104
),
105105
child: Text(
106-
'Hello 😀😃😄😁😆😅😂🤣🥲🥹️😊😇🙂🙃😉😌 Sexy',
106+
trigger
107+
? 'World 🧳🌂☂️🧵🪡🪢🪭🧶👓🕶🥽🥼🦺👔👖🧣 Effect'
108+
: 'Hello 😀😃😄😁😆😅😂🤣🥲🥹️😊😇🙂🙃😉😌 Sexy',
107109
style: TextStyle(
108110
color: Theme.of(context).colorScheme.onPrimaryContainer,
109111
),
110112
)
111113
.roll(
112-
'World 🧳🌂☂️🧵🪡🪢🪭🧶👓🕶🥽🥼🦺👔👖🧣 Effect',
113114
tapeStrategy: const ConsistentSymbolTapeStrategy(4),
114115
tapeSlideDirection: TextTapeSlideDirection.alternating,
115-
staggerTapes: false,
116+
staggerTapes: true,
116117
tapeCurve: Curves.easeInOutBack,
117118
widthCurve: Curves.easeOutQuart,
118119
symbolDistanceMultiplier: 2,
120+
staggerSoftness: 30,
121+
// clipBehavior: Clip.none,
119122
)
120123
.animate(
121124
trigger: trigger,
122-
reverse: true,
123-
duration: const Duration(milliseconds: 1500),
125+
duration: const Duration(milliseconds: 2000),
124126
),
125127
),
126128
);
@@ -148,7 +150,6 @@ class _TagLineState extends State<TagLine> {
148150
'Build',
149151
'Code',
150152
];
151-
int lastTagLine = 0;
152153
int tagLine = 0;
153154

154155
late Timer timer;
@@ -159,7 +160,6 @@ class _TagLineState extends State<TagLine> {
159160
timer = Timer.periodic(
160161
Duration(milliseconds: (1800 * timeDilation).toInt()), (timer) {
161162
setState(() {
162-
lastTagLine = tagLine;
163163
tagLine = (tagLine + 1) % tagLines.length;
164164
});
165165
});
@@ -212,15 +212,14 @@ class _TagLineState extends State<TagLine> {
212212
],
213213
).createShader(rect),
214214
child: Text(
215-
tagLines[lastTagLine],
215+
tagLines[tagLine],
216216
style: GoogleFonts.gloriaHallelujah().copyWith(
217217
color: Colors.white,
218218
fontWeight: FontWeight.bold,
219219
fontSize: 56,
220220
),
221221
)
222222
.roll(
223-
tagLines[tagLine],
224223
symbolDistanceMultiplier: 2,
225224
tapeSlideDirection: TextTapeSlideDirection.down,
226225
tapeCurve: Curves.easeInOutCubic,
@@ -263,7 +262,6 @@ class _TranslationState extends State<Translation> {
263262
'Namaste',
264263
'Salaam',
265264
];
266-
int lastTranslation = 0;
267265
int translation = 0;
268266

269267
late Timer timer;
@@ -275,7 +273,6 @@ class _TranslationState extends State<Translation> {
275273
timer = Timer.periodic(
276274
Duration(milliseconds: (2000 * timeDilation).toInt()), (timer) {
277275
setState(() {
278-
lastTranslation = translation;
279276
translation = (translation + 1) % translations.length;
280277
});
281278
});
@@ -315,15 +312,14 @@ class _TranslationState extends State<Translation> {
315312
],
316313
).createShader(rect),
317314
child: Text(
318-
translations[lastTranslation],
315+
translations[translation],
319316
style: GoogleFonts.sacramento().copyWith(
320317
color: Colors.white,
321318
fontWeight: FontWeight.bold,
322319
fontSize: 56,
323320
),
324321
)
325322
.roll(
326-
translations[translation],
327323
symbolDistanceMultiplier: 2,
328324
tapeCurve: Curves.easeInOutBack,
329325
widthCurve: Curves.easeInOutQuart,
@@ -361,7 +357,6 @@ class LikeButton extends StatefulWidget {
361357
}
362358

363359
class _LikeButtonState extends State<LikeButton> {
364-
int lastCounter = 19;
365360
int counter = 19;
366361
bool triggerShare = false;
367362
int downloadIteration = 1;
@@ -378,7 +373,6 @@ class _LikeButtonState extends State<LikeButton> {
378373
child: InkWell(
379374
onTap: () {
380375
setState(() {
381-
lastCounter = counter;
382376
counter++;
383377
});
384378
},
@@ -395,13 +389,12 @@ class _LikeButtonState extends State<LikeButton> {
395389
),
396390
const SizedBox(width: 8),
397391
Text(
398-
'${lastCounter}K',
392+
'${counter}K',
399393
style: GoogleFonts.robotoTextTheme()
400394
.bodyMedium!
401395
.copyWith(color: Colors.white, fontSize: 16),
402396
)
403397
.roll(
404-
'${counter}K',
405398
tapeStrategy: const AllSymbolsTapeStrategy(false),
406399
symbolDistanceMultiplier: 2,
407400
clipBehavior: Clip.none,
@@ -453,13 +446,12 @@ class _LikeButtonState extends State<LikeButton> {
453446
),
454447
const SizedBox(width: 8),
455448
Text(
456-
'Share',
449+
triggerShare ? 'Thanks!' : 'Share',
457450
style: GoogleFonts.robotoTextTheme()
458451
.bodyMedium!
459452
.copyWith(color: Colors.white, fontSize: 16),
460453
)
461454
.roll(
462-
'Thanks!',
463455
tapeStrategy:
464456
const ConsistentSymbolTapeStrategy(0, true),
465457
symbolDistanceMultiplier: 2,
@@ -513,11 +505,6 @@ class _LikeButtonState extends State<LikeButton> {
513505
.copyWith(color: Colors.white, fontSize: 16),
514506
)
515507
.roll(
516-
switch (downloadIteration) {
517-
1 => 'Downloading',
518-
2 => 'Downloaded',
519-
_ => 'Download',
520-
},
521508
tapeStrategy:
522509
const ConsistentSymbolTapeStrategy(0, false),
523510
symbolDistanceMultiplier: 2,
@@ -642,7 +629,6 @@ class _ColorPalettePageState extends State<ColorPalettePage> {
642629
]
643630
};
644631

645-
int lastPage = 0;
646632
int currentPage = 0;
647633
final PageController _pageController = PageController();
648634

@@ -694,12 +680,11 @@ class _ColorPalettePageState extends State<ColorPalettePage> {
694680
colors: palettes.values.elementAt(currentPage),
695681
).createShader(rect),
696682
child: Text(
697-
palettes.keys.elementAt(lastPage).toUpperCase(),
683+
palettes.keys.elementAt(currentPage).toUpperCase(),
698684
style: const TextStyle(
699685
fontWeight: FontWeight.w700, color: Colors.white),
700686
)
701687
.roll(
702-
palettes.keys.elementAt(currentPage).toUpperCase(),
703688
staggerSoftness: 6,
704689
reverseStaggerDirection: false,
705690
tapeSlideDirection: TextTapeSlideDirection.down,
@@ -731,7 +716,6 @@ class _ColorPalettePageState extends State<ColorPalettePage> {
731716
itemCount: palettes.keys.length,
732717
onPageChanged: (int page) {
733718
setState(() {
734-
lastPage = currentPage;
735719
currentPage = page;
736720
});
737721
},

0 commit comments

Comments
 (0)