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.
148 lines
4.3 KiB
148 lines
4.3 KiB
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;
|
|
|