import Rx, { Observable } from 'rxjs'; // import DOM from './dom'; import { RAD } from './enums'; import Store from './store'; const random = { bool: () => Math.random() < 0.5, num: (min, max) => min + Math.round(Math.random() * max) } function moveArc(arc, newRadius) { const r0 = arc.r; const r1 = newRadius; // Moves arc center to new radius while keeping theta constant. arc.x -= (r1 - r0) * Math.cos(arc.t); arc.y += (r1 - r0) * Math.sin(arc.t); arc.r = r1; return arc; } function changeDirection(arc) { arc.t = (arc.t + Math.PI) % RAD.t360; arc.x -= (2 * arc.r) * Math.cos(arc.t); arc.y += (2 * arc.r) * Math.sin(arc.t); return arc; } // function transformVisionGrid(store) { // const { // arc, // clockwise, // particle.x, // particle.y, // radius, // } = store.get(); // // const r0 = Math.min(arc.t, arc.t - Math.PI); // const r1 = Math.max(arc.t, arc.t + Math.PI); // // const gridX = particle.x - particle.x % 5; // const gridY = particle.y - particle.y % 5; // // visionGridPoints.forEach(({ x, y, alpha, div }, i) => { // if (alpha >= 0 && alpha <= r0) { // div.style.display = (clockwise ? 'none' : 'block'); // // div.className = (clockwise ? 'anim3-dot removed' : 'anim3-dot'); // } else if (alpha >= arc.t && alpha <= r1) { // div.style.display = (clockwise ? 'none' : 'block'); // // div.className = (clockwise ? 'anim3-dot removed' : 'anim3-dot'); // } else { // div.style.display = (clockwise ? 'block' : 'none'); // // div.className = (clockwise ? 'anim3-dot' : 'anim3-dot removed'); // } // // div.style.left = `${x + gridX}px`; // div.style.top = `${-y + gridY}px`; // }); // } // function Particle(container, bounds, options = {}) { this.container = container; this.bounds = bounds; this.node = document.createElement('div'); this.node.className = 'particle has-vision'; this.circle = document.createElement('div'); this.circle.className = 'particle-movement-circle'; this.container.appendChild(this.node); this.container.appendChild(this.circle); this.arc = { r: random.num(100, 200), t: random.num(0, RAD.t360), x: random.num(0, bounds.width), y: random.num(0, bounds.height) } this.particle = { clockwise: random.bool(), speed: 4, x: 0, y: 0 } this.interval = 0; this.updateOptions(options); this.nextFrame(); }; Particle.prototype.nextFrame = function() { this.move(); this.repaintParticle(); this.repaintCircle(); } Particle.prototype.updateOptions = function(options) { this.particleImage = 'seahorse'; this.randomlyChangeRadius = (new Boolean(options.randomlyChangeRadius)) || true; this.randomlyChangeRotation = (new Boolean(options.randomlyChangeRotation)) || true; this.showCircle = (new Boolean(options.showCircle)) || false; this.showVision = (new Boolean(options.showVision)) || false; } Particle.prototype.repaintParticle = function() { const rad = this.particle.clockwise ? RAD.t180 - this.arc.t : RAD.t360 - this.arc.t; this.node.style.left = `${this.particle.x}px`; this.node.style.top = `${this.particle.y}px`; this.node.style.transform = `rotate(${rad}rad)`; } Particle.prototype.repaintCircle = function() { this.circle.style.width = `${2 * this.arc.r}px`; this.circle.style.height = `${2 * this.arc.r}px`; this.circle.style.left = `${this.arc.x - this.arc.r}px`; this.circle.style.top = `${this.arc.y - this.arc.r}px`; this.circle.style.borderRadius = `${this.arc.r}px`; } Particle.prototype.move = function(store) { // Randomly change radius and rotation direction. this.interval -= 1; if (this.interval <= 0) { this.interval = random.num(50, 100); this.arc = moveArc(this.arc, random.num(100, 200)); if (random.bool()) { this.particle.clockwise = !this.particle.clockwise; this.arc = changeDirection(this.arc); } } // Ensure constant velocity and theta between 0 and 2π. const delta = this.particle.speed / this.arc.r; this.arc.t += (this.particle.clockwise ? -delta : +delta); this.arc.t = (this.arc.t > 0 ? this.arc.t % RAD.t360 : RAD.t360 - this.arc.t); this.particle.x = this.arc.x + this.arc.r * Math.cos(this.arc.t); this.particle.y = this.arc.y - this.arc.r * Math.sin(this.arc.t); // Overflow. if (this.particle.x < 0) { this.particle.x += this.bounds.width; this.arc.x += this.bounds.width } else if (this.particle.x > this.bounds.width) { this.particle.x -= this.bounds.width; this.arc.x -= this.bounds.width } if (this.particle.y < 0) { this.particle.y += this.bounds.height; // TODO size of area this.arc.y += this.bounds.height } else if (this.particle.y > this.bounds.height) { this.particle.y -= this.bounds.height; this.arc.y -= this.bounds.height } } export default Particle;