UNPKG

just-animate

Version:
127 lines (126 loc) 3.19 kB
import { S_INACTIVE, _ } from './utils/constants'; import { CANCEL, DESTROY, FINISH, PAUSE, PLAY, REVERSE, TICK, UPDATE, UPDATE_TIME, UPDATE_RATE, APPEND, INSERT, SET } from './actions'; import { append, cancel, destroy, finish, insert, pause, play, reverse, set, tick, update, updateRate, updateTime } from './reducers/index'; import { pushDistinct, all, remove } from './utils/lists'; import { calculateConfigs } from './reducers/calc-configs'; import { rebuild } from './reducers/rebuild'; const stateSubs = []; const stores = {}; const reducers = { [APPEND]: append, [CANCEL]: cancel, [DESTROY]: destroy, [FINISH]: finish, [INSERT]: insert, [PAUSE]: pause, [PLAY]: play, [REVERSE]: reverse, [SET]: set, [TICK]: tick, [UPDATE]: update, [UPDATE_RATE]: updateRate, [UPDATE_TIME]: updateTime }; function createInitial(opts) { const refs = {}; if (opts.references) { for (var name in opts.references) { refs['@' + name] = opts.references[name]; } } const newModel = { configs: [], cursor: 0, duration: 0, id: opts.id, players: _, rate: 1, refs: refs, repeat: _, round: _, state: S_INACTIVE, time: _, yoyo: false }; return newModel; } export function getState(id) { const model = stores[id]; if (!model) { throw new Error('not found'); } return model.state; } export function addState(opts) { stores[opts.id] = { state: createInitial(opts), subs: {} }; } export function on(id, eventName, listener) { const store = stores[id]; if (store) { const subs = (store.subs[eventName] = store.subs[eventName] || []); pushDistinct(subs, listener); } } export function off(id, eventName, listener) { const store = stores[id]; if (store) { remove(store.subs[eventName], listener); } } export function dispatch(action, id, data) { const fn = reducers[action]; const store = stores[id]; if (!fn || !store) { throw new Error('not found'); } const ctx = { events: [], needUpdate: [], trigger, dirty }; const model = store.state; fn(model, data, ctx); all(ctx.events, evt => { const subs = store.subs[evt]; if (subs) { all(subs, sub => { sub(model.time); }); } }); if (ctx.destroyed) { delete stores[id]; } else if (ctx.needUpdate.length) { if (model.state !== S_INACTIVE) { rebuild(model, ctx); } else { calculateConfigs(model); } all(stateSubs, sub => { sub(store); }); } } function trigger(eventName) { pushDistinct(this.events, eventName); } function dirty(config) { pushDistinct(this.needUpdate, config); } if (typeof window !== 'undefined') { window.just_devtools = { dispatch, subscribe(fn) { pushDistinct(stateSubs, fn); }, unsubscribe(fn) { remove(stateSubs, fn); } }; }