diff --git a/src/animations/DecayAnimation.js b/src/animations/DecayAnimation.js index 80eed20..a28ffe8 100644 --- a/src/animations/DecayAnimation.js +++ b/src/animations/DecayAnimation.js @@ -3,7 +3,7 @@ import Animation from './Animation'; import decay from './decay'; import { block, clockRunning, startClock, stopClock, cond } from '../base'; import Clock from '../core/AnimatedClock'; -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; class DecayAnimation extends Animation { constructor(config) { diff --git a/src/animations/SpringAnimation.js b/src/animations/SpringAnimation.js index b73eec8..2cde1c7 100644 --- a/src/animations/SpringAnimation.js +++ b/src/animations/SpringAnimation.js @@ -1,4 +1,4 @@ -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; import Animation from './Animation'; import SpringConfig from '../SpringConfig'; import spring from './spring'; diff --git a/src/animations/TimingAnimation.js b/src/animations/TimingAnimation.js index f18f608..369736e 100644 --- a/src/animations/TimingAnimation.js +++ b/src/animations/TimingAnimation.js @@ -1,4 +1,4 @@ -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; import timing from './timing'; import { block, clockRunning, startClock, stopClock, cond } from '../base'; import Clock from '../core/AnimatedClock'; diff --git a/src/animations/spring.js b/src/animations/spring.js index 6770d51..d27b345 100644 --- a/src/animations/spring.js +++ b/src/animations/spring.js @@ -18,7 +18,7 @@ import { greaterThan, } from '../base'; import { min, abs } from '../derived'; -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; const MAX_STEPS_MS = 64; diff --git a/src/base.js b/src/base.js index 921b7a9..17e6bfe 100644 --- a/src/base.js +++ b/src/base.js @@ -1,111 +1,16 @@ -import AnimatedCond from './core/AnimatedCond'; -import AnimatedSet from './core/AnimatedSet'; -import AnimatedOperator from './core/AnimatedOperator'; -import AnimatedStartClock from './core/AnimatedStartClock'; -import AnimatedStopClock from './core/AnimatedStopClock'; -import AnimatedClockTest from './core/AnimatedClockTest'; -import AnimatedDebug from './core/AnimatedDebug'; -import AnimatedCall from './core/AnimatedCall'; -import AnimatedEvent from './core/AnimatedEvent'; -import AnimatedAlways from './core/AnimatedAlways'; -import AnimatedConcat from './core/AnimatedConcat'; - -import { adapt } from './utils'; - -function operator(name) { - return (...args) => new AnimatedOperator(name, args.map(adapt)); -} - -export const add = operator('add'); -export const sub = operator('sub'); -export const multiply = operator('multiply'); -export const divide = operator('divide'); -export const pow = operator('pow'); -export const modulo = operator('modulo'); -export const sqrt = operator('sqrt'); -export const sin = operator('sin'); -export const cos = operator('cos'); -export const tan = operator('tan'); -export const acos = operator('acos'); -export const asin = operator('asin'); -export const atan = operator('atan'); -export const exp = operator('exp'); -export const round = operator('round'); -export const lessThan = operator('lessThan'); -export const eq = operator('eq'); -export const greaterThan = operator('greaterThan'); -export const lessOrEq = operator('lessOrEq'); -export const greaterOrEq = operator('greaterOrEq'); -export const neq = operator('neq'); -export const and = operator('and'); -export const or = operator('or'); -export const defined = operator('defined'); -export const not = operator('not'); - -export const set = function(what, value) { - return new AnimatedSet(what, adapt(value)); -}; - -export const cond = function(cond, ifBlock, elseBlock) { - return new AnimatedCond( - adapt(cond), - adapt(ifBlock), - elseBlock === undefined ? undefined : adapt(elseBlock) - ); -}; - -export const block = function(items) { - return adapt(items); -}; - -export const call = function(args, func) { - return new AnimatedCall(args, func); -}; - -export const debug = function(message, value) { - if (__DEV__) { - const runningInRemoteDebugger = typeof atob !== 'undefined'; - // hack to detect if app is running in remote debugger - // https://stackoverflow.com/questions/39022216 - - const runningInExpoShell = - global.Expo && global.Expo.Constants.appOwnership !== 'standalone'; - - if (runningInRemoteDebugger || runningInExpoShell) { - // When running in expo or remote debugger we use JS console.log to output variables - // otherwise we output to the native console using native debug node - return block([ - call([value], ([a]) => console.log(`${message} ${a}`)), - value, - ]); - } else { - return new AnimatedDebug(message, adapt(value)); - } - } - // Debugging is disabled in PROD - return value; -}; - -export const startClock = function(clock) { - return new AnimatedStartClock(clock); -}; - -export const always = function(item) { - return new AnimatedAlways(item); -}; - -export const concat = function(...args) { - return new AnimatedConcat(args.map(adapt)); -}; - -export const stopClock = function(clock) { - return new AnimatedStopClock(clock); -}; - -export const clockRunning = function(clock) { - return new AnimatedClockTest(clock); -}; - -export const event = function(argMapping, config) { - return new AnimatedEvent(argMapping, config); -}; +export { createAnimatedCond as cond } from './core/AnimatedCond'; +export { createAnimatedSet as set } from './core/AnimatedSet'; +export { + createAnimatedStartClock as startClock, +} from './core/AnimatedStartClock'; +export { createAnimatedStopClock as stopClock } from './core/AnimatedStopClock'; +export { + createAnimatedClockTest as clockRunning, +} from './core/AnimatedClockTest'; +export { createAnimatedDebug as debug } from './core/AnimatedDebug'; +export { createAnimatedCall as call } from './core/AnimatedCall'; +export { createAnimatedEvent as event } from './core/AnimatedEvent'; +export { createAnimatedAlways as always } from './core/AnimatedAlways'; +export { createAnimatedConcat as concat } from './core/AnimatedConcat'; +export { createAnimatedBlock as block, adapt } from './core/AnimatedBlock'; +export * from './operators'; diff --git a/src/core/AnimatedAlways.js b/src/core/AnimatedAlways.js index f92975e..0043096 100644 --- a/src/core/AnimatedAlways.js +++ b/src/core/AnimatedAlways.js @@ -1,6 +1,6 @@ import AnimatedNode from './AnimatedNode'; -export default class AnimatedAlways extends AnimatedNode { +class AnimatedAlways extends AnimatedNode { _what; constructor(what) { @@ -12,3 +12,7 @@ export default class AnimatedAlways extends AnimatedNode { return 0; } } + +export function createAnimatedAlways(item) { + return new AnimatedAlways(item); +} diff --git a/src/core/AnimatedBezier.js b/src/core/AnimatedBezier.js index 301ca46..ea64eb0 100644 --- a/src/core/AnimatedBezier.js +++ b/src/core/AnimatedBezier.js @@ -1,4 +1,4 @@ -import { val } from '../utils'; +import { val } from '../val'; import AnimatedNode from './AnimatedNode'; // These values are established by empiricism with tests (tradeoff: performance VS precision) diff --git a/src/core/AnimatedBlock.js b/src/core/AnimatedBlock.js index 9eee4e3..70b8aca 100644 --- a/src/core/AnimatedBlock.js +++ b/src/core/AnimatedBlock.js @@ -1,7 +1,8 @@ import AnimatedNode from './AnimatedNode'; -import { val } from '../utils'; +import { val } from '../val'; +import InternalAnimatedValue from './InternalAnimatedValue'; -export default class AnimatedBlock extends AnimatedNode { +class AnimatedBlock extends AnimatedNode { _array; constructor(array) { @@ -17,3 +18,24 @@ export default class AnimatedBlock extends AnimatedNode { return result; } } + +export function createAnimatedBlock(items) { + return adapt(items); +} + +function nodify(v) { + if (typeof v === 'object' && v.__isProxy) { + if (!v.__val) { + v.__val = new InternalAnimatedValue(0); + } + return v.__val; + } + // TODO: cache some typical static values (e.g. 0, 1, -1) + return v instanceof AnimatedNode ? v : new InternalAnimatedValue(v); +} + +export function adapt(v) { + return Array.isArray(v) + ? new AnimatedBlock(v.map(node => adapt(node))) + : nodify(v); +} diff --git a/src/core/AnimatedCall.js b/src/core/AnimatedCall.js index 5f9a98b..21ba3d6 100644 --- a/src/core/AnimatedCall.js +++ b/src/core/AnimatedCall.js @@ -1,5 +1,5 @@ import ReanimatedEventEmitter from '../ReanimatedEventEmitter'; -import { val } from '../utils'; +import { val } from '../val'; import AnimatedNode from './AnimatedNode'; const NODE_MAPPING = new Map(); @@ -9,7 +9,7 @@ function listener(data) { node && node._callback(data.args); } -export default class AnimatedCall extends AnimatedNode { +class AnimatedCall extends AnimatedNode { _callback; _args; @@ -40,3 +40,7 @@ export default class AnimatedCall extends AnimatedNode { return 0; } } + +export function createAnimatedCall(args, func) { + return new AnimatedCall(args, func); +} diff --git a/src/core/AnimatedClock.js b/src/core/AnimatedClock.js index a892784..e681d27 100644 --- a/src/core/AnimatedClock.js +++ b/src/core/AnimatedClock.js @@ -1,8 +1,8 @@ -import AnimatedValue from './AnimatedValue'; +import InternalAnimatedValue from './AnimatedValue'; import AnimatedNode from './AnimatedNode'; -import { val } from '../utils'; +import { val } from '../val'; -class AnimatedMainClock extends AnimatedValue { +class AnimatedMainClock extends InternalAnimatedValue { _frameCallback; constructor() { diff --git a/src/core/AnimatedClockTest.js b/src/core/AnimatedClockTest.js index fe07979..59e42de 100644 --- a/src/core/AnimatedClockTest.js +++ b/src/core/AnimatedClockTest.js @@ -2,7 +2,7 @@ import AnimatedNode from './AnimatedNode'; import AnimatedClock from './AnimatedClock'; import invariant from 'fbjs/lib/invariant'; -export default class AnimatedClockTest extends AnimatedNode { +class AnimatedClockTest extends AnimatedNode { _clockNode; constructor(clockNode) { @@ -18,3 +18,7 @@ export default class AnimatedClockTest extends AnimatedNode { return this._clockNode.isStarted() ? 1 : 0; } } + +export function createAnimatedClockTest(clock) { + return new AnimatedClockTest(clock); +} diff --git a/src/core/AnimatedCode.js b/src/core/AnimatedCode.js index 42250c2..7eb7d5b 100644 --- a/src/core/AnimatedCode.js +++ b/src/core/AnimatedCode.js @@ -1,5 +1,5 @@ import React from 'react'; -import AnimatedAlways from './AnimatedAlways'; +import { createAnimatedAlways } from './AnimatedAlways'; import AnimatedNode from './AnimatedNode'; class Code extends React.Component { @@ -33,7 +33,7 @@ class Code extends React.Component { ); } - this.always = new AnimatedAlways(nodeExec || nodeChildren); + this.always = createAnimatedAlways(nodeExec || nodeChildren); this.always.__attach(); } diff --git a/src/core/AnimatedConcat.js b/src/core/AnimatedConcat.js index 1201655..f875106 100644 --- a/src/core/AnimatedConcat.js +++ b/src/core/AnimatedConcat.js @@ -1,7 +1,12 @@ import AnimatedNode from './AnimatedNode'; +import { adapt } from '../core/AnimatedBlock'; -export default class AnimatedConcat extends AnimatedNode { +class AnimatedConcat extends AnimatedNode { constructor(input) { super({ type: 'concat', input: input.map(n => n.__nodeID) }, input); } } + +export function createAnimatedConcat(...args) { + return new AnimatedConcat(args.map(adapt)); +} diff --git a/src/core/AnimatedCond.js b/src/core/AnimatedCond.js index 295c00d..475b2ad 100644 --- a/src/core/AnimatedCond.js +++ b/src/core/AnimatedCond.js @@ -1,7 +1,8 @@ -import { val } from '../utils'; +import { val } from '../val'; import AnimatedNode from './AnimatedNode'; +import { adapt } from '../core/AnimatedBlock'; -export default class AnimatedCond extends AnimatedNode { +class AnimatedCond extends AnimatedNode { _condition; _ifBlock; _elseBlock; @@ -29,3 +30,11 @@ export default class AnimatedCond extends AnimatedNode { } } } + +export function createAnimatedCond(cond, ifBlock, elseBlock) { + return new AnimatedCond( + adapt(cond), + adapt(ifBlock), + elseBlock === undefined ? undefined : adapt(elseBlock) + ); +} diff --git a/src/core/AnimatedDebug.js b/src/core/AnimatedDebug.js index 2344a9a..a37dad3 100644 --- a/src/core/AnimatedDebug.js +++ b/src/core/AnimatedDebug.js @@ -1,7 +1,9 @@ -import { val } from '../utils'; +import { val } from '../val'; import AnimatedNode from './AnimatedNode'; +import { createAnimatedBlock as block, adapt } from './AnimatedBlock'; +import { createAnimatedCall as call } from './AnimatedCall'; -export default class AnimatedDebug extends AnimatedNode { +class AnimatedDebug extends AnimatedNode { _message; _value; @@ -17,3 +19,27 @@ export default class AnimatedDebug extends AnimatedNode { return value; } } + +export function createAnimatedDebug(message, value) { + if (__DEV__) { + const runningInRemoteDebugger = typeof atob !== 'undefined'; + // hack to detect if app is running in remote debugger + // https://stackoverflow.com/questions/39022216 + + const runningInExpoShell = + global.Expo && global.Expo.Constants.appOwnership !== 'standalone'; + + if (runningInRemoteDebugger || runningInExpoShell) { + // When running in expo or remote debugger we use JS console.log to output variables + // otherwise we output to the native console using native debug node + return block([ + call([value], ([a]) => console.log(`${message} ${a}`)), + value, + ]); + } else { + return new AnimatedDebug(message, adapt(value)); + } + } + // Debugging is disabled in PROD + return value; +} diff --git a/src/core/AnimatedEvent.js b/src/core/AnimatedEvent.js index 9623e57..5f60d66 100644 --- a/src/core/AnimatedEvent.js +++ b/src/core/AnimatedEvent.js @@ -2,8 +2,8 @@ import { findNodeHandle } from 'react-native'; import ReanimatedModule from '../ReanimatedModule'; import AnimatedNode from './AnimatedNode'; -import AnimatedValue from './AnimatedValue'; -import AnimatedAlways from './AnimatedAlways'; +import InternalAnimatedValue from './AnimatedValue'; +import { createAnimatedAlways } from './AnimatedAlways'; import invariant from 'fbjs/lib/invariant'; import createEventObjectProxyPolyfill from './createEventObjectProxyPolyfill'; @@ -15,13 +15,13 @@ function sanitizeArgMapping(argMapping) { const alwaysNodes = []; const traverse = (value, path) => { - if (value instanceof AnimatedValue) { + if (value instanceof InternalAnimatedValue) { eventMappings.push(path.concat(value.__nodeID)); } else if (typeof value === 'object' && value.__val) { eventMappings.push(path.concat(value.__val.__nodeID)); } else if (typeof value === 'function') { - const node = new AnimatedValue(0); - alwaysNodes.push(new AnimatedAlways(value(node))); + const node = new InternalAnimatedValue(0); + alwaysNodes.push(createAnimatedAlways(value(node))); eventMappings.push(path.concat(node.__nodeID)); } else if (typeof value === 'object') { for (const key in value) { @@ -61,7 +61,7 @@ function sanitizeArgMapping(argMapping) { typeof Proxy === 'function' ? new Proxy({}, proxyHandler) : createEventObjectProxyPolyfill(); - alwaysNodes.push(new AnimatedAlways(ev(proxy))); + alwaysNodes.push(createAnimatedAlways(ev(proxy))); traverse(proxy, []); } @@ -99,3 +99,7 @@ export default class AnimatedEvent extends AnimatedNode { this.__detach(); } } + +export function createAnimatedEvent(argMapping, config) { + return new AnimatedEvent(argMapping, config); +} diff --git a/src/core/AnimatedOperator.js b/src/core/AnimatedOperator.js index ad30fe1..90c47f8 100644 --- a/src/core/AnimatedOperator.js +++ b/src/core/AnimatedOperator.js @@ -1,7 +1,8 @@ import AnimatedNode from './AnimatedNode'; -import { val } from '../utils'; +import { val } from '../val'; import invariant from 'fbjs/lib/invariant'; +import { adapt } from '../core/AnimatedBlock'; function reduce(fn) { return input => input.reduce((a, b) => fn(val(a), val(b))); @@ -53,7 +54,7 @@ const OPERATIONS = { neq: infix((a, b) => a != b), }; -export default class AnimatedOperator extends AnimatedNode { +class AnimatedOperator extends AnimatedNode { _input; _op; _operation; @@ -75,3 +76,7 @@ export default class AnimatedOperator extends AnimatedNode { return this._operation(this._input); } } + +export function createAnimatedOperator(name) { + return (...args) => new AnimatedOperator(name, args.map(adapt)); +} diff --git a/src/core/AnimatedSet.js b/src/core/AnimatedSet.js index 0983776..ad1a7c7 100644 --- a/src/core/AnimatedSet.js +++ b/src/core/AnimatedSet.js @@ -1,7 +1,8 @@ import AnimatedNode from './AnimatedNode'; -import { val } from '../utils'; +import { val } from '../val'; +import { adapt } from '../core/AnimatedBlock'; -export default class AnimatedSet extends AnimatedNode { +class AnimatedSet extends AnimatedNode { _what; _value; @@ -17,3 +18,7 @@ export default class AnimatedSet extends AnimatedNode { return newValue; } } + +export function createAnimatedSet(what, value) { + return new AnimatedSet(what, adapt(value)); +} diff --git a/src/core/AnimatedStartClock.js b/src/core/AnimatedStartClock.js index 7d273fd..3b4f4de 100644 --- a/src/core/AnimatedStartClock.js +++ b/src/core/AnimatedStartClock.js @@ -2,7 +2,7 @@ import AnimatedNode from './AnimatedNode'; import AnimatedClock from './AnimatedClock'; import invariant from 'fbjs/lib/invariant'; -export default class AnimatedStartClock extends AnimatedNode { +class AnimatedStartClock extends AnimatedNode { _clockNode; constructor(clockNode) { @@ -19,3 +19,7 @@ export default class AnimatedStartClock extends AnimatedNode { return 0; } } + +export function createAnimatedStartClock(clock) { + return new AnimatedStartClock(clock); +} diff --git a/src/core/AnimatedStopClock.js b/src/core/AnimatedStopClock.js index af87ecd..d4f5aa6 100644 --- a/src/core/AnimatedStopClock.js +++ b/src/core/AnimatedStopClock.js @@ -2,7 +2,7 @@ import AnimatedNode from './AnimatedNode'; import AnimatedClock from './AnimatedClock'; import invariant from 'fbjs/lib/invariant'; -export default class AnimatedStopClock extends AnimatedNode { +class AnimatedStopClock extends AnimatedNode { _clockNode; constructor(clockNode) { @@ -19,3 +19,7 @@ export default class AnimatedStopClock extends AnimatedNode { return 0; } } + +export function createAnimatedStopClock(clock) { + return new AnimatedStopClock(clock); +} diff --git a/src/core/AnimatedValue.js b/src/core/AnimatedValue.js index 768d09a..2b98d3b 100644 --- a/src/core/AnimatedValue.js +++ b/src/core/AnimatedValue.js @@ -1,56 +1,10 @@ -import AnimatedNode from './AnimatedNode'; -import { set } from '../base'; -import { val } from '../utils'; -import { evaluateOnce } from '../derived/evaluateOnce'; +import { createAnimatedSet as set } from '../core/AnimatedSet'; import interpolate from '../derived/interpolate'; -import ReanimatedModule from '../ReanimatedModule'; - -function sanitizeValue(value) { - return value === null || value === undefined || typeof value === 'string' - ? value - : Number(value); -} - -export default class AnimatedValue extends AnimatedNode { - constructor(value) { - super({ type: 'value', value: sanitizeValue(value) }); - this._startingValue = this._value = value; - this._animation = null; - } - - __detach() { - ReanimatedModule.getValue( - this.__nodeID, - val => (this.__nodeConfig.value = val) - ); - this.__detachAnimation(this._animation); - super.__detach(); - } - - __detachAnimation(animation) { - animation && animation.__detach(); - if (this._animation === animation) { - this._animation = null; - } - } - - __attachAnimation(animation) { - this.__detachAnimation(this._animation); - this._animation = animation; - } - - __onEvaluate() { - if (this.__inputNodes && this.__inputNodes.length) { - this.__inputNodes.forEach(val); - } - return this._value + this._offset; - } - - _updateValue(value) { - this._value = value; - this.__forceUpdateCache(value); - } +import InternalAnimatedValue from './InternalAnimatedValue'; +import { evaluateOnce } from '../derived/evaluateOnce'; +// Animated value wrapped with extra methods for omit cycle of dependencies +export default class AnimatedValue extends InternalAnimatedValue { setValue(value) { this.__detachAnimation(this._animation); evaluateOnce(set(this, value), this); diff --git a/src/core/InternalAnimatedValue.js b/src/core/InternalAnimatedValue.js new file mode 100644 index 0000000..c4a56d9 --- /dev/null +++ b/src/core/InternalAnimatedValue.js @@ -0,0 +1,54 @@ +import AnimatedNode from './AnimatedNode'; +import { val } from '../val'; +import ReanimatedModule from '../ReanimatedModule'; + +function sanitizeValue(value) { + return value === null || value === undefined || typeof value === 'string' + ? value + : Number(value); +} + +/** + * This class has been made internal in order to omit dependencies' cycles which + * were caused by imperative setValue and interpolate – they are currently exposed with AnimatedValue.js + */ +export default class InternalAnimatedValue extends AnimatedNode { + constructor(value) { + super({ type: 'value', value: sanitizeValue(value) }); + this._startingValue = this._value = value; + this._animation = null; + } + + __detach() { + ReanimatedModule.getValue( + this.__nodeID, + val => (this.__nodeConfig.value = val) + ); + this.__detachAnimation(this._animation); + super.__detach(); + } + + __detachAnimation(animation) { + animation && animation.__detach(); + if (this._animation === animation) { + this._animation = null; + } + } + + __attachAnimation(animation) { + this.__detachAnimation(this._animation); + this._animation = animation; + } + + __onEvaluate() { + if (this.__inputNodes && this.__inputNodes.length) { + this.__inputNodes.forEach(val); + } + return this._value + this._offset; + } + + _updateValue(value) { + this._value = value; + this.__forceUpdateCache(value); + } +} diff --git a/src/derived/acc.js b/src/derived/acc.js index 6c2f2fe..6d4975a 100644 --- a/src/derived/acc.js +++ b/src/derived/acc.js @@ -1,5 +1,5 @@ import { set, add } from '../base'; -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; export default function acc(v) { const acc = new AnimatedValue(0); diff --git a/src/derived/diff.js b/src/derived/diff.js index ce54d38..25fdf98 100644 --- a/src/derived/diff.js +++ b/src/derived/diff.js @@ -1,5 +1,5 @@ import { cond, block, defined, sub, set } from '../base'; -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; export default function diff(v) { const stash = new AnimatedValue(0); diff --git a/src/derived/diffClamp.js b/src/derived/diffClamp.js index ed94057..32802b5 100644 --- a/src/derived/diffClamp.js +++ b/src/derived/diffClamp.js @@ -1,5 +1,5 @@ import { cond, defined, set, add } from '../base'; -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; import min from './min'; import max from './max'; import diff from './diff'; diff --git a/src/derived/evaluateOnce.js b/src/derived/evaluateOnce.js index ac4c7ee..8e81b37 100644 --- a/src/derived/evaluateOnce.js +++ b/src/derived/evaluateOnce.js @@ -1,5 +1,8 @@ -import AnimatedValue from '../core/AnimatedValue'; -import { call, always, cond, set } from '../base'; +import AnimatedValue from '../core/InternalAnimatedValue'; +import { createAnimatedSet as set } from '../core/AnimatedSet'; +import { createAnimatedCall as call } from '../core/AnimatedCall'; +import { createAnimatedAlways as always } from '../core/AnimatedAlways'; +import { createAnimatedCond as cond } from '../core/AnimatedCond'; /** * evaluate given node and notify children @@ -7,6 +10,7 @@ import { call, always, cond, set } from '../base'; * @param input - nodes (or one node) representing values which states input for node. * @param callback - after callback */ + export function evaluateOnce(node, input = [], callback) { if (!Array.isArray(input)) { input = [input]; diff --git a/src/derived/interpolate.js b/src/derived/interpolate.js index 616be80..d673a5d 100644 --- a/src/derived/interpolate.js +++ b/src/derived/interpolate.js @@ -1,12 +1,13 @@ import { - cond, lessThan, multiply, sub, add, divide, greaterThan, -} from '../base'; +} from '../operators'; + +import { createAnimatedCond as cond } from '../core/AnimatedCond'; import invariant from 'fbjs/lib/invariant'; import AnimatedNode from '../core/AnimatedNode'; diff --git a/src/derived/max.js b/src/derived/max.js index bec8d47..88d889f 100644 --- a/src/derived/max.js +++ b/src/derived/max.js @@ -1,5 +1,5 @@ import { cond, lessThan } from '../base'; -import { adapt } from '../utils'; +import { adapt } from '../core/AnimatedBlock'; export default function max(a, b) { a = adapt(a); diff --git a/src/derived/min.js b/src/derived/min.js index 84651d7..81ebfb2 100644 --- a/src/derived/min.js +++ b/src/derived/min.js @@ -1,5 +1,5 @@ import { cond, lessThan } from '../base'; -import { adapt } from '../utils'; +import { adapt } from '../core/AnimatedBlock'; export default function min(a, b) { a = adapt(a); diff --git a/src/derived/onChange.js b/src/derived/onChange.js index b25abbe..53468de 100644 --- a/src/derived/onChange.js +++ b/src/derived/onChange.js @@ -1,5 +1,5 @@ import { block, cond, defined, neq, not, set } from '../base'; -import AnimatedValue from '../core/AnimatedValue'; +import AnimatedValue from '../core/InternalAnimatedValue'; export default function onChange(value, action) { const prevValue = new AnimatedValue(); diff --git a/src/operators.js b/src/operators.js new file mode 100644 index 0000000..44ac71f --- /dev/null +++ b/src/operators.js @@ -0,0 +1,29 @@ +import { createAnimatedOperator } from './core/AnimatedOperator'; + +const operator = createAnimatedOperator; + +export const add = operator('add'); +export const sub = operator('sub'); +export const multiply = operator('multiply'); +export const divide = operator('divide'); +export const pow = operator('pow'); +export const modulo = operator('modulo'); +export const sqrt = operator('sqrt'); +export const sin = operator('sin'); +export const cos = operator('cos'); +export const exp = operator('exp'); +export const round = operator('round'); +export const lessThan = operator('lessThan'); +export const eq = operator('eq'); +export const greaterThan = operator('greaterThan'); +export const lessOrEq = operator('lessOrEq'); +export const greaterOrEq = operator('greaterOrEq'); +export const neq = operator('neq'); +export const and = operator('and'); +export const or = operator('or'); +export const defined = operator('defined'); +export const not = operator('not'); +export const tan = operator('tan'); +export const acos = operator('acos'); +export const asin = operator('asin'); +export const atan = operator('atan'); diff --git a/src/utils.js b/src/utils.js deleted file mode 100644 index 52d56da..0000000 --- a/src/utils.js +++ /dev/null @@ -1,24 +0,0 @@ -import AnimatedBlock from './core/AnimatedBlock'; -import AnimatedNode from './core/AnimatedNode'; -import AnimatedValue from './core/AnimatedValue'; - -function nodify(v) { - if (typeof v === 'object' && v.__isProxy) { - if (!v.__val) { - v.__val = new AnimatedValue(0); - } - return v.__val; - } - // TODO: cache some typical static values (e.g. 0, 1, -1) - return v instanceof AnimatedNode ? v : new AnimatedValue(v); -} - -export function adapt(v) { - return Array.isArray(v) - ? new AnimatedBlock(v.map(node => adapt(node))) - : nodify(v); -} - -export function val(v) { - return v && v.__getValue ? v.__getValue() : v || 0; -} diff --git a/src/val.js b/src/val.js new file mode 100644 index 0000000..13ed220 --- /dev/null +++ b/src/val.js @@ -0,0 +1,3 @@ +export function val(v) { + return v && v.__getValue ? v.__getValue() : v || 0; +}