Guest User

Untitled

a guest
Aug 17th, 2019
64
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import 'dart:ui';
  2.  
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/rendering.dart';
  5.  
  6. class TiltableStack extends StatefulWidget {
  7. final List<Widget> children;
  8. final Alignment alignment;
  9.  
  10. const TiltableStack({
  11. Key key,
  12. this.children,
  13. this.alignment = Alignment.center,
  14. }) : super(key: key);
  15.  
  16. @override
  17. _TiltableStackState createState() => _TiltableStackState();
  18. }
  19.  
  20. class _TiltableStackState extends State<TiltableStack>
  21. with SingleTickerProviderStateMixin {
  22. AnimationController _controller;
  23. Animation<double> tilt;
  24. Animation<double> depth;
  25. double pitch = 0;
  26. double yaw = 0;
  27.  
  28. @override
  29. void initState() {
  30. super.initState();
  31. _controller = AnimationController(
  32. duration: const Duration(milliseconds: 500), vsync: this)
  33. ..addListener(() {
  34. setState(() {
  35. if (tilt != null) {
  36. pitch *= tilt.value;
  37. yaw *= tilt.value;
  38. }
  39. });
  40. })
  41. ..forward(from: 1.0);
  42. }
  43.  
  44. @override
  45. dispose() {
  46. super.dispose();
  47. _controller.dispose();
  48. }
  49.  
  50. cancelPan() {
  51. tilt = Tween<double>(
  52. begin: 1.0,
  53. end: 0.0,
  54. ).animate(
  55. CurvedAnimation(
  56. parent: _controller,
  57. curve: Curves.elasticIn.flipped,
  58. ),
  59. );
  60. depth = tilt;
  61. _controller.forward();
  62. }
  63.  
  64. startPan() {
  65. tilt = null;
  66. depth = Tween<double>(
  67. begin: 1.0,
  68. end: 0.0,
  69. ).animate(
  70. CurvedAnimation(
  71. parent: _controller,
  72. curve: const Cubic(1.0, 0.0, 1.0, 1.0),
  73. ),
  74. );
  75. _controller.reverse();
  76. }
  77.  
  78. updatePan(DragUpdateDetails drag) {
  79. setState(() {
  80. var size = MediaQuery.of(context).size;
  81. pitch += drag.delta.dy * (1 / size.height);
  82. yaw -= drag.delta.dx * (1 / size.width);
  83. });
  84. }
  85.  
  86. @override
  87. Widget build(BuildContext context) {
  88. return GestureDetector(
  89. onPanUpdate: updatePan,
  90. onPanEnd: (_) => cancelPan(),
  91. onPanCancel: cancelPan,
  92. onPanDown: (_) => startPan(),
  93. child: Stack(
  94. alignment: widget.alignment,
  95. children: widget.children
  96. .asMap()
  97. .map(
  98. (i, element) {
  99. return MapEntry(
  100. i,
  101. Stack(
  102. alignment: Alignment.center,
  103. children: [
  104. Transform(
  105. transform: Matrix4.identity()
  106. ..setEntry(3, 2, 0.001)
  107. ..rotateX(pitch)
  108. ..rotateY(yaw)
  109. ..translate(-yaw * i * 70, pitch * i * 70, 0)
  110. ..scale((depth?.value ?? 0) * (i + 1) * 0.1 + 1),
  111. child: element,
  112. alignment: FractionalOffset.center,
  113. ),
  114. ],
  115. ),
  116. );
  117. },
  118. )
  119. .values
  120. .toList(),
  121. ),
  122. );
  123. }
  124. }
RAW Paste Data