-
-
Save callmephil/f219dc01768ae320744938682f22f24f to your computer and use it in GitHub Desktop.
deintegrate effect.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ignore_for_file: prefer-single-widget-per-file | |
| import 'dart:math'; | |
| import 'package:flutter/material.dart'; | |
| import 'package:flutter_animate/flutter_animate.dart'; | |
| void main() => runApp(const MaterialApp(home: ThanosSnapDemo())); | |
| class ThanosSnapDemo extends StatefulWidget { | |
| const ThanosSnapDemo({super.key}); | |
| @override | |
| State<ThanosSnapDemo> createState() => _ThanosSnapDemoState(); | |
| } | |
| class _ThanosSnapDemoState extends State<ThanosSnapDemo> { | |
| bool snapped = false; | |
| @override | |
| Widget build(BuildContext context) { | |
| const text = | |
| 'Hmm. We’re having trouble finding that site.' | |
| 'Please check the URL or try again later.' | |
| 'If the problem persists, contact support.'; | |
| final chars = text.split(''); | |
| return Scaffold( | |
| backgroundColor: Colors.black, | |
| body: Center( | |
| child: Padding( | |
| padding: const EdgeInsets.all(8), | |
| child: Column( | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| children: [ | |
| ElevatedButton( | |
| onPressed: () => setState(() => snapped = !snapped), | |
| child: const Text('Snap'), | |
| ), | |
| Wrap( | |
| key: ValueKey(snapped), | |
| alignment: WrapAlignment.center, | |
| children: [ | |
| for (int i = 0; i < chars.length; i++) | |
| _AnimatedChar( | |
| char: chars[i], | |
| index: i, | |
| snapped: snapped, | |
| ), | |
| ], | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| class _AnimatedChar extends StatelessWidget { | |
| const _AnimatedChar({ | |
| required this.char, | |
| required this.index, | |
| required this.snapped, | |
| }); | |
| final String char; | |
| final int index; | |
| final bool snapped; | |
| // Static random group assignment for all chars | |
| static final List<int> _groups = []; | |
| static int _getGroup(int index, int totalChars, int groupCount) { | |
| // Fill _groups only once | |
| if (_groups.length != totalChars) { | |
| _groups.clear(); | |
| final rand = Random(42); // Seed for repeatability | |
| for (var i = 0; i < totalChars; i++) { | |
| _groups.add(rand.nextInt(groupCount)); | |
| } | |
| } | |
| return _groups[index]; | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| final random = Random(index); | |
| final dx = (random.nextDouble() - 0.5) * 200; | |
| final dyDirection = random.nextBool() ? 1 : -1; | |
| final dy = random.nextDouble() * 300 * dyDirection; | |
| final blurRadius = | |
| random.nextDouble() * 4 + 2; // Lower blur for performance | |
| // Get total chars and group count from context | |
| final totalChars = | |
| context.findAncestorWidgetOfExactType<Wrap>()?.children.length ?? 100; | |
| const groupCount = 6; // e.g. 6 random groups | |
| final group = _getGroup(index, totalChars, groupCount); | |
| final delay = Duration(milliseconds: group * 120); | |
| return RepaintBoundary( | |
| child: | |
| Text( | |
| char, | |
| style: const TextStyle( | |
| fontSize: 36, | |
| color: Colors.white, | |
| fontWeight: FontWeight.bold, | |
| ), | |
| ) | |
| .animate() | |
| .move( | |
| begin: snapped ? Offset.zero : Offset(dx, dy), | |
| end: snapped ? Offset(dx, dy) : Offset.zero, | |
| curve: Curves.easeInOutCubic, | |
| duration: 800.ms, | |
| delay: delay, | |
| ) | |
| .fade( | |
| begin: snapped ? 1 : 0, | |
| end: snapped ? 0 : 1, | |
| duration: 1200.ms, | |
| delay: delay, | |
| ) | |
| .blur( | |
| begin: snapped ? Offset.zero : Offset(blurRadius, blurRadius), | |
| end: snapped ? Offset(blurRadius, blurRadius) : Offset.zero, | |
| duration: 400.ms, | |
| delay: delay, | |
| ) | |
| .scale( | |
| begin: snapped ? const Offset(1, 1) : const Offset(0.8, 0.8), | |
| end: const Offset(0.8, 0.8), | |
| duration: 800.ms, | |
| delay: delay, | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment