You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.4 KiB
122 lines
3.4 KiB
import Rx, { Observable } from 'rxjs';
|
|
import { CONTROLS } from './enums';
|
|
|
|
function Controls(container, { animating, count, maxCount, speed }, customNodes) {
|
|
this.nodes = {
|
|
animating: createAnimatingControl(animating),
|
|
count: createCountControl(count, maxCount),
|
|
speed: createSpeedControl(speed),
|
|
}
|
|
|
|
container.appendChild(this.nodes.count);
|
|
container.appendChild(this.nodes.speed);
|
|
|
|
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.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 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$,
|
|
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 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 = 15;
|
|
slider.value = value;
|
|
slider.className = 'controls-range-input';
|
|
|
|
label.appendChild(text);
|
|
label.appendChild(slider);
|
|
|
|
return label;
|
|
}
|
|
|
|
export default Controls;
|
|
|