import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
//定义全局获取颜色的方法
Color getRandomWhiteColor(Random random){
//透明度0~200 255是不透明
int a =random.nextInt(200);
return Color.fromARGB(a, 255, 255, 255) ;
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
List<BobbleBean> _list = [];
//随机数
Random _random =new Random(DateTime.now().millisecondsSinceEpoch);
double _maxSpend = 1.0;
double _maxRadius = 100;
double _maxThate = 2*pi;
AnimationController _animationController;
AnimationController _fadeAnimationController;
void initState() {
setState(() {
for(int i=0;i<20;i++){
BobbleBean bean = new BobbleBean();
print(i);
bean.color =getRandomWhiteColor(_random);
//设置位置 先来个默认的
bean.position = Offset(-1,-1);
bean.spend = _random.nextDouble() * _maxSpend;
bean.radius = _random.nextDouble() * _maxRadius;
bean.theta = _random.nextDouble() * _maxThate;
_list.add(bean);
}
//创建动画一秒
_animationController = new AnimationController(vsync: this,duration: Duration(microseconds: 1000));
//执行刷新监听
_animationController.addListener(() {
setState(() {
});
});
//重复执行
// _animationController.repeat();
_fadeAnimationController = new AnimationController(vsync: this,duration: Duration(microseconds: 1800));
//执行刷新监听
_fadeAnimationController.forward();
_fadeAnimationController.addStatusListener((status){
if(status==AnimationStatus.completed){
_animationController.repeat();
}
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Stack(
children: [
//渐变背景
buildBackground(),
//气泡
buildBobbleWidget(context),
//高斯模糊
buildBlurWidget(),
buildBottomWidget(context),
],
),
)
);
}
buildBobbleWidget(BuildContext context){
return CustomPaint(
size:MediaQuery.of(context).size,
painter: CustomMyPainter(list:_list,random:_random),
);
}
buildBlurWidget(){
return BackdropFilter(
filter: ImageFilter.blur(sigmaX: .3,sigmaY: .3),
child: Container(
color: Colors.white.withOpacity(0.1),
),
);
}
buildBottomWidget(BuildContext context){
return Positioned(
bottom: 80,left: 40,right: 40,
child:FadeTransition(
opacity: _fadeAnimationController,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFileWidget(
obscuretext:false,
labelText:'账号',
prefixIconData:Icons.phone_android
),
SizedBox(
height: 14,
),
TextFileWidget(
obscuretext:true,
labelText:'密码',
suffixIconData: Icons.visibility,
prefixIconData:Icons.lock_outline
),
// Container(
// height: 38,
// width: double.infinity,
// child: ElevatedButton(
//
// ),
// )
],
),
)
);
}
}
class TextFileWidget extends StatelessWidget {
Function(String value) onChanged;
bool obscuretext;
String labelText;
IconData prefixIconData;
IconData suffixIconData;
TextFileWidget({this.onChanged,this.labelText,this.obscuretext,this.suffixIconData,this.prefixIconData});
@override
Widget build(BuildContext context) {
return TextField(
onChanged: onChanged,
obscureText: obscuretext,
style: TextStyle(
color: Colors.blue,
fontSize: 14,
),
decoration: InputDecoration(
filled: true,
labelText: labelText,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.blue)
),
prefixIcon: Icon(prefixIconData,size: 18,color:Colors.blue,),
suffixIcon: Icon(suffixIconData,size: 18,color:Colors.blue,)
),
);
}
}
class CustomMyPainter extends CustomPainter{
List<BobbleBean> list = [];
Random random;
CustomMyPainter({this.list, this.random});
//先来个画笔
Paint _paint = new Paint()..isAntiAlias = true;
@override
void paint(Canvas canvas,Size size){
//绘制前重新计算每个点的位置
list.forEach((element) {
Offset newCenterOffset = calcuLateXy(element.spend,element.theta);
double dx = newCenterOffset.dx+element.position.dx;
double dy = newCenterOffset.dy+element.position.dy;
if(dx <0||dx>size.width){
dx = random.nextDouble()*size.width;
}
if(dy <0||dx>size.height){
dy = random.nextDouble()*size.height;
}
element.position =Offset(dx,dy);
});
list.forEach((element) {
_paint.color = element.color;
canvas.drawCircle(element.position, element.radius, _paint);
});
}
@override
bool shouldRepaint(covariant CustomMyPainter oldDelegate){
//返回false 不刷新
return true;
}
Offset calcuLateXy(double spend ,double theta){
return Offset(spend*cos(theta),spend*sin(theta));
}
}
class buildBackground extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient:LinearGradient(
begin:Alignment.topLeft,
end:Alignment.bottomRight,
colors: [
Colors.lightBlueAccent.withOpacity(0.3),
Colors.lightBlue.withOpacity(0.3),
Colors.blue.withOpacity(0.3)
]
)
),
);
}
}
class BobbleBean{
//位置
Offset position;
//颜色
Color color;
//速度
double spend;
double theta;
double radius;
}
flutter 好看的动画登陆页学习
于 2020-11-23 11:54:44 首次发布