Created
March 31, 2025 08:08
-
-
Save iBelow/49870e2048cf1068d237137d8a511e34 to your computer and use it in GitHub Desktop.
Gemini 2.5 Pro code example
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
| import 'dart:math' as math; | |
| import 'package:flutter/material.dart'; | |
| void main() { | |
| runApp(const MyApp()); | |
| } | |
| class MyApp extends StatelessWidget { | |
| const MyApp({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| debugShowCheckedModeBanner: false, | |
| theme: ThemeData( | |
| brightness: Brightness.dark, | |
| primarySwatch: Colors.blue, | |
| ), | |
| home: const AnimatedHomePage(), | |
| ); | |
| } | |
| } | |
| class AnimatedHomePage extends StatefulWidget { | |
| const AnimatedHomePage({super.key}); | |
| @override | |
| State<AnimatedHomePage> createState() => _AnimatedHomePageState(); | |
| } | |
| // Используем SingleTickerProviderStateMixin для AnimationController | |
| class _AnimatedHomePageState extends State<AnimatedHomePage> | |
| with SingleTickerProviderStateMixin { | |
| late AnimationController _controller; | |
| late Animation<double> _scaleAnimation; | |
| late Animation<double> _rotationAnimation; | |
| late Animation<Offset> _slideAnimation; | |
| late Animation<double> _textFadeAnimation; | |
| late Animation<AlignmentGeometry> _backgroundAlignAnimation; | |
| bool _isHovering = false; | |
| @override | |
| void initState() { | |
| super.initState(); | |
| // Создаем контроллер анимации | |
| _controller = AnimationController( | |
| duration: const Duration(milliseconds: 1500), // Общая длительность | |
| vsync: this, | |
| ); | |
| // Анимация фона (перемещение центра градиента) | |
| _backgroundAlignAnimation = TweenSequence<AlignmentGeometry>( | |
| [ | |
| TweenSequenceItem( | |
| tween: AlignmentTween(begin: Alignment.topLeft, end: Alignment.topRight), | |
| weight: 1, | |
| ), | |
| TweenSequenceItem( | |
| tween: AlignmentTween(begin: Alignment.topRight, end: Alignment.bottomRight), | |
| weight: 1, | |
| ), | |
| TweenSequenceItem( | |
| tween: AlignmentTween(begin: Alignment.bottomRight, end: Alignment.bottomLeft), | |
| weight: 1, | |
| ), | |
| TweenSequenceItem( | |
| tween: AlignmentTween(begin: Alignment.bottomLeft, end: Alignment.topLeft), | |
| weight: 1, | |
| ), | |
| ], | |
| ).animate(_controller); | |
| // Анимация скольжения карточки (сверху вниз) | |
| _slideAnimation = Tween<Offset>( | |
| begin: const Offset(0, -1.5), // Начинаем за пределами экрана сверху | |
| end: Offset.zero, | |
| ).animate( | |
| CurvedAnimation( | |
| parent: _controller, | |
| // Начинается сразу, заканчивается на 60% времени | |
| curve: const Interval(0.0, 0.6, curve: Curves.elasticOut), // Эффект "резинки" | |
| ), | |
| ); | |
| // Анимация масштабирования карточки (от 0 до 1) | |
| _scaleAnimation = Tween<double>( | |
| begin: 0.0, | |
| end: 1.0, | |
| ).animate( | |
| CurvedAnimation( | |
| parent: _controller, | |
| // Начинается сразу, заканчивается на 60% времени | |
| curve: const Interval(0.0, 0.6, curve: Curves.elasticOut), | |
| ), | |
| ); | |
| // Анимация вращения карточки | |
| _rotationAnimation = Tween<double>( | |
| begin: -math.pi / 8, // Начальный небольшой наклон | |
| end: 0.0, // Конечное положение без наклона | |
| ).animate( | |
| CurvedAnimation( | |
| parent: _controller, | |
| // Начинается чуть позже (20%), заканчивается на 70% | |
| curve: const Interval(0.2, 0.7, curve: Curves.easeInOutSine), | |
| ), | |
| ); | |
| // Анимация появления текста (с задержкой) | |
| _textFadeAnimation = Tween<double>( | |
| begin: 0.0, | |
| end: 1.0, | |
| ).animate( | |
| CurvedAnimation( | |
| parent: _controller, | |
| // Начинается на 50% времени, заканчивается на 100% | |
| curve: const Interval(0.5, 1.0, curve: Curves.easeIn), | |
| ), | |
| ); | |
| // Запускаем анимацию один раз при старте | |
| _controller.forward(); | |
| // Запускаем анимацию фона в цикле | |
| _controller.repeat(reverse: true, period: const Duration(seconds: 10)); | |
| } | |
| @override | |
| void dispose() { | |
| _controller.dispose(); // Освобождаем ресурсы контроллера | |
| super.dispose(); | |
| } | |
| void _handleHover(bool hovering) { | |
| setState(() { | |
| _isHovering = hovering; | |
| }); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| body: AnimatedBuilder( | |
| animation: _backgroundAlignAnimation, // Слушаем изменения фона | |
| builder: (context, child) { | |
| return Container( | |
| // Анимированный градиент фона | |
| decoration: BoxDecoration( | |
| gradient: LinearGradient( | |
| colors: const [Color(0xFF1E88E5), Color(0xFFE91E63), Color(0xFFFFC107)], | |
| begin: _backgroundAlignAnimation.value, | |
| end: Alignment.center, // Можно сделать и end анимированным | |
| stops: const [0.0, 0.5, 1.0], | |
| ), | |
| ), | |
| child: child, // Вставляем остальное содержимое | |
| ); | |
| }, | |
| child: Center( | |
| // MouseRegion для отслеживания наведения мыши | |
| child: MouseRegion( | |
| onEnter: (_) => _handleHover(true), | |
| onExit: (_) => _handleHover(false), | |
| cursor: SystemMouseCursors.click, // Показываем курсор-руку | |
| child: GestureDetector( | |
| onTap: () { | |
| // Перезапускаем анимацию по тапу | |
| if (_controller.status == AnimationStatus.completed || _controller.status == AnimationStatus.dismissed) { | |
| _controller.forward(from: 0.0); | |
| } else if (_controller.status == AnimationStatus.forward) { | |
| _controller.reverse(); | |
| } else { // reverse | |
| _controller.forward(); | |
| } | |
| }, | |
| // AnimatedBuilder слушает основной контроллер для анимаций карточки | |
| child: AnimatedBuilder( | |
| animation: _controller, | |
| builder: (context, child) { | |
| // Применяем трансформации к карточке | |
| return Transform.translate( | |
| offset: _slideAnimation.value * 100, // Умножаем для видимого эффекта | |
| child: Transform.scale( | |
| scale: _scaleAnimation.value, | |
| child: Transform.rotate( | |
| angle: _rotationAnimation.value, | |
| child: child, // Карточка передается сюда | |
| ), | |
| ), | |
| ); | |
| }, | |
| // Сама карточка (содержимое) | |
| child: AnimatedContainer( | |
| duration: const Duration(milliseconds: 200), // Плавность для hover-эффекта | |
| padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 30), | |
| decoration: BoxDecoration( | |
| color: Colors.black.withOpacity(0.7), | |
| borderRadius: BorderRadius.circular(20), | |
| boxShadow: [ | |
| BoxShadow( | |
| color: Colors.black.withOpacity(_isHovering ? 0.6 : 0.3), | |
| blurRadius: _isHovering ? 25 : 15, | |
| spreadRadius: _isHovering ? 5 : 2, | |
| offset: const Offset(0, 8), | |
| ), | |
| ], | |
| ), | |
| // Масштабирование при наведении | |
| transform: Matrix4.identity()..scale(_isHovering ? 1.05 : 1.0), | |
| transformAlignment: Alignment.center, | |
| child: FadeTransition( | |
| opacity: _textFadeAnimation, // Анимация прозрачности текста | |
| child: Column( | |
| mainAxisSize: MainAxisSize.min, | |
| children: const [ | |
| Icon(Icons.rocket_launch, size: 60, color: Colors.amberAccent), | |
| SizedBox(height: 20), | |
| Text( | |
| 'Flutter Анимации', | |
| style: TextStyle( | |
| fontSize: 28, | |
| fontWeight: FontWeight.bold, | |
| color: Colors.white, | |
| letterSpacing: 1.2, | |
| ), | |
| ), | |
| SizedBox(height: 10), | |
| Text( | |
| 'Без сторонних пакетов!', | |
| style: TextStyle( | |
| fontSize: 16, | |
| color: Colors.white70, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment