Skip to content

Commit

Permalink
[added] reactivity to spring properties
Browse files Browse the repository at this point in the history
Reviewers: O3 Material JavaScript platform reviewers, #material_motion, O2 Material Motion, featherless

Reviewed By: #material_motion, O2 Material Motion, featherless

Subscribers: featherless

Tags: #material_motion

Differential Revision: http://codereview.cc/D2502
  • Loading branch information
appsforartists committed Jan 14, 2017
1 parent 7ebf00c commit e8c985b
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ import {
TogglableProperty,
} from 'material-motion-experimental-addons';

import {
springSource,
} from 'material-motion-springs-adaptor-rebound';

import {
createProperty,
} from 'material-motion-streams';

// How the contents of a bottom sheet transition between states vary from app-
// to-app. For instance, an app could choose any of these:
//
Expand All @@ -50,7 +58,24 @@ import {
// when the user crosses a threshold.

class BottomSheetMain extends React.Component {
_isOpen = new TogglableProperty();
_isOpen = new TogglableProperty({
onValue: 0,
// TODO: make these reactive based on viewport size
offValue: 300,
});

_spring = springSource({
destination: this._isOpen,

// TODO: make these optional in TypeScript
initialValue: createProperty({ initialValue: 0 }),
initialVelocity: createProperty({ initialValue: 0 }),
threshold: createProperty({ initialValue: 1 }),
tension: createProperty({ initialValue: 342 }),
friction: createProperty({ initialValue: 30 }),
});

_testing = this._spring.subscribe((value: number) => console.log('spring value: ', value));

_model = {
title: 'A really interesting talk',
Expand All @@ -59,8 +84,6 @@ class BottomSheetMain extends React.Component {
};

render() {
this._isOpen.subscribe(console.log);

return (
<Col
backgroundColor = '#ECECEC'
Expand Down
60 changes: 48 additions & 12 deletions packages/springs-adaptor-rebound/src/springSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@ export function springSource<T extends number | NumericDict>({
export default springSource;

function numericSpringSource({
destination,
destination: destination$,
tension: tension$,
friction: friction$,
initialValue,
initialVelocity = createProperty({ initialValue: 0 }),
initialVelocity,
threshold,
tension,
friction,
}: SpringArgs<number>) {
return new MotionObservable(
(observer: MotionObserver<number>) => {
const spring = _springSystem.createSpringWithConfig({
tension: tension.read(),
friction: friction.read(),
tension: tension$.read(),
friction: friction$.read(),
});

const listener: Listener = {
Expand All @@ -121,12 +121,48 @@ function numericSpringSource({
observer.state(State.AT_REST);
spring.addListener(listener);

// Whenever the spring is subscribed to, it pulls its values from its
// parameters
spring.setCurrentValue(initialValue.read());
spring.setVelocity(initialVelocity.read());
spring.setEndValue(destination.read());
spring.setRestSpeedThreshold(threshold.read());
destination$.subscribe(
destination => {
// Any time the destination changes, we re-initialize the starting
// parameters. This means initialValue needs to be backed by the same
// property that subscribe's to the spring.
//
// This is an optimization for elements that are draggable (and then
// spring to a location upon release), but is needlessly complicated
// for other cases.
//
// TODO: detect if a value is constant or readable, and only reset its
// values if it's readable
spring.setCurrentValue(initialValue.read());
spring.setRestSpeedThreshold(threshold.read());

// If we don't have an author-specified override, let Rebound handle
// tracking velocity
if (initialVelocity) {
spring.setVelocity(initialVelocity.read());
}

spring.setEndValue(destination);
}
);

tension$.subscribe(
tension => {
spring.setSpringConfig({
tension,
friction: spring.getSpringConfig().friction,
});
}
);

friction$.subscribe(
friction => {
spring.setSpringConfig({
tension: spring.getSpringConfig().tension,
friction,
});
}
);

return function disconnect() {
spring.removeListener(listener);
Expand Down
8 changes: 4 additions & 4 deletions packages/streams/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ export interface MotionElement {

export type SpringArgs<T> = {
destination: PropertyObservable<T>,
initialValue: PropertyObservable<T>,
initialVelocity: PropertyObservable<T>,
threshold: ScopedReadable<number>,
friction: ScopedReadable<number>,
friction: PropertyObservable<number>,
tension: ScopedReadable<number>,
initialValue: ScopedReadable<T>,
initialVelocity: ScopedReadable<T>,
threshold: ScopedReadable<number>,
};

0 comments on commit e8c985b

Please sign in to comment.