import 'package:flutter/material.dart'; import 'dart:math' as math; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData.dark(), home: const Scaffold( backgroundColor: Colors.black, body: Center( child: CircularWaveVisualizer(), ), ), ); } } class CircularWaveVisualizer extends StatefulWidget { const CircularWaveVisualizer({super.key}); @override _CircularWaveVisualizerState createState() => _CircularWaveVisualizerState(); } class _CircularWaveVisualizerState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(seconds: 12), )..repeat(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { return CustomPaint( painter: CircularWavePainter(_controller.value), size: const Size(300, 300), ); }, ); } } class CircularWavePainter extends CustomPainter { final double animationValue; final int rings = 40; // Halka sayısı final int pointsPerRing = 180; // Her halkadaki nokta sayısı CircularWavePainter(this.animationValue); @override void paint(Canvas canvas, Size size) { final centerX = size.width / 2; final centerY = size.height / 2; final maxRadius = math.min(size.width, size.height) / 2; for (var r = 0; r < rings; r++) { double ringRadius = (r / rings) * maxRadius; for (var p = 0; p < pointsPerRing; p++) { double angle = (p * 2 * math.pi) / pointsPerRing; double normalizedRadius = ringRadius / maxRadius; // Daha yumuşak dalga efekti double wave1 = math.sin(angle * 4 + animationValue * 2 * math.pi) * 2; double wave2 = math.cos(normalizedRadius * 8 + animationValue * 2 * math.pi) * 2; double totalWave = (wave1 + wave2) * (1 - normalizedRadius) * 2; // Nokta pozisyonu double x = centerX + (ringRadius + totalWave) * math.cos(angle); double y = centerY + (ringRadius + totalWave) * math.sin(angle); // Nokta büyüklüğü (merkezden uzaklaştıkça küçülür) double pointSize = math.max(0.5, 1.2 * (1 - normalizedRadius)); // Renk geçişi Color pointColor = Color.lerp( const Color(0xFF4169E1), // Mavi const Color(0xFF800080), // Mor normalizedRadius, )!; // Opaklık ayarı double opacity = math.max(0.1, 1 - normalizedRadius); pointColor = pointColor.withOpacity(opacity * 0.8); // Nokta çizimi var paint = Paint() ..color = pointColor ..style = PaintingStyle.fill ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 0.5); canvas.drawCircle( Offset(x, y), pointSize, paint, ); // Noktalar arası bağlantılar if (p > 0 && r > 0) { // Bir önceki nokta ile bağlantı double prevAngle = ((p - 1) * 2 * math.pi) / pointsPerRing; double prevX = centerX + ringRadius * math.cos(prevAngle); double prevY = centerY + ringRadius * math.sin(prevAngle); double distance = math.sqrt(math.pow(x - prevX, 2) + math.pow(y - prevY, 2)); if (distance < 8) { canvas.drawLine( Offset(prevX, prevY), Offset(x, y), Paint() ..color = pointColor.withOpacity(0.05) ..strokeWidth = 0.2, ); } } } } } @override bool shouldRepaint(CircularWavePainter oldDelegate) => oldDelegate.animationValue != animationValue; }