import Rx, { Observable } from 'rxjs'; import { CONTROLS } from './enums'; function Controls(container, { animating, count, maxCount, randomize, speed }, customNodes) { this.nodes = { animating: createAnimatingControl(animating), count: createCountControl(count, maxCount), randomize: createRandomizeControl(randomize), speed: createSpeedControl(speed), } container.appendChild(this.nodes.count); container.appendChild(this.nodes.speed); container.appendChild(this.nodes.randomize); if (customNodes !== undefined) { customNodes.forEach(node => { container.appendChild(node); }); } container.appendChild(this.nodes.animating); this.updateOptions({ key: CONTROLS.ANIMATING, value: animating }); this.updateOptions({ key: CONTROLS.COUNT, value: count }); this.updateOptions({ key: CONTROLS.RANDOMIZE, value: randomize }); this.updateOptions({ key: CONTROLS.SPEED, value: speed }); } Controls.prototype.updateOptions = function({ key, value}) { if (key === CONTROLS.COUNT) { this.nodes.count.querySelector('span').innerHTML = (value == 1) ? '1 particle' : `${value} particles`; } if (key === CONTROLS.SPEED) { this.nodes.speed.querySelector('span').innerHTML = `Speed: ${value}`; } if (key === CONTROLS.ANIMATING) { this.nodes.animating.querySelector('span').innerHTML = (value ? '◼ Stop' : '▶ Start'); } } Controls.prototype.mount = function(customNodes) { const animating$ = Rx.Observable.fromEvent(this.nodes.animating, 'change') .map(evt => ({ key: CONTROLS.ANIMATING, value: evt.target.checked })); const count$ = Rx.Observable.fromEvent(this.nodes.count, 'input') .map(evt => ({ key: CONTROLS.COUNT, value: evt.target.value * 1 })); const randomize$ = Rx.Observable.fromEvent(this.nodes.randomize, 'change') .map(evt => ({ key: CONTROLS.RANDOMIZE, value: evt.target.checked })); const speed$ = Rx.Observable.fromEvent(this.nodes.speed, 'input') .map(evt => ({ key: CONTROLS.SPEED, value: evt.target.value * 1 })); const eventStack$ = Rx.Observable.merge( animating$, count$, randomize$, speed$ ); eventStack$.subscribe(this.updateOptions.bind(this)); return eventStack$; } function createAnimatingControl(value) { const label = document.createElement('label'); label.className = 'controls-label'; label.className = 'controls-animating'; const text = document.createElement('span'); text.innerHTML = '...'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = value; label.appendChild(checkbox); label.appendChild(text); return label; } function createCountControl(value, max) { const label = document.createElement('label'); label.className = 'controls-range'; const text = document.createElement('span'); text.innerHTML = '...'; text.className = 'controls-range-text'; const slider = document.createElement('input'); slider.type = 'range'; slider.min = 1; slider.max = max; slider.value = value; slider.className = 'controls-range-input'; label.appendChild(text); label.appendChild(slider); 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; } function createSpeedControl(value) { const label = document.createElement('label'); label.className = 'controls-range'; const text = document.createElement('span'); text.className = 'controls-range-text'; const slider = document.createElement('input'); slider.type = 'range'; slider.min = 1; slider.max = 20; slider.value = value; slider.className = 'controls-range-input'; label.appendChild(text); label.appendChild(slider); return label; } export default Controls;