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 createState() => _LinkLogoAnimationState(); } class _LinkLogoAnimationState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _rotation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 1200), vsync: this, )..repeat(reverse: true); _rotation = Tween( 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( '', ), ), ), Positioned.fill( child: Transform( alignment: const Alignment( (224 * 2 / originalViewportSize) - 1, (352 * 2 / originalViewportSize) - 1, ), transform: Matrix4.identity()..rotateZ(-_rotation.value), child: SvgPicture.string( '', ), ), ), ], ); }, ), ); } String _toHex(Color color) { return '#${color.toARGB32().toRadixString(16).substring(2)}'; } }