Add scroll physics demo (#123)

* add spring physics card demo

* fix button colors in animations project

* code review updates

* refactor method into runAnimation

* combine updateAnimation and runAnimation

* update comment
pull/125/head
John Ryan 5 years ago committed by GitHub
parent cc0c0dadd2
commit b51d75966a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,6 +14,7 @@ import 'src/misc/card_swipe.dart';
import 'src/misc/carousel.dart';
import 'src/misc/expand_card.dart';
import 'src/misc/focus_image.dart';
import 'src/misc/physics_card_drag.dart';
import 'src/misc/repeating_animation.dart';
void main() => runApp(AnimationSamples());
@ -48,6 +49,8 @@ final miscDemos = [
Demo('Card Swipe', CardSwipeDemo.routeName, (context) => CardSwipeDemo()),
Demo('Repeating Animation', RepeatingAnimationDemo.routeName,
(context) => RepeatingAnimationDemo()),
Demo('Spring Physics', PhysicsCardDragDemo.routeName,
(context) => PhysicsCardDragDemo()),
];
final basicDemoRoutes =

@ -9,7 +9,6 @@ class PageRouteBuilderDemo extends StatelessWidget {
body: Center(
child: RaisedButton(
child: Text('Go!'),
color: Theme.of(context).primaryColor,
onPressed: () {
Navigator.of(context).push(_createRoute());
},

@ -43,12 +43,13 @@ class _CustomTweenDemoState extends State<CustomTweenDemo>
return Scaffold(
appBar: AppBar(
actions: [
RaisedButton(
MaterialButton(
child: Text(
controller.status == AnimationStatus.completed
? 'Delete Essay'
: 'Write Essay',
),
textColor: Colors.white,
onPressed: () {
if (controller.status == AnimationStatus.completed) {
controller.reverse();

@ -0,0 +1,117 @@
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
class PhysicsCardDragDemo extends StatelessWidget {
static const String routeName = '/misc/physics_card';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: DraggableCard(
child: FlutterLogo(
size: 128,
),
),
);
}
}
/// A draggable card that moves back to [Alignment.center] when it's
/// released.
class DraggableCard extends StatefulWidget {
final Widget child;
DraggableCard({this.child});
@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;
/// Calculates and runs a [SpringSimulation]
void _runAnimation(Offset pixelsPerSecond, Size size) {
_animation = _controller.drive(
AlignmentTween(
begin: _dragAlignment,
end: Alignment.center,
),
);
// 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(
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);
_controller.addListener(() {
setState(() {
_dragAlignment = _animation.value;
});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final 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,
),
),
);
}
}
Loading…
Cancel
Save