import Rx, { Observable } from 'rxjs'; import Grid from './grid'; import Particle from './particle'; import Controls from './controls'; import { CONTROLS } from './enums'; function Animation1a() { this.options = { count: 1, maxCount: 10, randomize: true, showMovementCircle: true, speed: 4 }; this.container = document.getElementById('animation1a'); this.particles = []; this.grid = new Grid(); this.movementCircleCtrl = createMovementCircleControl(); this.randomizeCtrl = createRandomizeControl(); const controls = new Controls( document.getElementById('controls1a'), this.options, [this.movementCircleCtrl, this.randomizeCtrl] ); const circle$ = Rx.Observable.fromEvent(this.movementCircleCtrl, 'change') .map(evt => ({ key: CONTROLS.MOVEMENT_CIRCLE, value: evt.target.checked })); const randomize$ = Rx.Observable.fromEvent(this.randomizeCtrl, 'change') .map(evt => ({ key: CONTROLS.RANDOMIZE, value: evt.target.checked })); const eventStack$ = controls.mount().merge(circle$, randomize$); eventStack$.subscribe(this.subscriber.bind(this)); this.updateCount(this.options.count); this.updateMovementCircle(this.options.showMovementCircle); this.updateRandomize(this.options.randomize); }; function createMovementCircleControl() { const label = document.createElement('label'); label.className = 'controls-checkbox'; const text = document.createElement('span'); text.innerHTML = 'Show movement circle'; text.className = 'controls-checkbox-text'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.className = 'controls-checkbox-input'; label.appendChild(checkbox); label.appendChild(text); return label; } function createRandomizeControl(value) { const label = document.createElement('label'); label.className = 'controls-checkbox'; const text = document.createElement('span'); text.innerHTML = 'Randomize movement'; text.className = 'controls-checkbox-text'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.className = 'controls-checkbox-input'; checkbox.checked = value; label.appendChild(checkbox); label.appendChild(text); return label; } Animation1a.prototype.subscriber = function({ key, value }) { switch(key) { case CONTROLS.ANIMATING: this.updateAnimating(value); break; case CONTROLS.COUNT: this.updateCount(value); break; case CONTROLS.MOVEMENT_CIRCLE: this.updateMovementCircle(value); break; case CONTROLS.RANDOMIZE: this.updateRandomize(value); break; case CONTROLS.SPEED: this.updateSpeed(value); break; } } Animation1a.prototype.nextFrame = function() { this.particles.forEach(p => p.nextFrame()); } Animation1a.prototype.updateAnimating = function(isAnimating) { this.options.animating = isAnimating; if (isAnimating) { const fps$ = Rx.Observable.interval(1000 / 32) .takeWhile(_ => this.options.animating); fps$.subscribe(this.nextFrame.bind(this)); } } Animation1a.prototype.updateCount = function(count) { const bounds = this.container.getBoundingClientRect(); while (this.particles.length > count) { delete this.particles.pop().remove(); } while (this.particles.length < count) { const p = new Particle(this.container, bounds, this.options, this.grid); this.particles.push(p); } } Animation1a.prototype.updateMovementCircle = function(value) { this.options.showMovementCircle = value; this.movementCircleCtrl.querySelector('[type=checkbox]').checked = value; this.particles.forEach(p => p.updateConfig({ showMovementCircle: value })); } Animation1a.prototype.updateRandomize = function(value) { this.options.randomize = value; this.randomizeCtrl.querySelector('[type=checkbox]').checked = value; this.particles.forEach(p => p.updateConfig({ randomize: value })); } Animation1a.prototype.updateSpeed = function(value) { this.options.speed = value; this.particles.forEach(p => p.updateConfig({ speed: value })); } export default Animation1a;