Build a Futuristic Wireless Power Share Tracker App using Flutter (Cyberpunk UI | Single main.dart)
Demo :
Click Video πππ
✨ FEATURES :
✔ Single main.dart file (No extra files)
✔ 100% Responsive (Mobile, Tablet, Desktop)
✔ Cyberpunk + Neon Glow UI
✔ Wireless Power Share Simulation
✔ Advanced CustomPainter HUD
✔ Smooth Animations & Effects
✔ Shorts / Reels friendly design
✔ Beginner + Advanced Flutter devs ke liye perfect
Code :
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
void main() {
runApp(const CyberpunkPowerApp());
}
class CyberpunkPowerApp extends StatelessWidget {
const CyberpunkPowerApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Power Share Protocol',
debugShowCheckedModeBanner: false,
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: Colors.black,
primaryColor: Colors.cyanAccent,
colorScheme: const ColorScheme.dark(
primary: Colors.cyanAccent,
secondary: Colors.purpleAccent,
surface: Colors.black,
),
),
home: const PowerShareHome(),
);
}
}
class PowerShareHome extends StatefulWidget {
const PowerShareHome({super.key});
@override
State<PowerShareHome> createState() => _PowerShareHomeState();
}
class _PowerShareHomeState extends State<PowerShareHome> with TickerProviderStateMixin {
bool _isSharing = false;
double _powerLevel = 0.0;
late AnimationController _pulseController;
late AnimationController _scanController;
late AnimationController _rotationController;
Timer? _chargeTimer;
@override
void initState() {
super.initState();
_pulseController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(reverse: true);
_scanController = AnimationController(
vsync: this,
duration: const Duration(seconds: 4)
)..repeat();
_rotationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 10),
)..repeat();
}
@override
void dispose() {
_pulseController.dispose();
_scanController.dispose();
_rotationController.dispose();
_chargeTimer?.cancel();
super.dispose();
}
void _toggleSimulation() {
setState(() {
_isSharing = !_isSharing;
});
if (_isSharing) {
// Reset and start charging
_powerLevel = 0.0;
_chargeTimer?.cancel();
_chargeTimer = Timer.periodic(const Duration(milliseconds: 50), (timer) {
setState(() {
_powerLevel += 0.2;
if (_powerLevel >= 100) {
_powerLevel = 100;
timer.cancel();
_isSharing = false; // Auto stop when full
}
});
});
} else {
_chargeTimer?.cancel();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) {
final isDesktop = constraints.maxWidth > 800;
return Center(
child: Container(
width: isDesktop ? 800 : double.infinity,
height: constraints.maxHeight,
decoration: const BoxDecoration(
gradient: RadialGradient(
center: Alignment.center,
radius: 1.5,
colors: [
Color(0xFF1a1a1a),
Colors.black,
],
),
),
child: Stack(
fit: StackFit.expand,
children: [
// Background grid
CustomPaint(
painter: GridPainter(),
),
// Scanning line effect
if (_isSharing)
AnimatedBuilder(
animation: _scanController,
builder: (context, child) {
return CustomPaint(
painter: ScannerPainter(_scanController.value),
);
},
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Header
const Padding(
padding: EdgeInsets.only(top: 60.0, bottom: 20),
child: Text(
"WIRELESS POWER PROTOCOL",
style: TextStyle(
color: Colors.cyanAccent,
fontFamily: 'Courier',
fontSize: 14,
letterSpacing: 4,
fontWeight: FontWeight.bold,
),
),
),
const Spacer(),
// Main Power HUD
Stack(
alignment: Alignment.center,
children: [
// Rotating Outer Ring
AnimatedBuilder(
animation: _rotationController,
builder: (context, child) {
return Transform.rotate(
angle: _rotationController.value * 2 * math.pi,
child: CustomPaint(
size: const Size(320, 320),
painter: TechRingPainter(_isSharing),
),
);
},
),
// Glow Pulse
AnimatedBuilder(
animation: _pulseController,
builder: (context, child) {
return Container(
width: 250,
height: 250,
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: _isSharing
? Colors.cyanAccent.withOpacity(0.2 + 0.3 * _pulseController.value)
: Colors.purpleAccent.withOpacity(0.1),
blurRadius: 30 + 30 * _pulseController.value,
spreadRadius: 5,
)
]
),
);
},
),
// Progress Circle
SizedBox(
width: 240,
height: 240,
child: CustomPaint(
painter: PowerCirclePainter(
progress: _powerLevel / 100,
isSharing: _isSharing,
),
),
),
// Center Data
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_isSharing ? "TRANSFERRING..." : "SYSTEM READY",
style: TextStyle(
color: _isSharing ? Colors.cyanAccent : Colors.white54,
fontSize: 10,
letterSpacing: 2,
fontFamily: "Courier",
),
),
const SizedBox(height: 5),
Text(
"${_powerLevel.toStringAsFixed(1)}%",
style: TextStyle(
color: Colors.white,
fontSize: 42,
fontWeight: FontWeight.bold,
fontFamily: "Courier",
shadows: [
BoxShadow(
color: _isSharing ? Colors.cyanAccent : Colors.purpleAccent,
blurRadius: 15,
)
]
),
),
const SizedBox(height: 5),
if (_isSharing)
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.bolt, color: Colors.yellowAccent, size: 16),
Text(
"${(15 + 5 * _pulseController.value).toStringAsFixed(1)}W",
style: const TextStyle(
color: Colors.yellowAccent,
fontSize: 14,
fontFamily: "Courier"
),
),
],
),
],
)
],
),
const Spacer(),
// Warning / Disclaimer
Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
decoration: BoxDecoration(
border: Border.all(color: Colors.white12),
borderRadius: BorderRadius.circular(4),
color: Colors.black45,
),
child: const Text(
"Simulation Only – Educational UI Demo",
style: TextStyle(
color: Colors.white38,
fontSize: 9,
letterSpacing: 1.2,
fontFamily: "Courier"
),
),
),
const SizedBox(height: 30),
// Action Button
GestureDetector(
onTap: _toggleSimulation,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
height: 55,
width: isDesktop ? 300 : MediaQuery.of(context).size.width * 0.7,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: _isSharing
? [Colors.redAccent.withOpacity(0.4), Colors.redAccent.withOpacity(0.2)]
: [Colors.cyanAccent.withOpacity(0.4), Colors.blueAccent.withOpacity(0.2)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: _isSharing ? Colors.redAccent : Colors.cyanAccent.withOpacity(0.8),
width: 1.5
),
boxShadow: [
BoxShadow(
color: _isSharing ? Colors.redAccent.withOpacity(0.3) : Colors.cyanAccent.withOpacity(0.3),
blurRadius: 15,
spreadRadius: 1
)
]
),
child: Center(
child: Text(
_isSharing ? "TERMINATE LINK" : "START POWER SHARE",
style: TextStyle(
color: _isSharing ? Colors.redAccent : Colors.cyanAccent,
fontSize: 14,
fontWeight: FontWeight.bold,
fontFamily: "Courier",
letterSpacing: 2
),
),
),
),
),
const SizedBox(height: 50),
],
)
],
),
),
);
},
),
);
}
}
class GridPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.cyanAccent.withOpacity(0.03)
..strokeWidth = 1;
const step = 50.0;
// Vertical lines
for (double x = 0; x <= size.width; x += step) {
canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint);
}
// Horizontal lines
for (double y = 0; y <= size.height; y += step) {
canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
class ScannerPainter extends CustomPainter {
final double scanValue;
ScannerPainter(this.scanValue);
@override
void paint(Canvas canvas, Size size) {
final y = size.height * scanValue;
final paint = Paint()
..shader = LinearGradient(
colors: [Colors.cyanAccent.withOpacity(0), Colors.cyanAccent.withOpacity(0.3), Colors.cyanAccent.withOpacity(0)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
).createShader(Rect.fromLTWH(0, y - 50, size.width, 100));
canvas.drawRect(Rect.fromLTWH(0, y - 25, size.width, 50), paint);
final linePaint = Paint()
..color = Colors.cyanAccent.withOpacity(0.5)
..strokeWidth = 1;
canvas.drawLine(Offset(0, y), Offset(size.width, y), linePaint);
}
@override
bool shouldRepaint(ScannerPainter oldDelegate) => oldDelegate.scanValue != scanValue;
}
class TechRingPainter extends CustomPainter {
final bool isSharing;
TechRingPainter(this.isSharing);
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = size.width / 2 - 5;
final paint = Paint()
..color = isSharing ? Colors.redAccent.withOpacity(0.3) : Colors.cyan.withOpacity(0.2)
..style = PaintingStyle.stroke
..strokeWidth = 2
..strokeCap = StrokeCap.square;
// Dashed outer ring
for (int i = 0; i < 360; i += 10) {
if (i % 20 == 0) continue; // Gap
final x1 = center.dx + radius * math.cos(i * math.pi / 180);
final y1 = center.dy + radius * math.sin(i * math.pi / 180);
final x2 = center.dx + (radius - 10) * math.cos(i * math.pi / 180);
final y2 = center.dy + (radius - 10) * math.sin(i * math.pi / 180);
canvas.drawLine(Offset(x1, y1), Offset(x2, y2), paint);
}
}
@override
bool shouldRepaint(TechRingPainter oldDelegate) => oldDelegate.isSharing != isSharing;
}
class PowerCirclePainter extends CustomPainter {
final double progress;
final bool isSharing;
PowerCirclePainter({required this.progress, required this.isSharing});
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = size.width / 2;
// Background Ring
final bgPaint = Paint()
..color = Colors.grey.withOpacity(0.1)
..style = PaintingStyle.stroke
..strokeWidth = 12;
canvas.drawCircle(center, radius, bgPaint);
// Gradient Arc
final rect = Rect.fromCircle(center: center, radius: radius);
final gradient = SweepGradient(
startAngle: -math.pi / 2,
endAngle: -math.pi / 2 + (math.pi * 2),
colors: isSharing
? [Colors.cyanAccent, Colors.purpleAccent, Colors.blueAccent, Colors.cyanAccent]
: [Colors.purpleAccent.withOpacity(0.5), Colors.deepPurple, Colors.purpleAccent.withOpacity(0.5)],
tileMode: TileMode.repeated,
);
final arcPaint = Paint()
..shader = gradient.createShader(rect)
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round
..strokeWidth = 12;
// Draw the progress arc
// If scanning, maybe show a full ring rotating? Or just the power level.
// Let's stick to power level.
canvas.drawArc(
rect,
-math.pi / 2,
math.pi * 2 * (progress > 0.01 ? progress : 0.01),
false,
arcPaint
);
// Internal Ticks
final tickPaint = Paint()
..color = isSharing ? Colors.cyanAccent.withOpacity(0.8) : Colors.purpleAccent.withOpacity(0.3)
..strokeWidth = 2;
for (int i = 0; i < 40; i++) {
final angle = (i * 9) * (math.pi / 180) - math.pi/2;
final p1 = Offset(
center.dx + (radius - 25) * math.cos(angle),
center.dy + (radius - 25) * math.sin(angle)
);
final p2 = Offset(
center.dx + (radius - 15) * math.cos(angle),
center.dy + (radius - 15) * math.sin(angle)
);
canvas.drawLine(p1, p2, tickPaint);
}
}
@override
bool shouldRepaint(PowerCirclePainter oldDelegate) => oldDelegate.progress != progress || oldDelegate.isSharing != isSharing;
}
Comments
Post a Comment