Files
CheckTheethKids/lib/widgets/liquid_waves_background.dart
2026-07-14 18:23:03 +01:00

71 lines
2.2 KiB
Dart

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<LiquidWavesBackground> createState() => _LiquidWavesBackgroundState();
}
class _LiquidWavesBackgroundState extends State<LiquidWavesBackground>
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,
),
),
),
),
),
);
}
}