UNPKG

material-motion

Version:

Makes it easy to add rich, interactive motion to your application.

183 lines 6.31 kB
/** @license * Copyright 2016 - present The Material Motion Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ import { combineLatest, } from '../combineLatest'; import { createProperty, } from '../observables'; import { State, } from '../enums/State'; import { anyOf, } from '../aggregators'; import { subscribe, } from '../subscribe'; import { DEFAULT_DAMPING, DEFAULT_STIFFNESS, DEFAULT_THRESHOLD, NumericSpring, } from './NumericSpring'; /** * `Point2DSpring` is a spring that accepts and emits `Point2D`s for its * configuration values. Internally, it is composed of two independent * `NumericSpring`s. * * Because each internal spring emits independently, `value$` will emit * intermediate values (e.g. changing `initialValue` from `{ x: 0, y: 0 }` to * `{ x: 5, y: 4 }` will cause 2 emissions, one when `x` changes and one when * `y` changes.) This may be corrected in a future release, when emits could be * batched into one per frame. */ export class Point2DSpring { constructor() { this.xSpring = new NumericSpring(); this.ySpring = new NumericSpring(); this.destination$ = createProperty({ initialValue: { x: 0, y: 0 }, }); this.initialValue$ = createProperty({ initialValue: { x: 0, y: 0 }, }); this.initialVelocity$ = createProperty({ initialValue: { x: 0, y: 0 }, }); this.stiffness$ = createProperty({ initialValue: DEFAULT_STIFFNESS, }); this.damping$ = createProperty({ initialValue: DEFAULT_DAMPING, }); this.threshold$ = createProperty({ initialValue: DEFAULT_THRESHOLD, }); this.enabled$ = createProperty({ initialValue: true, }); this.state$ = anyOf([ this.xSpring.state$.isAnyOf([State.ACTIVE]), this.ySpring.state$.isAnyOf([State.ACTIVE]), ]).dedupe().rewrite({ mapping: { true: State.ACTIVE, false: State.AT_REST, }, })._remember(); // Since this emits `Point2D`s, it's probably safe to presume it will be used // for translation. But, to be consistent with `NumericSpring`, we write // outputs to `value$` rather than `styleStreams`. // If `value$` were debounced, it would emit its terminal value after `state$` // is `AT_REST`. This might be OK in practice (since there would only be one // final frame emitted while the interaction is `AT_REST`). However, to // maintain the contract that `state$` will be `ACTIVE` whenever the stream is // animating, and to make testing simpler, we don't debounce here. // // If it were debounced, we'd have to either ensure that `state$` waits until // the next frame before emitting `AT_REST`, or accept that they are out-of- // sync and add an extra mockRAF.step() to the relevant tests. this.value$ = combineLatest({ x: this.xSpring.value$, y: this.ySpring.value$, }); subscribe({ sink: this.xSpring.destination$, source: this.destination$.pluck('x'), }); subscribe({ sink: this.ySpring.destination$, source: this.destination$.pluck('y'), }); subscribe({ sink: this.xSpring.initialValue$, source: this.initialValue$.pluck('x'), }); subscribe({ sink: this.ySpring.initialValue$, source: this.initialValue$.pluck('y'), }); subscribe({ sink: this.xSpring.initialVelocity$, source: this.initialVelocity$.pluck('x'), }); subscribe({ sink: this.ySpring.initialVelocity$, source: this.initialVelocity$.pluck('y'), }); subscribe({ sinks: [ this.xSpring.stiffness$, this.ySpring.stiffness$, ], source: this.stiffness$, }); subscribe({ sinks: [ this.xSpring.damping$, this.ySpring.damping$, ], source: this.damping$, }); subscribe({ sinks: [ this.xSpring.threshold$, this.ySpring.threshold$, ], source: this.threshold$, }); subscribe({ sinks: [ this.xSpring.enabled$, this.ySpring.enabled$, ], source: this.enabled$, }); } get destination() { return this.destination$.read(); } set destination(value) { this.destination$.write(value); } get initialValue() { return this.initialValue$.read(); } set initialValue(value) { this.initialValue$.write(value); } get initialVelocity() { return this.initialVelocity$.read(); } set initialVelocity(value) { this.initialVelocity$.write(value); } get stiffness() { return this.stiffness$.read(); } set stiffness(value) { this.stiffness$.write(value); } get damping() { return this.damping$.read(); } set damping(value) { this.damping$.write(value); } get threshold() { return this.threshold$.read(); } set threshold(value) { this.threshold$.write(value); } get enabled() { return this.enabled$.read(); } set enabled(value) { this.enabled$.write(value); } get state() { return this.state$._read(); } } export default Point2DSpring; //# sourceMappingURL=Point2DSpring.js.map