Created
March 8, 2023 07:38
-
-
Save divyanshub024/790f4e8e3b19769a423c79641ed7ac44 to your computer and use it in GitHub Desktop.
This file contains 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 'package:flutter/material.dart'; | |
import 'dart:ui'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith( | |
scaffoldBackgroundColor: const Color(0xFFECDAC3), | |
), | |
debugShowCheckedModeBanner: false, | |
home: const InfinityPathAnimation(), | |
); | |
} | |
} | |
class InfinityPathAnimation extends StatefulWidget { | |
const InfinityPathAnimation({Key? key}) : super(key: key); | |
@override | |
State<InfinityPathAnimation> createState() => _InfinityPathAnimationState(); | |
} | |
class _InfinityPathAnimationState extends State<InfinityPathAnimation> | |
with SingleTickerProviderStateMixin { | |
int infinitiesLength = 9; | |
late AnimationController _controller; | |
@override | |
void initState() { | |
_controller = AnimationController( | |
vsync: this, | |
duration: const Duration( | |
seconds: 10, | |
), | |
lowerBound: 0.0, | |
upperBound: 1.0, | |
)..repeat(); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: Center( | |
child: AnimatedBuilder( | |
animation: _controller, | |
builder: (context, _) { | |
return CustomPaint( | |
size: const Size(500, 500), | |
painter: InfinityPainter( | |
progress: _controller.value, | |
infinitiesLength: infinitiesLength, | |
), | |
); | |
}, | |
), | |
), | |
); | |
} | |
} | |
class InfinityPainter extends CustomPainter { | |
InfinityPainter({ | |
required this.progress, | |
required this.infinitiesLength, | |
}); | |
final double progress; | |
final int infinitiesLength; | |
late double width; | |
late double height; | |
final colors = const [ | |
Color(0xFF086A9A), | |
Color(0xFFD8523B), | |
Color(0xFFF8B023), | |
]; | |
@override | |
void paint(Canvas canvas, Size size) { | |
width = size.width; | |
height = size.height; | |
for (int i = 0; i < infinitiesLength; i++) { | |
_drawInfinitySymbols( | |
canvas, | |
color: colors[i % 3], | |
index: i, | |
strokeWidth: 10, | |
); | |
} | |
} | |
void _drawInfinitySymbols( | |
Canvas canvas, { | |
Color color = Colors.blueAccent, | |
double strokeWidth = 10, | |
int index = 0, | |
}) { | |
final paint = Paint() | |
..color = color | |
..style = PaintingStyle.stroke | |
..isAntiAlias = true | |
..strokeJoin = StrokeJoin.round | |
..strokeCap = StrokeCap.round | |
..strokeWidth = strokeWidth; | |
final path = _getInfinityPath(strokeWidth, index); | |
PathMetric pathMetric = path.computeMetrics().first; | |
Path extractPath = pathMetric.extractPath( | |
(pathMetric.length * progress) / 2, | |
(pathMetric.length * progress), | |
); | |
canvas.drawPath(extractPath, paint); | |
} | |
Path _getInfinityPath(double strokeWidth, int index) { | |
final sw = strokeWidth * 1.5; | |
final originX = width / 2 + (sw * index); | |
final originY = height / 2; | |
return Path() | |
..moveTo(originX, originY) | |
..cubicTo( | |
0 - (sw * index) * 1.2, //x1 | |
0 - (sw * index) * 2, //y1 | |
0 - (sw * index) * 1.2, //x2 | |
height + (sw * index) * 2, //y2 | |
originX, //x3 | |
originY, //y3 | |
) | |
..cubicTo( | |
width + width / 3 - (sw * index * 1.2), //x1 | |
0 - height / 3 + (sw * index * 2), //y1 | |
width + width / 3 - (sw * index * 1.2), //x2 | |
height + height / 3 - (sw * index * 2), //y2 | |
originX, //x3 | |
originY, //y3 | |
) | |
..cubicTo( | |
0 - (sw * index) * 1.2, //x1 | |
0 - (sw * index) * 2, //y1 | |
0 - (sw * index) * 1.2, //x2 | |
height + (sw * index) * 2, //y2 | |
originX, //x3 | |
originY, //y3 | |
) | |
..cubicTo( | |
width + width / 3 - (sw * index * 1.2), //x1 | |
0 - height / 3 + (sw * index * 2), //y1 | |
width + width / 3 - (sw * index * 1.2), //x2 | |
height + height / 3 - (sw * index * 2), //y2 | |
originX, //x3 | |
originY, //y3 | |
); | |
} | |
@override | |
bool shouldRepaint(covariant CustomPainter oldDelegate) => true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment