Flutter 3 d rotation
Flutter Tranform is used to transform graphics, and PageView is used to control pagination. With four pages, the percentage of rotation between the four pages is about 0.25.
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
PageController _pageController = PageController(initialPage: 1);
double animationRotationValue = 0;
double screenWidth = 0;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 2)); _pageController.addListener(() {if(_pageController.page == 0) { // Loop scrolling
_pageController.jumpToPage(4);
}
if(_pageController.page == 5) { // Loop scrolling
_pageController.jumpToPage(1);
}
double offset = _pageController.offset / screenWidth * 0.25;
setState(() {
animationRotationValue = offset * math.pi * 2;
});
});
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
bool isOnLeft(double rotation) => math.cos(rotation) > 0;
@override
Widget build(BuildContext context) {
final numberOfTexts = 4;
final size = MediaQuery.of(context).size;
screenWidth = size.width;
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Positioned.fill(
child: Container(
width: double.infinity,
height: double.infinity,
child: Stack(
alignment: Alignment.center,
children: List.generate(
numberOfTexts,
(index) {
return AnimatedBuilder(
animation: _animationController,
child: Container(
height: 300,
width: 200,
alignment: Alignment.center,
child: Transform( /// Turn over the pagetransform: Matrix4.identity() .. setEntry(3.2.0.001)
..translate(20.0)
..rotateY(math.pi),
child: Text("$index", style: TextStyle(fontSize: 30, color: Colors.white, fontWeight: FontWeight.bold),),
),
decoration: BoxDecoration(
color: Colors.white,
gradient: LinearGradient(
colors: [
Colors.transparent,
Colors.blue.withOpacity(0.9),
Colors.transparent
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
stops: [0.0.0.1],
),
),
),
builder: (context, child) {
double rotation = 2 * math.pi * index / numberOfTexts +
math.pi / 2 +
animationRotationValue;
// if (isOnLeft(rotation)) {
// rotation = -rotation +
// 2 * animationRotationValue -
// math.pi * 2 / numberOfTexts;
// }
returnTransform( alignment: Alignment.center, transform: Matrix4.identity() .. setEntry(3.2.0.001).. rotateY(rotation) .. translate(. 0.0.0.150.0) , child: child ); }); }, ), ), ), ), Positioned.fill( child: PageView.builder( itemCount: numberOfTexts +2,
controller: _pageController,
itemBuilder: (context, index) {
returnContainer(); }))],),),); }}Copy the code