{"map":"{\"version\":3,\"file\":\"getVelocity$.js\",\"sourceRoot\":\"\",\"sources\":[\"../../src/getVelocity$.ts\"],\"names\":[],\"mappings\":\"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\"}","code":"/** @license\r\n *  Copyright 2016 - present The Material Motion Authors. All Rights Reserved.\r\n *\r\n *  Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\r\n *  use this file except in compliance with the License. You may obtain a copy\r\n *  of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n *  Unless required by applicable law or agreed to in writing, software\r\n *  distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\r\n *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r\n *  License for the specific language governing permissions and limitations\r\n *  under the License.\r\n */\r\nimport { MotionObservable, } from './observables/proxies';\r\nimport { createPlucker, } from './operators/pluck';\r\nimport { isPoint2D, } from './typeGuards';\r\n// These constants are exported for testing.\r\nexport const MAXIMUM_AGE = 250;\r\nexport const MAXIMUM_INCOMING_DISPATCHES = 5;\r\nconst pluckTimestamp = createPlucker('timestamp');\r\nconst pluckValue = createPlucker('value');\r\nconst pluckX = createPlucker('value.x');\r\nconst pluckY = createPlucker('value.y');\r\n/**\r\n * Computes the velocity of an incoming stream and emits the result. Velocity's\r\n * denominator is in milliseconds; if the incoming stream is measured in pixels,\r\n * the resulting stream will be in pixels / millisecond.\r\n *\r\n * Velocity is computed by watching the trailing 250ms of up to 5 emissions and\r\n * measuring the distance between the longest pair of events moving in the\r\n * current direction.  This approach is more resiliant to anomolous data than a\r\n * simple (nextPosition - prevPosition) / (nextTime - prevTime).\r\n *\r\n * If `pulse$` is supplied, `velocity(pulse$)` will only emit values when\r\n * `pulse$` emits a value.  This is useful for ensuring that velocity is only\r\n * calculated when it will be used.\r\n */\r\nexport function getVelocity$({ value$, pulse$, \r\n    // These values are borrowed from Matthew Bolohan's drag implementation (which\r\n    // presumes the units are \"px / ms\").\r\n    maximumVelocity = 5, defaultVelocity = 1, }) {\r\n    return new MotionObservable((observer) => {\r\n        let records = [];\r\n        const trailingSubscription = value$.timestamp()._slidingWindow({ size: MAXIMUM_INCOMING_DISPATCHES }).subscribe(nextRecords => records = nextRecords);\r\n        const pulseSubscription = pulse$.timestamp().subscribe(({ timestamp: now }) => {\r\n            const recentRecords = records.filter(({ timestamp }) => now - timestamp < MAXIMUM_AGE);\r\n            if (records.length && isPoint2D(records[0].value)) {\r\n                observer.next({\r\n                    x: calculateVelocity({ records: recentRecords, pluckValue: pluckX, pluckTimestamp, maximumVelocity, defaultVelocity }),\r\n                    y: calculateVelocity({ records: recentRecords, pluckValue: pluckY, pluckTimestamp, maximumVelocity, defaultVelocity }),\r\n                });\r\n            }\r\n            else {\r\n                observer.next(calculateVelocity({ records: recentRecords, pluckValue, pluckTimestamp, maximumVelocity, defaultVelocity }));\r\n            }\r\n        });\r\n        return () => {\r\n            trailingSubscription.unsubscribe();\r\n            pulseSubscription.unsubscribe();\r\n        };\r\n    });\r\n}\r\n;\r\n/**\r\n * Computes velocity using the oldest value that's moving in the current\r\n * direction.\r\n *\r\n * It walks backwards over an array of records and makes sure that each segment\r\n * is going in the same direction (incrementing or decrementing) as the last\r\n * segment.  When it detects a change in direction (or has checked the whole\r\n * array), it returns the velocity between the newest value and the oldest\r\n * moving in the same direction.\r\n */\r\nfunction calculateVelocity({ records, pluckValue, pluckTimestamp, maximumVelocity, defaultVelocity }) {\r\n    if (records.length < 2) {\r\n        return 0;\r\n    }\r\n    let velocity = 0;\r\n    // Backing over the array pairwise, `next` is the newer value and `prev` is\r\n    // the older value.  `last` is always the final value.\r\n    const lastIndex = records.length - 1;\r\n    const lastValue = pluckValue(records[lastIndex]);\r\n    const lastTimestamp = pluckTimestamp(records[lastIndex]);\r\n    let prevValue;\r\n    let prevTimestamp;\r\n    let nextValue = lastValue;\r\n    let nextTimestamp = lastTimestamp;\r\n    for (let i = lastIndex - 1; i >= 0; i--) {\r\n        prevValue = pluckValue(records[i]);\r\n        prevTimestamp = pluckTimestamp(records[i]);\r\n        const averageVelocity = (lastValue - prevValue) / (lastTimestamp - prevTimestamp);\r\n        const pairwiseVelocity = (nextValue - prevValue) / (nextTimestamp - prevTimestamp);\r\n        if (velocity !== 0 && pairwiseVelocity > 0 !== velocity > 0) {\r\n            break;\r\n        }\r\n        else {\r\n            velocity = averageVelocity;\r\n        }\r\n        nextValue = prevValue;\r\n        nextTimestamp = prevTimestamp;\r\n    }\r\n    if (Math.abs(velocity) > maximumVelocity) {\r\n        // If there isn't enough data to trust our accuracy (perhaps the main thread\r\n        // was blocked), use the default velocity.\r\n        const direction = velocity / Math.abs(velocity);\r\n        if (records.length < 3) {\r\n            velocity = direction * defaultVelocity;\r\n        }\r\n        else {\r\n            velocity = direction * maximumVelocity;\r\n        }\r\n    }\r\n    return velocity;\r\n}\r\n//# sourceMappingURL=getVelocity$.js.map","dts":{"name":"/Users/brentons/Projects/material-motion-js/packages/core/getVelocity$.d.ts","text":"import { ObservableWithMotionOperators, Point2D } from './types';\r\nexport declare const MAXIMUM_AGE = 250;\r\nexport declare const MAXIMUM_INCOMING_DISPATCHES = 5;\r\nexport declare type GetVelocity$Args<U extends number | Point2D> = {\r\n    value$: ObservableWithMotionOperators<U>;\r\n    pulse$: ObservableWithMotionOperators<any>;\r\n    maximumVelocity?: number;\r\n    defaultVelocity?: number;\r\n};\r\n/**\r\n * Computes the velocity of an incoming stream and emits the result. Velocity's\r\n * denominator is in milliseconds; if the incoming stream is measured in pixels,\r\n * the resulting stream will be in pixels / millisecond.\r\n *\r\n * Velocity is computed by watching the trailing 250ms of up to 5 emissions and\r\n * measuring the distance between the longest pair of events moving in the\r\n * current direction.  This approach is more resiliant to anomolous data than a\r\n * simple (nextPosition - prevPosition) / (nextTime - prevTime).\r\n *\r\n * If `pulse$` is supplied, `velocity(pulse$)` will only emit values when\r\n * `pulse$` emits a value.  This is useful for ensuring that velocity is only\r\n * calculated when it will be used.\r\n */\r\nexport declare function getVelocity$<U extends number | Point2D>({value$, pulse$, maximumVelocity, defaultVelocity}: GetVelocity$Args<U>): ObservableWithMotionOperators<U>;\r\n"}}
