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.
176 lines
5.5 KiB
176 lines
5.5 KiB
import Rx, { Observable } from 'rxjs';
|
|
import { CONTROLS } from './enums';
|
|
|
|
function Controls(container, { animating, count, maxCount, randomizeRadius, randomizeRotation, speed }, customNodes) {
|
|
this.nodes = {
|
|
animating: createAnimatingControl(animating),
|
|
count: createCountControl(count, maxCount),
|
|
radius: createRadiusControl(randomizeRadius),
|
|
rotation: createRotationControl(randomizeRotation),
|
|
speed: createSpeedControl(speed),
|
|
}
|
|
|
|
container.appendChild(this.nodes.count);
|
|
container.appendChild(this.nodes.speed);
|
|
container.appendChild(this.nodes.radius);
|
|
container.appendChild(this.nodes.rotation);
|
|
|
|
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.RADIUS, value: randomizeRadius });
|
|
this.updateOptions({ key: CONTROLS.ROTATION, value: randomizeRotation });
|
|
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 animatingStream = Rx.Observable.fromEvent(this.nodes.animating, 'change')
|
|
.map(evt => ({ key: CONTROLS.ANIMATING, value: evt.target.checked }));
|
|
|
|
const countStream = Rx.Observable.fromEvent(this.nodes.count, 'input')
|
|
.map(evt => ({ key: CONTROLS.COUNT, value: evt.target.value * 1 }));
|
|
|
|
const radiusStream = Rx.Observable.fromEvent(this.nodes.radius, 'change')
|
|
.map(evt => ({ key: CONTROLS.RADIUS, value: evt.target.checked }));
|
|
|
|
const rotationStream = Rx.Observable.fromEvent(this.nodes.rotation, 'change')
|
|
.map(evt => ({ key: CONTROLS.ROTATION, value: evt.target.checked }));
|
|
|
|
const speedStream = Rx.Observable.fromEvent(this.nodes.speed, 'input')
|
|
.map(evt => ({ key: CONTROLS.SPEED, value: evt.target.value * 1 }));
|
|
|
|
animatingStream.subscribe(this.updateOptions.bind(this));
|
|
countStream.subscribe(this.updateOptions.bind(this));
|
|
radiusStream.subscribe(this.updateOptions.bind(this));
|
|
rotationStream.subscribe(this.updateOptions.bind(this));
|
|
speedStream.subscribe(this.updateOptions.bind(this));
|
|
|
|
return Rx.Observable.merge(
|
|
animatingStream,
|
|
countStream,
|
|
radiusStream,
|
|
rotationStream,
|
|
speedStream,
|
|
);
|
|
}
|
|
|
|
const createAnimatingControl = function(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;
|
|
}
|
|
|
|
const createCountControl = function(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;
|
|
}
|
|
|
|
const createRadiusControl = function(value) {
|
|
const label = document.createElement('label');
|
|
label.className = 'controls-checkbox';
|
|
|
|
const text = document.createElement('span');
|
|
text.innerHTML = 'Random radii';
|
|
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;
|
|
}
|
|
|
|
const createRotationControl = function(value) {
|
|
const label = document.createElement('label');
|
|
label.className = 'controls-checkbox';
|
|
|
|
const text = document.createElement('span');
|
|
text.innerHTML = 'Random rotation';
|
|
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;
|
|
}
|
|
|
|
const createSpeedControl = function(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 = 50;
|
|
slider.value = value;
|
|
slider.className = 'controls-range-input';
|
|
|
|
label.appendChild(text);
|
|
label.appendChild(slider);
|
|
|
|
return label;
|
|
}
|
|
|
|
export default Controls;
|
|
|