import Rx, { Observable } from 'rxjs'; import AnimationBase from './animation0'; import DOM from './dom'; import Store from './store'; const evtScare = (scareX, scareY) => new CustomEvent("scare", { detail: { scareX, scareY } }); const particleDiv = document.createElement('div'); particleDiv.className = 'particle'; function checkScare([evt, store]) { const state = store.get(); const { evtX, evtY } = DOM.getEventOffsetCoords(evt, DOM.containerBounds); const diffX = Math.abs(state.x - evtX); const diffY = Math.abs(state.y - evtY); if (diffX < 50 && diffY < 50) { DOM.container.dispatchEvent(evtScare(evtX, evtY)); } }; function flee([evt, store]) { const initialState = store.get(); const { scareX, scareY } = evt.detail; const fps$ = Rx.Observable.interval(1000 / 32); fps$ .scan((acc, i) => { return store.set({ x: acc.x + acc.dx, y: acc.y + acc.dy }) }, initialState) .takeWhile(state => { const xDanger = Math.abs(initialState.x - state.x) < 150; const yDanger = Math.abs(initialState.y - state.y) < 150; return xDanger && yDanger; }) .subscribe(state => { particleDiv.style.left = `${state.x}px`; particleDiv.style.top = `${state.y}px`; }) }; function reset() { if (particleDiv.parentNode) { DOM.container.removeChild(particleDiv); } const store = new Store({ x: 10, y: 10, dx: 5, dy: 5 }); const state = store.get(); particleDiv.style.top = `${state.y}px`; particleDiv.style.left = `${state.x}px`; DOM.container.appendChild(particleDiv); return store; }; function init() { const store = reset(); const click$ = Rx.Observable .fromEvent(DOM.container, 'click') .map(evt => [evt, store]) .subscribe(checkScare); Rx.Observable .fromEvent(DOM.container, 'scare') .map(evt => [evt, store]) .subscribe(flee); }; const Animation2 = Object.assign(AnimationBase, { init, reset }); export default Animation2;