Files
app/wei_ai_app/lib/screens/control/free_control_screen.dart
2026-01-28 19:10:19 +08:00

206 lines
8.1 KiB
Dart

import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lucide_icons/lucide_icons.dart';
class FreeControlScreen extends StatefulWidget {
const FreeControlScreen({super.key});
@override
State<FreeControlScreen> createState() => _FreeControlScreenState();
}
class _FreeControlScreenState extends State<FreeControlScreen> {
double _intensity = 0;
bool _isClimax = false;
void _handleInteraction(Offset localPosition, double height) {
final relativeY = 1 - (localPosition.dy / height).clamp(0.0, 1.0);
setState(() => _intensity = (relativeY * 100).roundToDouble());
}
void _handleClimax() {
if (_isClimax) return;
setState(() {
_isClimax = true;
_intensity = 100;
});
HapticFeedback.heavyImpact();
Future.delayed(const Duration(seconds: 3), () {
if (mounted) {
setState(() {
_isClimax = false;
_intensity = 20;
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF2E1065),
body: SafeArea(
child: Column(
children: [
// Header
Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 16, 16),
child: Row(
children: [
IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: Icon(LucideIcons.chevronLeft, color: Colors.white.withOpacity(0.7)),
),
const Text(
'自由操控',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
),
// Control Area
Expanded(
child: Center(
child: LayoutBuilder(
builder: (context, constraints) {
final controlHeight = constraints.maxHeight * 0.65;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onPanUpdate: (details) {
_handleInteraction(details.localPosition, controlHeight);
},
onTapDown: (details) {
_handleInteraction(details.localPosition, controlHeight);
},
child: Container(
width: 180,
height: controlHeight,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.05),
borderRadius: BorderRadius.circular(32),
border: Border.all(color: Colors.white.withOpacity(0.2)),
),
child: Stack(
children: [
// Fill Level
Align(
alignment: Alignment.bottomCenter,
child: AnimatedContainer(
duration: const Duration(milliseconds: 50),
width: double.infinity,
height: controlHeight * (_intensity / 100),
decoration: BoxDecoration(
color: _isClimax
? Colors.red.withOpacity(0.5)
: const Color(0xFFC084FC).withOpacity(0.5),
borderRadius: BorderRadius.circular(32),
),
),
),
// Labels
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text(
'MAX',
style: TextStyle(
fontSize: 10,
fontFamily: 'monospace',
color: Colors.white.withOpacity(0.4),
),
),
),
Center(
child: Text(
_intensity.toInt().toString(),
style: TextStyle(
fontSize: 48,
fontWeight: FontWeight.bold,
fontFamily: 'monospace',
color: _isClimax ? Colors.red[200] : Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
'OFF',
style: TextStyle(
fontSize: 10,
fontFamily: 'monospace',
color: Colors.white.withOpacity(0.4),
),
),
),
],
),
],
),
),
),
const SizedBox(height: 16),
Text(
'上下滑动触控板以控制强度',
style: TextStyle(
fontSize: 12,
fontFamily: 'monospace',
letterSpacing: 1,
color: Colors.white.withOpacity(0.6),
),
),
],
);
},
),
),
),
// Climax Button
Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 40),
child: GestureDetector(
onTap: _handleClimax,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 18),
decoration: BoxDecoration(
color: _isClimax ? Colors.red : Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: _isClimax ? Colors.red : Colors.red.withOpacity(0.5),
),
),
child: Center(
child: Text(
_isClimax ? 'MAX OUTPUT...' : '一键爆发',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
letterSpacing: 2,
color: _isClimax ? Colors.white : Colors.red[300],
),
),
),
),
),
),
],
),
),
);
}
}