Created
March 5, 2021 19:44
-
-
Save lecuseasar/29abd49ba555b19edbaa9fa9caa55e32 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter/physics.dart'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Material App', | |
home: PhysicsCardDrag(), | |
); | |
} | |
} | |
class PhysicsCardDrag extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(), | |
body: Stack( | |
children: [ | |
DraggableCard( | |
child: FlutterLogo(size: 256), | |
endAlignment: Alignment.topLeft, | |
), | |
DraggableCard( | |
child: FlutterLogo(size: 256), | |
endAlignment: Alignment.topCenter, | |
), | |
DraggableCard( | |
child: FlutterLogo(size: 256), | |
endAlignment: Alignment.topRight, | |
), | |
DraggableCard( | |
child: FlutterLogo(size: 256), | |
endAlignment: Alignment.bottomLeft, | |
), | |
DraggableCard( | |
child: FlutterLogo(size: 256), | |
endAlignment: Alignment.bottomCenter, | |
), | |
DraggableCard( | |
child: FlutterLogo(size: 256), | |
endAlignment: Alignment.bottomRight, | |
), | |
], | |
), | |
); | |
} | |
} | |
/// A draggable card that moves back to [Alignment.center] when it's | |
/// released. | |
class DraggableCard extends StatefulWidget { | |
final Widget child; | |
final Alignment endAlignment; | |
const DraggableCard({ | |
Key key, | |
this.child, | |
this.endAlignment, | |
}) : super(key: key); | |
@override | |
_DraggableCardState createState() => _DraggableCardState(); | |
} | |
class _DraggableCardState extends State<DraggableCard> with SingleTickerProviderStateMixin { | |
AnimationController _controller; | |
/// The alignment of the card as it is dragged or being animated. | |
/// While the card is being dragged, this value is set to the values computed | |
/// in the GestureDetector onPanUpdate callback. If the animation is running, | |
/// this value is set to the value of the [_animation]. | |
Alignment _dragAlignment = Alignment.center; | |
Animation<Alignment> _animation; | |
void _runAnimation(Offset pixelsPerSecond, Size size) { | |
_animation = _controller.drive( | |
AlignmentTween( | |
begin: _dragAlignment, | |
end: widget.endAlignment, | |
), | |
); | |
// _controller.reset(); | |
// _controller.forward(); | |
// Calculate the velocity relative to the unit interval, [0,1], | |
// used by the animation controller. | |
final unitsPerSecondX = pixelsPerSecond.dx / size.width; | |
final unitsPerSecondY = pixelsPerSecond.dy / size.height; | |
final unitsPerSecond = Offset(unitsPerSecondX, unitsPerSecondY); | |
final unitVelocity = unitsPerSecond.distance; | |
const spring = SpringDescription( | |
// * change | |
mass: 30, | |
stiffness: 1, | |
damping: 1, | |
); | |
final simulation = SpringSimulation(spring, 0, 1, -unitVelocity); | |
_controller.animateWith(simulation); | |
} | |
@override | |
void initState() { | |
super.initState(); | |
_controller = AnimationController(vsync: this, duration: Duration(seconds: 1)); | |
_controller.addListener(() { | |
setState(() { | |
_dragAlignment = _animation.value; | |
}); | |
}); | |
} | |
@override | |
void dispose() { | |
_controller.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
var size = MediaQuery.of(context).size; | |
return GestureDetector( | |
onPanDown: (details) { | |
_controller.stop(); | |
}, | |
onPanUpdate: (details) { | |
setState(() { | |
_dragAlignment += Alignment( | |
details.delta.dx / (size.width / 2), | |
details.delta.dy / (size.height / 2), | |
); | |
}); | |
}, | |
onPanEnd: (details) { | |
_runAnimation(details.velocity.pixelsPerSecond, size); | |
}, | |
child: Align( | |
alignment: _dragAlignment, | |
child: Card( | |
child: widget.child, | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment