SHARE
TWEET

Untitled

a guest Aug 17th, 2019 63 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top