twonly-app/lib/src/visual/views/onboarding/components/link_logo_animation.dart
otsmr ea41158872
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
redesigning register view
2026-05-16 23:02:12 +02:00

101 lines
3.7 KiB
Dart

import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class LinkLogoAnimation extends StatefulWidget {
const LinkLogoAnimation({
super.key,
this.size = 130,
this.color = Colors.white,
});
final double size;
final Color color;
@override
State<LinkLogoAnimation> createState() => _LinkLogoAnimationState();
}
class _LinkLogoAnimationState extends State<LinkLogoAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _rotation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
)..repeat(reverse: true);
_rotation =
Tween<double>(
begin: -2.0 * (math.pi / 180.0),
end: 2.0 * (math.pi / 180.0),
).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
const originalViewportSize = 640.0;
const path1 =
'M451.5 160C434.9 160 418.8 164.5 404.7 172.7C388.9 156.7 370.5 143.3 350.2 133.2C378.4 109.2 414.3 96 451.5 96C537.9 96 608 166 608 252.5C608 294 591.5 333.8 562.2 363.1L491.1 434.2C461.8 463.5 422 480 380.5 480C294.1 480 224 410 224 323.5C224 322 224 320.5 224.1 319C224.6 301.3 239.3 287.4 257 287.9C274.7 288.4 288.6 303.1 288.1 320.8C288.1 321.7 288.1 322.6 288.1 323.4C288.1 374.5 329.5 415.9 380.6 415.9C405.1 415.9 428.6 406.2 446 388.8L517.1 317.7C534.4 300.4 544.2 276.8 544.2 252.3C544.2 201.2 502.8 159.8 451.7 159.8z';
const path2 =
'M307.2 237.3C305.3 236.5 303.4 235.4 301.7 234.2C289.1 227.7 274.7 224 259.6 224C235.1 224 211.6 233.7 194.2 251.1L123.1 322.2C105.8 339.5 96 363.1 96 387.6C96 438.7 137.4 480.1 188.5 480.1C205 480.1 221.1 475.7 235.2 467.5C251 483.5 269.4 496.9 289.8 507C261.6 530.9 225.8 544.2 188.5 544.2C102.1 544.2 32 474.2 32 387.7C32 346.2 48.5 306.4 77.8 277.1L148.9 206C178.2 176.7 218 160.2 259.5 160.2C346.1 160.2 416 230.8 416 317.1C416 318.4 416 319.7 416 321C415.6 338.7 400.9 352.6 383.2 352.2C365.5 351.8 351.6 337.1 352 319.4C352 318.6 352 317.9 352 317.1C352 283.4 334 253.8 307.2 237.5z';
return SizedBox(
width: widget.size,
height: widget.size,
child: AnimatedBuilder(
animation: _rotation,
builder: (context, child) {
return Stack(
children: [
Positioned.fill(
child: Transform(
alignment: const Alignment(
(416 * 2 / originalViewportSize) - 1,
(288 * 2 / originalViewportSize) - 1,
),
transform: Matrix4.identity()..rotateZ(_rotation.value),
child: SvgPicture.string(
'<svg viewBox="0 0 640 640"><path d="$path1" fill="${_toHex(widget.color)}"/></svg>',
),
),
),
Positioned.fill(
child: Transform(
alignment: const Alignment(
(224 * 2 / originalViewportSize) - 1,
(352 * 2 / originalViewportSize) - 1,
),
transform: Matrix4.identity()..rotateZ(-_rotation.value),
child: SvgPicture.string(
'<svg viewBox="0 0 640 640"><path d="$path2" fill="${_toHex(widget.color)}"/></svg>',
),
),
),
],
);
},
),
);
}
String _toHex(Color color) {
return '#${color.toARGB32().toRadixString(16).substring(2)}';
}
}