Skip to content

Instantly share code, notes, and snippets.

@monkeyswarm
Last active July 15, 2021 17:02
Show Gist options
  • Save monkeyswarm/534239c5fe292e730b6f39f26b9ab943 to your computer and use it in GitHub Desktop.
Save monkeyswarm/534239c5fe292e730b6f39f26b9ab943 to your computer and use it in GitHub Desktop.
Flingy containers
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
final totalHeight = 600.0;
final minimizedHeight = 100.0;
final maximizedHeight = 400.0;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter 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<MyHomePage>
with SingleTickerProviderStateMixin {
double _sliderValue = 0;
AnimationController _animationController;
Animation<double> _topHeightAnimation;
Animation<double> _middleHeightAnimation;
Animation<double> _bottomHeightAnimation;
@override
void initState() {
_animationController = AnimationController(
vsync: this, duration: Duration(seconds: 1), value: 0.5);
_topHeightAnimation =
Tween<double>(begin: minimizedHeight, end: maximizedHeight).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
0.5, 1.0,
// curve: Curves.ease,
),
),
);
_middleHeightAnimation = TweenSequence<double>(
<TweenSequenceItem<double>>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: minimizedHeight, end: maximizedHeight),
weight: 1.0),
TweenSequenceItem<double>(
tween: Tween<double>(begin: maximizedHeight, end: minimizedHeight),
weight: 1.0),
],
).animate(_animationController);
_bottomHeightAnimation =
Tween<double>(begin: maximizedHeight, end: minimizedHeight).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
0.0,
0.5,
),
),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Fling amount:'),
Slider(
value: _sliderValue,
onChanged: (value) => setState(() => _sliderValue = value))
],
)),
Container(
height: totalHeight,
color: Color(0xFF444444),
child: GestureDetector(
onPanStart: (dragStart) {
_animationController.stop();
},
onPanUpdate: (DragUpdateDetails dragUpdate) {
//down is pos
_animationController.value = (_animationController.value +
dragUpdate.delta.dy / totalHeight)
.clamp(0.0, 1.0);
},
onPanEnd: (dragEnd) {
final double flingVelocity =
dragEnd.velocity.pixelsPerSecond.dy / totalHeight;
final currVal = _animationController.value;
final scaledFling =
flingVelocity * _sliderValue * _sliderValue;
final restVal =
((currVal + scaledFling.clamp(-.5, .5)) * 2).round() / 2;
// print(
// 'DEI pr vel ${dragEnd.velocity.pixelsPerSecond.dy} fl vel $flingVelocity');
// print(
// 'DEI pos ${_animationController.value} dest $restVal dsign ${(restVal - _animationController.value).sign} flingvel $flingVelocity');
const spring = SpringDescription(
mass: 30,
stiffness: 1,
damping: 1,
);
final simulation = SpringSimulation(spring,
_animationController.value, restVal, flingVelocity);
_animationController.animateWith(simulation);
},
child: AnimatedBuilder(
animation: _animationController,
builder: (BuildContext context, Widget child) => Column(
children: [
Container(
height: _topHeightAnimation.value,
color: (Color(0xFFFF0000))),
Container(
height: _middleHeightAnimation.value,
color: (Color(0xFF00FF00))),
Container(
height: _bottomHeightAnimation.value,
color: (Color(0xFF0000FF))),
],
))))
],
));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment