import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:lottie/lottie.dart'; /// Fundo decorativo com a animação "Liquid waves", reutilizado em todas as /// telas informativas da app (quiz, vídeos, termos, home, etc.) para manter /// a mesma posição/rotação em todo o lado. /// /// A animação arranca sincronizada com o relógio do sistema (em vez de /// sempre do frame 0) para que, ao navegar de uma tela para a seguinte, a /// nova instância do Lottie continue visualmente de onde a anterior ficou /// em vez de reiniciar de forma abrupta. class LiquidWavesBackground extends StatefulWidget { const LiquidWavesBackground({super.key}); @override State createState() => _LiquidWavesBackgroundState(); } class _LiquidWavesBackgroundState extends State with SingleTickerProviderStateMixin { // Duração real da composição (300x200, 60fps, frames 0-540 — ver // lottie/Liquid waves.json), usada para sincronizar o valor inicial com o // relógio do sistema sem depender do callback assíncrono onLoaded. static const Duration _loopDuration = Duration(seconds: 9); late final AnimationController _controller; @override void initState() { super.initState(); final elapsedMs = DateTime.now().millisecondsSinceEpoch % _loopDuration.inMilliseconds; _controller = AnimationController(vsync: this, duration: _loopDuration) ..value = elapsedMs / _loopDuration.inMilliseconds ..repeat(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final size = MediaQuery.sizeOf(context); return Positioned( left: -size.width * 0.40, bottom: -size.width * 0.45, child: IgnorePointer( child: SizedBox( width: size.width * 1.05, height: size.width * 1.05, child: Transform.rotate( angle: 35 * math.pi / 180, child: Opacity( opacity: 0.95, child: Lottie.asset( 'lottie/Liquid waves.json', controller: _controller, fit: BoxFit.cover, ), ), ), ), ), ); } }