Commit 7724dc75 authored by Matt Perry's avatar Matt Perry

apply.patch

parent 633b6501
...@@ -11,6 +11,7 @@ dart_pkg("sky") { ...@@ -11,6 +11,7 @@ dart_pkg("sky") {
"lib/animation/animated_simulation.dart", "lib/animation/animated_simulation.dart",
"lib/animation/animation_performance.dart", "lib/animation/animation_performance.dart",
"lib/animation/curves.dart", "lib/animation/curves.dart",
"lib/animation/forces.dart",
"lib/animation/scroll_behavior.dart", "lib/animation/scroll_behavior.dart",
"lib/animation/timeline.dart", "lib/animation/timeline.dart",
"lib/assets/.gitignore", "lib/assets/.gitignore",
......
...@@ -2,9 +2,11 @@ ...@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:newton/newton.dart'; import 'dart:async';
import 'package:sky/animation/timeline.dart'; import 'package:sky/animation/timeline.dart';
import 'package:sky/animation/curves.dart'; import 'package:sky/animation/curves.dart';
import 'package:sky/animation/forces.dart';
abstract class AnimatedVariable { abstract class AnimatedVariable {
void setFraction(double t); void setFraction(double t);
...@@ -99,23 +101,20 @@ class AnimationPerformance { ...@@ -99,23 +101,20 @@ class AnimationPerformance {
bool get isCompleted => progress == 1.0; bool get isCompleted => progress == 1.0;
bool get isAnimating => timeline.isAnimating; bool get isAnimating => timeline.isAnimating;
void play() { Future play() => _animateTo(1.0);
_animateTo(1.0); Future reverse() => _animateTo(0.0);
}
void reverse() {
_animateTo(0.0);
}
void stop() { void stop() {
timeline.stop(); timeline.stop();
} }
// Resume animating in a direction, with the given velocity. // Flings the timeline with an optional force (defaults to a critically damped
// TODO(mpcomplete): Allow user to specify the Simulation. // spring) and initial velocity. Negative velocity causes the timeline to go
void fling({double velocity: 1.0}) { // in reverse.
Simulation simulation = Future fling({double velocity: 1.0, Force force}) {
timeline.defaultSpringSimulation(velocity: velocity); if (force == null)
timeline.fling(simulation); force = kDefaultSpringForce;
return timeline.fling(force.release(progress, velocity));
} }
final List<Function> _listeners = new List<Function>(); final List<Function> _listeners = new List<Function>();
...@@ -134,11 +133,12 @@ class AnimationPerformance { ...@@ -134,11 +133,12 @@ class AnimationPerformance {
listener(); listener();
} }
void _animateTo(double target) { Future _animateTo(double target) {
double remainingDistance = (target - timeline.value).abs(); double remainingDistance = (target - timeline.value).abs();
timeline.stop(); timeline.stop();
if (remainingDistance != 0.0) if (remainingDistance == 0.0)
timeline.animateTo(target, duration: duration * remainingDistance); return new Future.value();
return timeline.animateTo(target, duration: duration * remainingDistance);
} }
void _tick(double t) { void _tick(double t) {
......
...@@ -5,10 +5,11 @@ ...@@ -5,10 +5,11 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'package:newton/newton.dart'; import 'package:newton/newton.dart';
import 'package:sky/animation/forces.dart';
const double _kSecondsPerMillisecond = 1000.0; const double _kSecondsPerMillisecond = 1000.0;
abstract class ScrollBehavior { abstract class ScrollBehavior extends Force {
Simulation release(double position, double velocity) => null; Simulation release(double position, double velocity) => null;
// Returns the new scroll offset. // Returns the new scroll offset.
......
...@@ -7,8 +7,6 @@ import 'dart:async'; ...@@ -7,8 +7,6 @@ import 'dart:async';
import 'package:newton/newton.dart'; import 'package:newton/newton.dart';
import 'package:sky/animation/animated_simulation.dart'; import 'package:sky/animation/animated_simulation.dart';
const double _kEpsilon = 0.001;
// Simple simulation that linearly varies from |begin| to |end| over |duration|. // Simple simulation that linearly varies from |begin| to |end| over |duration|.
class TweenSimulation extends Simulation { class TweenSimulation extends Simulation {
final double _durationInSeconds; final double _durationInSeconds;
...@@ -68,17 +66,6 @@ class Timeline { ...@@ -68,17 +66,6 @@ class Timeline {
_animation.stop(); _animation.stop();
} }
static final SpringDescription _kDefaultSpringDesc =
new SpringDescription.withDampingRatio(
mass: 1.0, springConstant: 500.0, ratio: 1.0);
Simulation defaultSpringSimulation({double velocity: 0.0}) {
// Target just past the 0 or 1 endpoint, because the animation will stop
// once the Spring gets within the epsilon, and we want to stop at 0 or 1.
double target = velocity < 0.0 ? -_kEpsilon : 1.0 + _kEpsilon;
return new SpringSimulation(_kDefaultSpringDesc, value, target, velocity);
}
// Give |simulation| control over the timeline. // Give |simulation| control over the timeline.
Future fling(Simulation simulation) { Future fling(Simulation simulation) {
stop(); stop();
......
...@@ -13,6 +13,7 @@ import 'package:vector_math/vector_math.dart'; ...@@ -13,6 +13,7 @@ import 'package:vector_math/vector_math.dart';
const Duration _kCardDismissFadeout = const Duration(milliseconds: 300); const Duration _kCardDismissFadeout = const Duration(milliseconds: 300);
const double _kMinFlingVelocity = 700.0; const double _kMinFlingVelocity = 700.0;
const double _kMinFlingVelocityDelta = 400.0; const double _kMinFlingVelocityDelta = 400.0;
const double _kFlingVelocityScale = 1.0/300.0;
const double _kDismissCardThreshold = 0.6; const double _kDismissCardThreshold = 0.6;
typedef void DismissedCallback(); typedef void DismissedCallback();
...@@ -129,7 +130,7 @@ class Dismissable extends AnimatedComponent { ...@@ -129,7 +130,7 @@ class Dismissable extends AnimatedComponent {
_dragUnderway = false; _dragUnderway = false;
_dragX = event.velocityX.sign; _dragX = event.velocityX.sign;
_position.end = _activeCardDragEndPoint; _position.end = _activeCardDragEndPoint;
_performance.fling(velocity: event.velocityX.abs() / _width); _performance.fling(velocity: event.velocityX.abs() * _kFlingVelocityScale);
} }
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import 'dart:sky' as sky; import 'dart:sky' as sky;
import 'package:sky/animation/animation_performance.dart'; import 'package:sky/animation/animation_performance.dart';
import 'package:sky/animation/curves.dart';
import 'package:sky/theme/shadows.dart'; import 'package:sky/theme/shadows.dart';
import 'package:sky/theme/colors.dart' as colors; import 'package:sky/theme/colors.dart' as colors;
import 'package:sky/widgets/animated_component.dart'; import 'package:sky/widgets/animated_component.dart';
...@@ -30,14 +29,11 @@ import 'package:vector_math/vector_math.dart'; ...@@ -30,14 +29,11 @@ import 'package:vector_math/vector_math.dart';
// The right nav can vary depending on content. // The right nav can vary depending on content.
const double _kWidth = 304.0; const double _kWidth = 304.0;
const double _kMinFlingVelocity = 1.2; const double _kMinFlingVelocity = 365.0;
const double _kFlingVelocityScale = 1.0/300.0;
const Duration _kBaseSettleDuration = const Duration(milliseconds: 246); const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
// TODO(mpcomplete): The curve must be linear if we want the drawer to track
// the user's finger. Odeon remedies this by attaching spring forces to the
// initial timeline when animating (so it doesn't look linear).
const Point _kOpenPosition = Point.origin; const Point _kOpenPosition = Point.origin;
const Point _kClosedPosition = const Point(-_kWidth, 0.0); const Point _kClosedPosition = const Point(-_kWidth, 0.0);
const Curve _kAnimationCurve = linear;
typedef void DrawerStatusChangeHandler (bool showing); typedef void DrawerStatusChangeHandler (bool showing);
...@@ -69,7 +65,7 @@ class Drawer extends AnimatedComponent { ...@@ -69,7 +65,7 @@ class Drawer extends AnimatedComponent {
AnimationPerformance _performance; AnimationPerformance _performance;
void initState() { void initState() {
_position = new AnimatedType<Point>(_kClosedPosition, end: _kOpenPosition, curve: _kAnimationCurve); _position = new AnimatedType<Point>(_kClosedPosition, end: _kOpenPosition);
_maskColor = new AnimatedColor(colors.transparent, end: const Color(0x7F000000)); _maskColor = new AnimatedColor(colors.transparent, end: const Color(0x7F000000));
_performance = new AnimationPerformance() _performance = new AnimationPerformance()
..duration = _kBaseSettleDuration ..duration = _kBaseSettleDuration
...@@ -95,11 +91,18 @@ class Drawer extends AnimatedComponent { ...@@ -95,11 +91,18 @@ class Drawer extends AnimatedComponent {
void _show() { void _show() {
if (navigator != null) if (navigator != null)
navigator.pushState(this, (_) => _performance.reverse()); navigator.pushState(this, (_) => _performance.reverse());
_performance.play(); _fling(1.0);
} }
void _hide() { void _hide() {
_performance.reverse(); _fling(-1.0);
}
// We fling the performance timeline instead of animating it to give it a
// nice spring effect. We can't use curves for this because we need a linear
// curve in order to track the user's finger while dragging.
void _fling(double direction) {
_performance.fling(velocity: direction.sign);
} }
Widget build() { Widget build() {
...@@ -151,9 +154,9 @@ class Drawer extends AnimatedComponent { ...@@ -151,9 +154,9 @@ class Drawer extends AnimatedComponent {
DrawerStatus get _status => _performance.isDismissed ? DrawerStatus.inactive : DrawerStatus.active; DrawerStatus get _status => _performance.isDismissed ? DrawerStatus.inactive : DrawerStatus.active;
bool get _isMostlyClosed => xPosition <= -_kWidth/2; bool get _isMostlyClosed => xPosition <= -_kWidth/2;
void _settle() => _isMostlyClosed ? _performance.reverse() : _performance.play(); void _settle() => _fling(_isMostlyClosed ? -1.0 : 1.0);
void handleMaskTap(_) => _performance.reverse(); void handleMaskTap(_) => _fling(-1.0);
// TODO(mpcomplete): Figure out how to generalize these handlers on a // TODO(mpcomplete): Figure out how to generalize these handlers on a
// "PannableThingy" interface. // "PannableThingy" interface.
...@@ -176,8 +179,7 @@ class Drawer extends AnimatedComponent { ...@@ -176,8 +179,7 @@ class Drawer extends AnimatedComponent {
} }
void handleFlingStart(event) { void handleFlingStart(event) {
double velocityX = event.velocityX / _kWidth; if (event.velocityX.abs() >= _kMinFlingVelocity)
if (velocityX.abs() >= _kMinFlingVelocity) _performance.fling(velocity: event.velocityX * _kFlingVelocityScale);
_performance.fling(velocity: velocityX);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment