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.
220 lines
5.9 KiB
220 lines
5.9 KiB
import Rx, { Observable } from 'rxjs';
|
|
import { CONTROLS } from './enums';
|
|
|
|
export default function(destroy$, {
|
|
count = 1,
|
|
id,
|
|
maxCount = 10,
|
|
showCircleControl = false,
|
|
showRandomizeControl = false,
|
|
showVisionGridControl = false
|
|
}) {
|
|
const container = document.createElement('div');
|
|
container.className = 'controlsContainer';
|
|
container.id = `controls${id}`;
|
|
document.getElementById(id).appendChild(container);
|
|
|
|
const observables = {
|
|
fps$: new Rx.Subject(),
|
|
count$: createCountControl(container, count, maxCount),
|
|
speed$: createSpeedControl(container),
|
|
circle$: showCircleControl && createCircleControl(container),
|
|
randomize$: showRandomizeControl && createRandomizeControl(container),
|
|
vision$: showVisionGridControl && createVisionGridControl(container),
|
|
animating$: createAnimatingControl(container)
|
|
};
|
|
|
|
observables.animating$.subscribe((isAnimating) => {
|
|
if (isAnimating === true) {
|
|
destroy$.next(id);
|
|
observables.count$.next(count);
|
|
}
|
|
});
|
|
|
|
destroy$.subscribe((sourceId) => {
|
|
if (id !== sourceId) {
|
|
observables.animating$.next(false);
|
|
observables.count$.next(0);
|
|
}
|
|
});
|
|
|
|
return observables;
|
|
}
|
|
|
|
|
|
function createAnimatingControl(container) {
|
|
const label = document.createElement('label');
|
|
label.className = 'controls-label';
|
|
label.className = 'controls-animating';
|
|
|
|
const text = document.createElement('span');
|
|
|
|
const checkbox = document.createElement('input');
|
|
checkbox.type = 'checkbox';
|
|
checkbox.checked = false;
|
|
|
|
label.appendChild(checkbox);
|
|
label.appendChild(text);
|
|
|
|
container.appendChild(label);
|
|
|
|
const animating$ = new Rx.BehaviorSubject(false);
|
|
|
|
label.addEventListener('change', (evt) => {
|
|
animating$.next(evt.target.checked);
|
|
});
|
|
|
|
animating$.subscribe((isAnimating) => {
|
|
text.innerHTML = (isAnimating ? '◼ Stop' : '▶ Start');
|
|
checkbox.checked = isAnimating;
|
|
});
|
|
|
|
return animating$;
|
|
}
|
|
|
|
function createCountControl(container, initialValue, max) {
|
|
const label = document.createElement('label');
|
|
label.className = 'controls-range';
|
|
|
|
const text = document.createElement('span');
|
|
// text.innerHTML = (initialValue == 1) ? '1 particle' : `${initialValue} particles`;
|
|
text.className = 'controls-range-text';
|
|
|
|
const slider = document.createElement('input');
|
|
slider.type = 'range';
|
|
slider.min = 1;
|
|
slider.max = max;
|
|
slider.value = initialValue;
|
|
slider.className = 'controls-range-input';
|
|
|
|
label.appendChild(text);
|
|
label.appendChild(slider);
|
|
|
|
container.appendChild(label);
|
|
|
|
const count$ = new Rx.BehaviorSubject(initialValue);
|
|
|
|
label.addEventListener('input', (evt) => {
|
|
count$.next(evt.target.value * 1);
|
|
});
|
|
|
|
count$.subscribe((value) => {
|
|
text.innerHTML = (value === 1) ? '1 particle' : `${value} particles`;
|
|
});
|
|
|
|
return count$;
|
|
}
|
|
|
|
function createSpeedControl(container) {
|
|
const label = document.createElement('label');
|
|
label.className = 'controls-range';
|
|
|
|
const text = document.createElement('span');
|
|
text.className = 'controls-range-text';
|
|
text.innerHTML = 'Speed: 0';
|
|
|
|
const slider = document.createElement('input');
|
|
slider.type = 'range';
|
|
slider.min = 1;
|
|
slider.max = 10;
|
|
slider.value = 4;
|
|
slider.className = 'controls-range-input';
|
|
|
|
label.appendChild(text);
|
|
label.appendChild(slider);
|
|
|
|
container.appendChild(label);
|
|
|
|
const speed$ = new Rx.BehaviorSubject(slider.value);
|
|
|
|
label.addEventListener('input', (evt) => {
|
|
speed$.next(evt.target.value * 1);
|
|
});
|
|
|
|
speed$.subscribe((value) => {
|
|
text.innerHTML = `Speed: ${value}`;
|
|
});
|
|
|
|
return speed$;
|
|
}
|
|
|
|
function createCircleControl(container) {
|
|
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';
|
|
checkbox.checked = true;
|
|
|
|
label.appendChild(checkbox);
|
|
label.appendChild(text);
|
|
|
|
container.appendChild(label);
|
|
|
|
const circle$ = new Rx.BehaviorSubject(true);
|
|
|
|
label.addEventListener('change', (evt) => {
|
|
circle$.next(evt.target.checked);
|
|
});
|
|
|
|
return circle$;
|
|
}
|
|
|
|
function createRandomizeControl(container) {
|
|
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 = true;
|
|
|
|
label.appendChild(checkbox);
|
|
label.appendChild(text);
|
|
|
|
container.appendChild(label);
|
|
|
|
const randomize$ = new Rx.BehaviorSubject(true);
|
|
|
|
label.addEventListener('change', (evt) => {
|
|
randomize$.next(evt.target.checked);
|
|
});
|
|
|
|
return randomize$;
|
|
}
|
|
|
|
function createVisionGridControl(container) {
|
|
const label = document.createElement('label');
|
|
label.className = 'controls-checkbox';
|
|
|
|
const text = document.createElement('span');
|
|
text.innerHTML = 'Show vision grid';
|
|
text.className = 'controls-checkbox-text';
|
|
|
|
const checkbox = document.createElement('input');
|
|
checkbox.type = 'checkbox';
|
|
checkbox.className = 'controls-checkbox-input';
|
|
checkbox.checked = true;
|
|
|
|
label.appendChild(checkbox);
|
|
label.appendChild(text);
|
|
|
|
container.appendChild(label);
|
|
|
|
const vision$ = new Rx.BehaviorSubject(true);
|
|
|
|
label.addEventListener('change', (evt) => {
|
|
vision$.next(evt.target.checked);
|
|
});
|
|
|
|
return vision$;
|
|
}
|
|
|