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.
 
 

134 lines
3.8 KiB

import Rx, { Observable } from 'rxjs';
import Particle from './particle';
import Store from './store';
import Controls from './controls';
import { CONTROLS } from './enums';
function Animation2a() {
this.options = {
count: 1,
maxCount: 10,
randomize: true,
showMovementCircle: true,
showVisionGrid: true,
speed: 4
};
this.container = document.getElementById('animation2a');
this.bounds = this.container.getBoundingClientRect();
this.particles = [];
this.globalGrid = createGlobalGrid(this.container, this.bounds);
const controls = new Controls(
document.getElementById('controls2a'),
this.options
);
controls.mount().subscribe(this.subscriber.bind(this));
this.updateAnimating(this.options.animating);
this.updateCount(this.options.count);
// TODO X dimension modified by core UI, maybe recalc grid in animation start?
// TODO remove bottom padding from Disqus
// TODO perf - cache trig or perform operations
// TODO only randomize movement on 1a
// TODO ANIM2a Vision grid touches trig transform
// TODO ANIM2a randomize hazards
// TODO ANIM2 particle evade
// TODO ANIM2b Scale vision grid to 1000 particles
// TODO ANIM3 flocking
};
Animation2a.prototype.subscriber = function({ key, value }) {
switch(key) {
case CONTROLS.ANIMATING: this.updateAnimating(value); break;
case CONTROLS.COUNT: this.updateCount(value); break;
case CONTROLS.RANDOMIZE: this.updateRandomize(value); break;
case CONTROLS.SPEED: this.updateSpeed(value); break;
}
}
Animation2a.prototype.nextFrame = function() {
this.particles.forEach(p => p.nextFrame());
}
Animation2a.prototype.updateAnimating = function(isAnimating) {
this.options.animating = isAnimating;
if (isAnimating) {
const fps$ = Rx.Observable.interval(1000 / 32)
.takeWhile(_ => this.options.animating);
fps$.subscribe(this.nextFrame.bind(this));
}
}
Animation2a.prototype.updateCount = function(count) {
while (this.particles.length >= count) {
delete this.particles.pop().remove();
}
while (this.particles.length < count) {
const p = new Particle(this.container, this.bounds, this.options, this.globalGrid);
this.particles.push(p);
}
}
Animation2a.prototype.updateRandomize = function(value) {
this.options.randomize = value;
this.particles.forEach(p => p.updateConfig({ randomize: value }));
}
Animation2a.prototype.updateSpeed = function(value) {
this.options.speed = value;
this.particles.forEach(p => p.updateConfig({ speed: value }));
}
function createGlobalGrid(container, bounds) {
const grid = {};
const gridSize = 5;
const hazards = [
{ x: 100, y: 100, w: 200, h: 200 },
{ x: 600, y: 200, w: 200, h: 200 },
];
return hazards.reduce((acc, { x, y, w, h }) => {
const div = document.createElement('div');
div.className = 'hazard';
div.style.left = `${x}px`;
div.style.top = `${y}px`;
div.style.height = `${h}px`;
div.style.width = `${w}px`;
container.appendChild(div);
for (let i = x; i <= (x + w); i += gridSize) {
for (let j = y; j <= (y + h); j += gridSize) {
if (acc[i] === undefined) {
acc[i] = {};
}
if (acc[i][j] !== undefined) {
continue;
}
const dot = document.createElement('dot');
dot.className = 'hazard-dot';
dot.style.left = `${i - x}px`;
dot.style.top = `${j - y}px`;
div.appendChild(dot);
acc[i][j] = true;
}
}
return acc;
}, {});
}
export default Animation2a;