import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'Components/custom_clipper.dart'; import 'constants.dart'; void main() { String initialRoute; initialRoute = '/home'; final MyApp myApp = MyApp( initialRoute: initialRoute, //context: localContext, ); runApp(myApp); } class MyApp extends StatefulWidget { final String initialRoute; //final Context context; MyApp({this.initialRoute}); // This widget is the root of your application. @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Tablet App Demo', initialRoute: widget.initialRoute, /*supportedLocales: [ const Locale('en', 'US'), const Locale('fr', 'FR'), ],*/ theme: ThemeData( primarySwatch: Colors.grey, scaffoldBackgroundColor: kBackgroundGrey, //fontFamily: "Vollkorn", textTheme: TextTheme(bodyText1: TextStyle(color: kMainRed)), visualDensity: VisualDensity.adaptivePlatformDensity, ), routes: { '/home': (context) => MyHomePage(title: 'Tablet App Demo Home Page') } ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State with TickerProviderStateMixin { int _counter = 0; Size sizeScreen = new Size(1080.0, 1920.0); // Tablet resolution double elementMinimizedSize = 200.0; double elementMaximizedSize = 400.0; bool minimized = false; double _leftMain; double _topMain; double _rightMain; double _bottomMain; double _leftTitle; double _topTitle; double _rightTitle; double _bottomTitle; double _leftElement; double _topElement; double _rightElement; double _bottomElement; double _leftMenu; double _topMenu; double _rightMenu; double _bottomMenu; AnimationController _controller; Completer _webViewController = Completer(); @override void initState() { setState(() { _leftMain = (sizeScreen.height / 2) - elementMaximizedSize; _topMain = (sizeScreen.width / 2) - elementMaximizedSize; _rightMain = (sizeScreen.height / 2) - elementMaximizedSize; _bottomMain = (sizeScreen.width / 2) - elementMaximizedSize; _leftElement = (sizeScreen.height/2)-elementMaximizedSize; _topElement = (sizeScreen.width/2)-elementMaximizedSize; _rightElement = (sizeScreen.height/2); _bottomElement = (sizeScreen.width/2); _leftMenu = 0; _topMenu = sizeScreen.width * 0.15; _rightMenu = sizeScreen.height; _bottomMenu = sizeScreen.width * 0.2; _leftTitle = 0; _topTitle = 0; _rightTitle = sizeScreen.height; _bottomTitle = sizeScreen.width; }); _controller = AnimationController(value: 12, vsync: this, duration: Duration(seconds: 1)); _controller.animateBack(0); super.initState(); } void _incrementCounter() { setState(() { _counter++; minimized = !minimized; if (minimized) { _controller.animateBack(5.0); } else { _controller.animateBack(0.0); } _leftMenu = 0; _topMenu = sizeScreen.width * 0.18; _rightMenu = minimized ? sizeScreen.height - elementMinimizedSize : sizeScreen.height; _bottomMenu = minimized ? sizeScreen.width * 0.2 : sizeScreen.width * 0.2; _leftMain = minimized ? 0 : (sizeScreen.height/2)-elementMaximizedSize; _topMain = minimized ? sizeScreen.width-elementMinimizedSize : (sizeScreen.width/2)-elementMaximizedSize; _rightMain = minimized ? sizeScreen.height-elementMinimizedSize : (sizeScreen.height/2)-elementMaximizedSize; _bottomMain = minimized ? 0 : (sizeScreen.width/2)-elementMaximizedSize; _leftElement = minimized ? sizeScreen.height * 0.11 : (sizeScreen.height/2)-elementMaximizedSize; _topElement = minimized ? 0 : (sizeScreen.width/2)-elementMaximizedSize; _rightElement = minimized ? 0 : (sizeScreen.height/2); _bottomElement = minimized ? 0 : (sizeScreen.width/2); _leftTitle = 0; _topTitle = 0; _rightTitle = minimized ? sizeScreen.height - elementMinimizedSize : sizeScreen.height; _bottomTitle = minimized ? sizeScreen.width * 0.83 : sizeScreen.width; }); } Future _onWillPop() async { return false; } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { SystemChrome.setEnabledSystemUIOverlays([]); Size size = MediaQuery.of(context).size; return new WillPopScope( onWillPop: _onWillPop, child: Scaffold( // Tablet size body: Container( height: size.height, width: size.width, child: Stack( children: [ // Main AnimatedPositioned( duration: const Duration(milliseconds: 1500), curve: Curves.easeInOutSine, left: _leftMain, top: _topMain, right: _rightMain, bottom: _bottomMain, child: InkWell( onTap: () { if (minimized) _incrementCounter(); }, child: Container( decoration: BoxDecoration( borderRadius: new BorderRadius.only( topRight: const Radius.circular(20.0), ), color: kSecondRed ), child: Center( child: Text( 'MAIN MENU', style: TextStyle(color: kTextRed, fontSize: 25), ), ), ), ), ), // Title opened AnimatedPositioned( duration: const Duration(milliseconds: 1500), curve: Curves.easeInOutSine, left: _leftTitle, top: _topTitle, right: _rightTitle, bottom: _bottomTitle, child: InkWell( onTap: () { if (minimized) _incrementCounter(); }, child: Container( decoration: BoxDecoration( borderRadius: new BorderRadius.only( bottomRight: const Radius.circular(20.0), ), color: kSecondRed ), child: Center( child: Text( 'Title opened element', style: TextStyle(color: kTextRed, fontSize: 25), ), ), ), ), ), // Element AnimatedPositioned( duration: const Duration(milliseconds: 1000), curve: Curves.easeInOutSine, top: _topElement, left: _leftElement, right: _rightElement, bottom: _bottomElement, child: Padding( padding: const EdgeInsets.all(5.0), child: AnimatedBuilder( animation: _controller, builder: (BuildContext context, Widget child) { return ClipPath( clipper: WaveClipper(move: _controller.value, minimized: minimized, height: _leftMain, width: _topMain), clipBehavior: Clip.hardEdge, child: InkWell( onTap: () => { if (!minimized) _incrementCounter() }, child: AnimatedContainer( // Define how long the animation should take. duration: Duration(seconds: 2), // Provide an optional curve to make the animation feel smoother. curve: Curves.easeInOutCubic, height: elementMaximizedSize, width: elementMaximizedSize, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.0), gradient: LinearGradient( begin: Alignment.centerRight, end: Alignment.centerLeft, colors: [ minimized ? kBackgroundSecondGrey : kSecondGrey, minimized ? kBackgroundSecondGrey : Colors.transparent ], ), ), child: Center( child: Padding( padding: const EdgeInsets.all(20.0), child: Container( width: size.width, height: size.height, child: WebView( initialUrl: "https://my.matterport.com/show/?m=k8bvdezfHbT", javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController webViewController) { _webViewController.complete(webViewController); }, navigationDelegate: (NavigationRequest request) { if (request.url != "https://my.matterport.com/show/?m=k8bvdezfHbT") { print('blocking navigation to $request}'); return NavigationDecision.prevent; } print('allowing navigation to $request'); return NavigationDecision.navigate; }, )), ), ), ), ), ); }, ), ), ), // MENU AnimatedPositioned( duration: const Duration(milliseconds: 2000), curve: Curves.easeInOutSine, top: _topMenu, left: _leftMenu, right: _rightMenu, bottom: _bottomMenu, child: Container( decoration: BoxDecoration( borderRadius: new BorderRadius.only( topRight: const Radius.circular(20.0), bottomRight: const Radius.circular(20.0), ), color: Colors.lightBlue ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Text('MENU'), Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text('Sub menu 1'), Text('Sub menu 2'), ] ) ] ), /*Icon( Icons.autorenew, color: Colors.pink, size: 24.0, semanticLabel: 'Text to announce in accessibility modes', ),*/ ), ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ), ); } }