import 'dart:math';
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math.dart' show radians;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox.expand(
child: RadialMenu(),
),
),
);
}
}
class RadialMenu extends StatefulWidget {
@override
_RadialMenuState createState() => _RadialMenuState();
}
class _RadialMenuState extends State<RadialMenu>
with SingleTickerProviderStateMixin {
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: Duration(milliseconds: 900),
vsync: this,
);
}
@override
Widget build(BuildContext context) {
return RadialAnimetion(
controller: controller,
);
}
}
class RadialAnimetion extends StatelessWidget {
RadialAnimetion({Key key, this.controller})
: scale = Tween<double>(
begin: 1.0,
end: 0.0,
).animate(
CurvedAnimation(
parent: controller,
curve: Curves.fastOutSlowIn,
),
),
translation = Tween<double>(
begin: 0.0,
end: 100.0,
).animate(
CurvedAnimation(
parent: controller,
curve: Curves.linear,
),
),
rotation = Tween<double>(
begin: 0.0,
end: 360.0,
).animate(
CurvedAnimation(
parent: controller,
curve: Interval(0.0, 0.8), // 到80%结束
),
),
super(key: key);
final AnimationController controller;
final Animation<double> scale;
final Animation<double> translation;
final Animation<double> rotation;
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: controller,
builder: (context, builder) {
return Transform.rotate(
angle: radians(rotation.value),
child: Stack(
alignment: Alignment.center,
children: <Widget>[
_buildButton(0, color: Colors.orange, icon: Icons.cloud_upload),
_buildButton(45, color: Colors.yellow, icon: Icons.comment),
_buildButton(90, color: Colors.pink, icon: Icons.color_lens),
_buildButton(135, color: Colors.green, icon: Icons.date_range),
_buildButton(180, color: Colors.blueGrey, icon: Icons.details),
_buildButton(225,
color: Colors.purple, icon: Icons.do_not_disturb_on),
_buildButton(270, color: Colors.lime, icon: Icons.drafts),
_buildButton(315,
color: Colors.indigo, icon: Icons.error_outline),
Transform.scale(
scale: scale.value - 1,
child: FloatingActionButton(
child: Icon(Icons.close),
onPressed: _close,
backgroundColor: Colors.red,
),
),
Transform.scale(
scale: scale.value,
child: FloatingActionButton(
child: Icon(Icons.menu),
onPressed: _open,
backgroundColor: Colors.blue,
),
),
],
),
);
},
);
}
_buildButton(double angle, {Color color, IconData icon}) {
// 将[度]转换为弧度。
final double rad = radians(angle);
return Transform(
transform: Matrix4.identity()
..translate(
translation.value * cos(rad),
translation.value * sin(rad),
),
child: FloatingActionButton(
backgroundColor: color,
child: Icon(icon),
onPressed: () {},
),
);
}
_open() {
controller.forward();
}
_close() {
controller.reverse();
}
}
原文地址:https://www.cnblogs.com/ajanuw/p/11127141.html
时间: 2024-10-16 14:25:24