mirror of https://github.com/flutter/samples.git
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 commentpull/125/head
parent
cc0c0dadd2
commit
b51d75966a
@ -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…
Reference in new issue