diff --git a/css/index.scss b/css/index.scss
index 9635728..42218be 100644
--- a/css/index.scss
+++ b/css/index.scss
@@ -29,18 +29,29 @@
}
.hazard {
- // background: url('../res/palette.svg');
- // background-size: 167px 100px;
- background: red;
+ background: #f9f8f0;
position: absolute;
+
+ &::after {
+ content: '\26A0';
+ font-size: 40px;
+ height: 40px;
+ line-height: 40px;
+ margin-left: -20px;
+ margin-top: -20px;
+ left: 50%;
+ opacity: 0.3;
+ position: absolute;
+ top: 50%;
+ width: 40px;
+ }
}
.hazard-dot {
- background: yellow;
- height: 2px;
- margin: 1px 0 0 1px;
+ background: red;
+ height: 1px;
position: absolute;
- width: 2px;
+ width: 1px;
}
// .highlight {
diff --git a/css/style.css b/css/style.css
index 11c6d4d..e8c2a0e 100644
--- a/css/style.css
+++ b/css/style.css
@@ -32,15 +32,26 @@ body {
z-index: 0; }
.hazard {
- background: red;
+ background: #f9f8f0;
position: absolute; }
+ .hazard::after {
+ content: '\26A0';
+ font-size: 40px;
+ height: 40px;
+ line-height: 40px;
+ margin-left: -20px;
+ margin-top: -20px;
+ left: 50%;
+ opacity: 0.3;
+ position: absolute;
+ top: 50%;
+ width: 40px; }
.hazard-dot {
- background: yellow;
- height: 2px;
- margin: 1px 0 0 1px;
+ background: red;
+ height: 1px;
position: absolute;
- width: 2px; }
+ width: 1px; }
.particle-container {
position: absolute;
z-index: 1; }
diff --git a/index.html b/index.html
index 3c61c2e..9e7c377 100644
--- a/index.html
+++ b/index.html
@@ -18,6 +18,7 @@
Have particle movement that feels calm and natural
Support large swarms of particles
Be able to evade obstacles
+ Exhibit flocking behavior
diff --git a/js/animation2a.js b/js/animation2a.js
index 364f731..364165f 100644
--- a/js/animation2a.js
+++ b/js/animation2a.js
@@ -9,8 +9,8 @@ function Animation2a() {
count: 1,
maxCount: 10,
randomize: true,
+ showMovementCircle: true,
showVisionGrid: true,
- showMovementCircle: false,
speed: 4
};
@@ -30,20 +30,17 @@ function Animation2a() {
this.updateAnimating(this.options.animating);
this.updateCount(this.options.count);
- // TODO X dimension modified by core UI
+ // 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 move animating into controls
- // TODO no randomize control except anim1
+ // TODO particle gridzie and vision rad into options
- // TODO ANIM2 put hazards in animation
// TODO ANIM2 particle evade
- // TODO ANIM2 style hazards
- // TODO ANIM2a randomize hazards
// TODO ANIM2a Vision grid touches
+ // TODO ANIM2a randomize hazards
// TODO ANIM2b Scale vision grid to 1000? particles
- // TODO ANIM3 Flocking
+ // TODO ANIM3 flocking
};
Animation2a.prototype.subscriber = function({ key, value }) {
@@ -76,19 +73,19 @@ Animation2a.prototype.updateCount = function(count) {
}
while (this.particles.length < count) {
- const p = new Particle(this.container, this.bounds, this.options);
+ 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.updateOptions({ randomize: value }));
+ this.particles.forEach(p => p.updateConfig({ randomize: value }));
}
Animation2a.prototype.updateSpeed = function(value) {
this.options.speed = value;
- this.particles.forEach(p => p.updateOptions({ speed: value }));
+ this.particles.forEach(p => p.updateConfig({ speed: value }));
}
function createGlobalGrid(container, bounds) {
@@ -96,9 +93,8 @@ function createGlobalGrid(container, bounds) {
const gridSize = 5;
const hazards = [
- { x: 100, y: 100, w: 100, h: 100 },
- { x: 200, y: 200, w: 100, h: 100 },
- { x: 600, y: 200, w: 100, h: 100 },
+ { x: 100, y: 100, w: 200, h: 200 },
+ { x: 600, y: 200, w: 200, h: 200 },
];
return hazards.reduce((acc, { x, y, w, h }) => {
diff --git a/js/bundle.js b/js/bundle.js
index 5522601..7804bce 100644
--- a/js/bundle.js
+++ b/js/bundle.js
@@ -472,7 +472,7 @@ eval("\nvar isArray_1 = __webpack_require__(/*! ../util/isArray */ 11);\nfunctio
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 14);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 16);\n\nvar _store = __webpack_require__(/*! ./store */ 22);\n\nvar _store2 = _interopRequireDefault(_store);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar random = {\n bool: function bool(weight) {\n return Math.random() < (weight || 0.5);\n },\n num: function num(min, max) {\n return min + Math.round(Math.random() * max);\n },\n color: function color() {\n return 'rgb(' + Math.floor(Math.random() * 255) + ', ' + Math.floor(Math.random() * 255) + ', ' + Math.floor(Math.random() * 255) + ')';\n }\n};\n\n/* ===== Constructor ===== */\n\nfunction Particle(parent, bounds, options) {\n this.options = Object.assign({\n randomize: false,\n showMovementCircle: false,\n showVisionGrid: false,\n speed: 4\n }, options);\n\n this.arc = {\n r: random.num(100, 200),\n t: random.num(_enums.RAD.t90, _enums.RAD.t360),\n x: random.num(0, bounds.width),\n y: random.num(0, bounds.height)\n };\n\n this.particle = {\n clockwise: random.bool(),\n color: random.color(),\n x: 0,\n y: 0\n };\n\n this.visionGridPoints = [];\n this.interval = random.num(_enums.RAD.t90, _enums.RAD.t360);\n\n this.bounds = bounds;\n this.parent = parent;\n\n this.container = document.createElement('div');\n this.container.className = 'particle-container';\n\n this.body = document.createElement('div');\n this.body.className = 'particle-body';\n this.body.style.backgroundColor = this.particle.color;\n\n this.container.appendChild(this.body);\n this.parent.appendChild(this.container);\n\n this.updateOptions(this.options);\n this.nextFrame();\n};\n\nParticle.prototype.remove = function () {\n this.parent.removeChild(this.container);\n return this;\n};\n\nParticle.prototype.nextFrame = function () {\n this.move();\n repaintContainer(this.container, this.particle);\n repaintBody(this.arc, this.body, this.particle);\n repaintCircle(this.arc, this.circle, this.particle);\n repaintVision(this.arc, this.vision, this.particle);\n};\n\nParticle.prototype.updateBounds = function (bounds) {\n this.bounds = bounds;\n};\n\nParticle.prototype.updateOptions = function (options) {\n var _this = this;\n\n Object.assign(this.options, options);\n\n if (options.showMovementCircle === true && this.circle === undefined) {\n this.circle = document.createElement('div');\n this.circle.className = 'particle-movement-circle';\n this.circle.style.borderColor = this.particle.color;\n this.container.appendChild(this.circle);\n }\n\n if (options.showMovementCircle === false && this.circle !== undefined) {\n this.container.removeChild(this.circle);\n delete this.circle;\n }\n\n if (options.showVisionGrid === true && this.vision === undefined) {\n this.vision = document.createElement('div');\n this.vision.className = 'particle-vision';\n this.container.appendChild(this.vision);\n\n this.visionGridPoints = calculateVisionGridPoints(this.particle);\n\n this.visionGridPoints.forEach(function (point) {\n _this.vision.appendChild(point.div);\n });\n }\n\n if (options.showVisionGrid === false && this.vision !== undefined) {\n // this.container.removeChild(this.vision);\n // delete this.vision;\n //\n // this.visionGridPoints.forEach(point => {\n // this.vision.removeChild(point.div);\n // });\n // this.visionGridPoints = [];\n }\n};\n\nParticle.prototype.move = function () {\n // Randomly change radius and rotation direction.\n if (this.interval <= 0) {\n this.interval = random.num(_enums.RAD.t90, _enums.RAD.t360);\n\n if (this.options.randomize === true) {\n this.arc = moveArc(this.arc, random.num(100, 200));\n\n if (random.bool(0.8)) {\n this.particle.clockwise = !this.particle.clockwise;\n this.arc = changeDirection(this.arc);\n }\n }\n }\n\n // Ensure constant velocity and theta between 0 and 2π.\n var delta = this.options.speed / this.arc.r;\n this.interval -= delta;\n\n this.arc.t += this.particle.clockwise ? -delta : +delta;\n this.arc.t = this.arc.t > 0 ? this.arc.t % _enums.RAD.t360 : _enums.RAD.t360 + this.arc.t;\n\n this.particle.x = this.arc.x + this.arc.r * Math.cos(this.arc.t);\n this.particle.y = this.arc.y - this.arc.r * Math.sin(this.arc.t);\n\n // Overflow.\n if (this.particle.x < 0) {\n this.particle.x += this.bounds.width;\n this.arc.x += this.bounds.width;\n } else if (this.particle.x > this.bounds.width) {\n this.particle.x -= this.bounds.width;\n this.arc.x -= this.bounds.width;\n }\n\n if (this.particle.y < 0) {\n this.particle.y += this.bounds.height; // TODO size of area\n this.arc.y += this.bounds.height;\n } else if (this.particle.y > this.bounds.height) {\n this.particle.y -= this.bounds.height;\n this.arc.y -= this.bounds.height;\n }\n};\n\nfunction moveArc(arc, newRadius) {\n var r0 = arc.r;\n var r1 = newRadius;\n\n // Moves arc center to new radius while keeping theta constant.\n arc.x -= (r1 - r0) * Math.cos(arc.t);\n arc.y += (r1 - r0) * Math.sin(arc.t);\n arc.r = r1;\n\n return arc;\n}\n\nfunction changeDirection(arc) {\n arc.t = (arc.t + _enums.RAD.t180) % _enums.RAD.t360;\n arc.x -= 2 * arc.r * Math.cos(arc.t);\n arc.y += 2 * arc.r * Math.sin(arc.t);\n\n return arc;\n}\n\nfunction calculateVisionGridPoints(particle) {\n var gridSize = 5;\n var visionRadius = 50;\n\n var r0 = Math.pow(visionRadius, 2);\n var r1 = Math.pow(visionRadius - gridSize, 2);\n\n var points = [];\n for (var x = -visionRadius; x <= visionRadius; x += gridSize) {\n for (var y = -visionRadius; y <= visionRadius; y += gridSize) {\n // Half of triangle\n if (x > -y) {\n continue;\n }\n\n // Vision band\n var p = Math.pow(x, 2) + Math.pow(y, 2);\n if (p > r0 || p < r1) {\n continue;\n }\n\n var div = document.createElement('div');\n div.className = 'particle-vision-dot';\n div.style.backgroundColor = particle.color;\n div.style.left = x + visionRadius + 'px';\n div.style.top = y + visionRadius + 'px';\n\n points.push({ x: x, y: y, div: div });\n }\n }\n\n return points;\n}\n\nfunction repaintContainer(containerNode, particle) {\n containerNode.style.left = particle.x + 'px';\n containerNode.style.top = particle.y + 'px';\n}\n\nfunction repaintBody(arc, bodyNode, particle) {\n var rad = particle.clockwise ? _enums.RAD.t180 - arc.t : _enums.RAD.t360 - arc.t;\n\n bodyNode.style.transform = 'rotate(' + (rad + _enums.RAD.t45) + 'rad)';\n}\n\nfunction repaintVision(arc, visionNode, particle) {\n if (visionNode === undefined) {\n return;\n }\n\n var rad = particle.clockwise ? _enums.RAD.t180 - arc.t : _enums.RAD.t360 - arc.t;\n\n visionNode.style.transform = 'rotate(' + (rad + _enums.RAD.t45) + 'rad)';\n}\n\nfunction repaintCircle(arc, circleNode) {\n if (circleNode === undefined) {\n return;\n }\n\n circleNode.style.width = 2 * arc.r + 'px';\n circleNode.style.height = 2 * arc.r + 'px';\n\n circleNode.style.left = '-' + (arc.r + arc.r * Math.cos(arc.t)) + 'px';\n circleNode.style.top = '-' + (arc.r - arc.r * Math.sin(arc.t)) + 'px';\n\n circleNode.style.borderRadius = arc.r + 'px';\n}\n\nexports.default = Particle;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgUkFEIH0gZnJvbSAnLi9lbnVtcyc7XG5pbXBvcnQgU3RvcmUgZnJvbSAnLi9zdG9yZSc7XG5cbmNvbnN0IHJhbmRvbSA9IHtcbiAgICBib29sOiAod2VpZ2h0KSA9PiBNYXRoLnJhbmRvbSgpIDwgKHdlaWdodCB8fCAwLjUpLFxuICAgIG51bTogKG1pbiwgbWF4KSA9PiBtaW4gKyBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiBtYXgpLFxuICAgIGNvbG9yOiAoKSA9PiBgcmdiKCR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU1KX0sICR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU1KX0sICR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU1KX0pYFxufVxuXG4vKiA9PT09PSBDb25zdHJ1Y3RvciA9PT09PSAqL1xuXG5mdW5jdGlvbiBQYXJ0aWNsZShwYXJlbnQsIGJvdW5kcywgb3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe1xuICAgICAgICByYW5kb21pemU6IGZhbHNlLFxuICAgICAgICBzaG93TW92ZW1lbnRDaXJjbGU6IGZhbHNlLFxuICAgICAgICBzaG93VmlzaW9uR3JpZDogZmFsc2UsXG4gICAgICAgIHNwZWVkOiA0XG4gICAgfSwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLmFyYyA9IHtcbiAgICAgICAgcjogcmFuZG9tLm51bSgxMDAsIDIwMCksXG4gICAgICAgIHQ6IHJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApLFxuICAgICAgICB4OiByYW5kb20ubnVtKDAsIGJvdW5kcy53aWR0aCksXG4gICAgICAgIHk6IHJhbmRvbS5udW0oMCwgYm91bmRzLmhlaWdodClcbiAgICB9XG5cbiAgICB0aGlzLnBhcnRpY2xlID0ge1xuICAgICAgICBjbG9ja3dpc2U6IHJhbmRvbS5ib29sKCksXG4gICAgICAgIGNvbG9yOiByYW5kb20uY29sb3IoKSxcbiAgICAgICAgeDogMCxcbiAgICAgICAgeTogMFxuICAgIH1cblxuICAgIHRoaXMudmlzaW9uR3JpZFBvaW50cyA9IFtdO1xuICAgIHRoaXMuaW50ZXJ2YWwgPSByYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKTtcblxuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuXG4gICAgdGhpcy5jb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSAncGFydGljbGUtY29udGFpbmVyJztcblxuICAgIHRoaXMuYm9keSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRoaXMuYm9keS5jbGFzc05hbWUgPSAncGFydGljbGUtYm9keSc7XG4gICAgdGhpcy5ib2R5LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMucGFydGljbGUuY29sb3I7XG5cbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmJvZHkpO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuY29udGFpbmVyKTtcblxuICAgIHRoaXMudXBkYXRlT3B0aW9ucyh0aGlzLm9wdGlvbnMpO1xuICAgIHRoaXMubmV4dEZyYW1lKCk7XG59O1xuXG5QYXJ0aWNsZS5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5wYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5jb250YWluZXIpO1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUubmV4dEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5tb3ZlKCk7XG4gICAgcmVwYWludENvbnRhaW5lcih0aGlzLmNvbnRhaW5lciwgdGhpcy5wYXJ0aWNsZSk7XG4gICAgcmVwYWludEJvZHkodGhpcy5hcmMsIHRoaXMuYm9keSwgdGhpcy5wYXJ0aWNsZSk7XG4gICAgcmVwYWludENpcmNsZSh0aGlzLmFyYywgdGhpcy5jaXJjbGUsIHRoaXMucGFydGljbGUpO1xuICAgIHJlcGFpbnRWaXNpb24odGhpcy5hcmMsIHRoaXMudmlzaW9uLCB0aGlzLnBhcnRpY2xlKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnVwZGF0ZUJvdW5kcyA9IGZ1bmN0aW9uKGJvdW5kcykge1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUudXBkYXRlT3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMub3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICBpZiAob3B0aW9ucy5zaG93TW92ZW1lbnRDaXJjbGUgPT09IHRydWUgJiYgdGhpcy5jaXJjbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmNpcmNsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICB0aGlzLmNpcmNsZS5jbGFzc05hbWUgPSAncGFydGljbGUtbW92ZW1lbnQtY2lyY2xlJztcbiAgICAgICAgdGhpcy5jaXJjbGUuc3R5bGUuYm9yZGVyQ29sb3IgPSB0aGlzLnBhcnRpY2xlLmNvbG9yO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmNpcmNsZSk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc2hvd01vdmVtZW50Q2lyY2xlID09PSBmYWxzZSAmJiB0aGlzLmNpcmNsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMuY2lyY2xlKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuY2lyY2xlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNob3dWaXNpb25HcmlkID09PSB0cnVlICYmIHRoaXMudmlzaW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy52aXNpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdGhpcy52aXNpb24uY2xhc3NOYW1lID0gJ3BhcnRpY2xlLXZpc2lvbic7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMudmlzaW9uKTtcblxuICAgICAgICB0aGlzLnZpc2lvbkdyaWRQb2ludHMgPSBjYWxjdWxhdGVWaXNpb25HcmlkUG9pbnRzKHRoaXMucGFydGljbGUpO1xuXG4gICAgICAgIHRoaXMudmlzaW9uR3JpZFBvaW50cy5mb3JFYWNoKHBvaW50ID0+IHtcbiAgICAgICAgICAgIHRoaXMudmlzaW9uLmFwcGVuZENoaWxkKHBvaW50LmRpdik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNob3dWaXNpb25HcmlkID09PSBmYWxzZSAmJiB0aGlzLnZpc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIHRoaXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMudmlzaW9uKTtcbiAgICAgICAgLy8gZGVsZXRlIHRoaXMudmlzaW9uO1xuICAgICAgICAvL1xuICAgICAgICAvLyB0aGlzLnZpc2lvbkdyaWRQb2ludHMuZm9yRWFjaChwb2ludCA9PiB7XG4gICAgICAgIC8vICAgICB0aGlzLnZpc2lvbi5yZW1vdmVDaGlsZChwb2ludC5kaXYpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gdGhpcy52aXNpb25HcmlkUG9pbnRzID0gW107XG4gICAgfVxufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUubW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIFJhbmRvbWx5IGNoYW5nZSByYWRpdXMgYW5kIHJvdGF0aW9uIGRpcmVjdGlvbi5cbiAgICBpZiAodGhpcy5pbnRlcnZhbCA8PSAwKSB7XG4gICAgICAgIHRoaXMuaW50ZXJ2YWwgPSByYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKTtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJhbmRvbWl6ZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgdGhpcy5hcmMgPSBtb3ZlQXJjKHRoaXMuYXJjLCByYW5kb20ubnVtKDEwMCwgMjAwKSk7XG5cbiAgICAgICAgICAgIGlmIChyYW5kb20uYm9vbCgwLjgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYXJ0aWNsZS5jbG9ja3dpc2UgPSAhdGhpcy5wYXJ0aWNsZS5jbG9ja3dpc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmMgPSBjaGFuZ2VEaXJlY3Rpb24odGhpcy5hcmMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIGNvbnN0YW50IHZlbG9jaXR5IGFuZCB0aGV0YSBiZXR3ZWVuIDAgYW5kIDLPgC5cbiAgICBjb25zdCBkZWx0YSA9IHRoaXMub3B0aW9ucy5zcGVlZCAvIHRoaXMuYXJjLnI7XG4gICAgdGhpcy5pbnRlcnZhbCAtPSBkZWx0YTtcblxuICAgIHRoaXMuYXJjLnQgKz0gKHRoaXMucGFydGljbGUuY2xvY2t3aXNlID8gLWRlbHRhIDogK2RlbHRhKTtcbiAgICB0aGlzLmFyYy50ID0gKHRoaXMuYXJjLnQgPiAwID8gdGhpcy5hcmMudCAlIFJBRC50MzYwIDogUkFELnQzNjAgKyB0aGlzLmFyYy50KTtcblxuICAgIHRoaXMucGFydGljbGUueCA9IHRoaXMuYXJjLnggKyB0aGlzLmFyYy5yICogTWF0aC5jb3ModGhpcy5hcmMudCk7XG4gICAgdGhpcy5wYXJ0aWNsZS55ID0gdGhpcy5hcmMueSAtIHRoaXMuYXJjLnIgKiBNYXRoLnNpbih0aGlzLmFyYy50KTtcblxuICAgIC8vIE92ZXJmbG93LlxuICAgIGlmICh0aGlzLnBhcnRpY2xlLnggPCAwKSB7XG4gICAgICAgIHRoaXMucGFydGljbGUueCArPSB0aGlzLmJvdW5kcy53aWR0aDtcbiAgICAgICAgdGhpcy5hcmMueCArPSB0aGlzLmJvdW5kcy53aWR0aFxuICAgIH0gZWxzZSBpZiAodGhpcy5wYXJ0aWNsZS54ID4gdGhpcy5ib3VuZHMud2lkdGgpIHtcbiAgICAgICAgdGhpcy5wYXJ0aWNsZS54IC09IHRoaXMuYm91bmRzLndpZHRoO1xuICAgICAgICB0aGlzLmFyYy54IC09IHRoaXMuYm91bmRzLndpZHRoXG4gICAgfVxuXG4gICAgaWYgKHRoaXMucGFydGljbGUueSA8IDApIHtcbiAgICAgICAgdGhpcy5wYXJ0aWNsZS55ICs9IHRoaXMuYm91bmRzLmhlaWdodDsgLy8gVE9ETyBzaXplIG9mIGFyZWFcbiAgICAgICAgdGhpcy5hcmMueSArPSB0aGlzLmJvdW5kcy5oZWlnaHRcbiAgICB9IGVsc2UgaWYgKHRoaXMucGFydGljbGUueSA+IHRoaXMuYm91bmRzLmhlaWdodCkge1xuICAgICAgICB0aGlzLnBhcnRpY2xlLnkgLT0gdGhpcy5ib3VuZHMuaGVpZ2h0O1xuICAgICAgICB0aGlzLmFyYy55IC09IHRoaXMuYm91bmRzLmhlaWdodFxuICAgIH1cbn1cblxuZnVuY3Rpb24gbW92ZUFyYyhhcmMsIG5ld1JhZGl1cykge1xuICAgIGNvbnN0IHIwID0gYXJjLnI7XG4gICAgY29uc3QgcjEgPSBuZXdSYWRpdXM7XG5cbiAgICAvLyBNb3ZlcyBhcmMgY2VudGVyIHRvIG5ldyByYWRpdXMgd2hpbGUga2VlcGluZyB0aGV0YSBjb25zdGFudC5cbiAgICBhcmMueCAtPSAocjEgLSByMCkgKiBNYXRoLmNvcyhhcmMudCk7XG4gICAgYXJjLnkgKz0gKHIxIC0gcjApICogTWF0aC5zaW4oYXJjLnQpO1xuICAgIGFyYy5yID0gcjE7XG5cbiAgICByZXR1cm4gYXJjO1xufVxuXG5mdW5jdGlvbiBjaGFuZ2VEaXJlY3Rpb24oYXJjKSB7XG4gICAgYXJjLnQgPSAoYXJjLnQgKyBSQUQudDE4MCkgJSBSQUQudDM2MDtcbiAgICBhcmMueCAtPSAoMiAqIGFyYy5yKSAqIE1hdGguY29zKGFyYy50KTtcbiAgICBhcmMueSArPSAoMiAqIGFyYy5yKSAqIE1hdGguc2luKGFyYy50KTtcblxuICAgIHJldHVybiBhcmM7XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZVZpc2lvbkdyaWRQb2ludHMocGFydGljbGUpIHtcbiAgICBjb25zdCBncmlkU2l6ZSA9IDU7XG4gICAgY29uc3QgdmlzaW9uUmFkaXVzID0gNTA7XG5cbiAgICBjb25zdCByMCA9IE1hdGgucG93KHZpc2lvblJhZGl1cywgMik7XG4gICAgY29uc3QgcjEgPSBNYXRoLnBvdyh2aXNpb25SYWRpdXMgLSBncmlkU2l6ZSwgMik7XG5cbiAgICBjb25zdCBwb2ludHMgPSBbXTtcbiAgICBmb3IgKGxldCB4ID0gLXZpc2lvblJhZGl1czsgeCA8PSB2aXNpb25SYWRpdXM7IHggKz0gZ3JpZFNpemUpIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IC12aXNpb25SYWRpdXM7IHkgPD0gdmlzaW9uUmFkaXVzOyB5ICs9IGdyaWRTaXplKSB7XG4gICAgICAgICAgICAvLyBIYWxmIG9mIHRyaWFuZ2xlXG4gICAgICAgICAgICBpZiAoeCA+IC15KSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFZpc2lvbiBiYW5kXG4gICAgICAgICAgICBjb25zdCBwID0gTWF0aC5wb3coeCwgMikgKyBNYXRoLnBvdyh5LCAyKTtcbiAgICAgICAgICAgIGlmIChwID4gcjAgfHwgcCA8IHIxKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS12aXNpb24tZG90JztcbiAgICAgICAgICAgIGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBwYXJ0aWNsZS5jb2xvcjtcbiAgICAgICAgICAgIGRpdi5zdHlsZS5sZWZ0ID0gYCR7eCArIHZpc2lvblJhZGl1c31weGA7XG4gICAgICAgICAgICBkaXYuc3R5bGUudG9wID0gYCR7eSArIHZpc2lvblJhZGl1c31weGA7XG5cbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHsgeCwgeSwgZGl2IH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvaW50cztcbn1cblxuZnVuY3Rpb24gcmVwYWludENvbnRhaW5lcihjb250YWluZXJOb2RlLCBwYXJ0aWNsZSkge1xuICAgIGNvbnRhaW5lck5vZGUuc3R5bGUubGVmdCA9IGAke3BhcnRpY2xlLnh9cHhgO1xuICAgIGNvbnRhaW5lck5vZGUuc3R5bGUudG9wID0gYCR7cGFydGljbGUueX1weGA7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRCb2R5KGFyYywgYm9keU5vZGUsIHBhcnRpY2xlKSB7XG4gICAgY29uc3QgcmFkID0gcGFydGljbGUuY2xvY2t3aXNlXG4gICAgICAgID8gUkFELnQxODAgLSBhcmMudFxuICAgICAgICA6IFJBRC50MzYwIC0gYXJjLnQ7XG5cbiAgICBib2R5Tm9kZS5zdHlsZS50cmFuc2Zvcm0gPSBgcm90YXRlKCR7cmFkICsgUkFELnQ0NX1yYWQpYDtcbn1cblxuZnVuY3Rpb24gcmVwYWludFZpc2lvbihhcmMsIHZpc2lvbk5vZGUsIHBhcnRpY2xlKSB7XG4gICAgaWYgKHZpc2lvbk5vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmFkID0gcGFydGljbGUuY2xvY2t3aXNlXG4gICAgICAgID8gUkFELnQxODAgLSBhcmMudFxuICAgICAgICA6IFJBRC50MzYwIC0gYXJjLnQ7XG5cbiAgICB2aXNpb25Ob2RlLnN0eWxlLnRyYW5zZm9ybSA9IGByb3RhdGUoJHtyYWQgKyBSQUQudDQ1fXJhZClgO1xufVxuXG5mdW5jdGlvbiByZXBhaW50Q2lyY2xlKGFyYywgY2lyY2xlTm9kZSkge1xuICAgIGlmIChjaXJjbGVOb2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNpcmNsZU5vZGUuc3R5bGUud2lkdGggPSBgJHsyICogYXJjLnJ9cHhgO1xuICAgIGNpcmNsZU5vZGUuc3R5bGUuaGVpZ2h0ID0gYCR7MiAqIGFyYy5yfXB4YDtcblxuICAgIGNpcmNsZU5vZGUuc3R5bGUubGVmdCA9IGAtJHthcmMuciArIGFyYy5yICogTWF0aC5jb3MoYXJjLnQpfXB4YDtcbiAgICBjaXJjbGVOb2RlLnN0eWxlLnRvcCA9IGAtJHthcmMuciAtIGFyYy5yICogTWF0aC5zaW4oYXJjLnQpfXB4YDtcblxuICAgIGNpcmNsZU5vZGUuc3R5bGUuYm9yZGVyUmFkaXVzID0gYCR7YXJjLnJ9cHhgO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQYXJ0aWNsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9wYXJ0aWNsZS5qcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTtBQUFBO0FBQ0E7Ozs7O0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFIQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9");
+eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 14);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 16);\n\nvar _store = __webpack_require__(/*! ./store */ 22);\n\nvar _store2 = _interopRequireDefault(_store);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar random = {\n bool: function bool(weight) {\n return Math.random() < (weight || 0.5);\n },\n color: function color() {\n return 'rgb(' + Math.floor(Math.random() * 255) + ', ' + Math.floor(Math.random() * 255) + ', ' + Math.floor(Math.random() * 255) + ')';\n },\n num: function num(min, max) {\n return min + Math.round(Math.random() * max);\n }\n};\n\n// ===== Constructor =====\n\nfunction Particle(parent, bounds, config, globalGrid) {\n this.config = Object.assign({\n bounds: bounds,\n color: random.color(),\n gridSize: 5,\n randomize: false,\n showMovementCircle: false,\n showVisionGrid: false,\n speed: 4,\n visionRadius: 50\n }, config);\n\n this.grids = {\n global: globalGrid,\n vision: calculateVisionGrid(this.config)\n };\n\n this.arc = {\n centerX: random.num(0, bounds.width),\n centerY: random.num(0, bounds.height),\n clockwise: random.bool(),\n endX: 0,\n endY: 0,\n length: random.num(_enums.RAD.t90, _enums.RAD.t360),\n radius: random.num(100, 200),\n theta: random.num(_enums.RAD.t90, _enums.RAD.t360)\n };\n\n this.nodes = {\n body: createBodyNode(this.config),\n circle: undefined,\n container: createContainerNode(this.config),\n parent: parent,\n vision: undefined,\n visionGrid: undefined\n };\n\n this.nodes.container.appendChild(this.nodes.body);\n parent.appendChild(this.nodes.container);\n\n this.updateConfig(this.config);\n this.nextFrame();\n};\n\n// ===== PROTOTYPE =====\n\nParticle.prototype.remove = function () {\n this.nodes.parent.removeChild(this.nodes.container);\n return this;\n};\n\nParticle.prototype.nextFrame = function () {\n // this.visionGrid = updateVisionGrid(this.visionGrid, this.globalGrid, this.particle);\n this.arc = updateArc(this.arc, this.config);\n\n repaintContainer(this.nodes.container, this.arc);\n repaintBody(this.nodes.body, this.arc);\n repaintCircle(this.nodes.circle, this.arc);\n // repaintVision(this.arc, this.nodes.vision, this.visionGrid, this.visionGridDivs);\n};\n\nParticle.prototype.updateConfig = function (config) {\n Object.assign(this.config, config);\n\n var _config = this.config,\n showMovementCircle = _config.showMovementCircle,\n showVisionGrid = _config.showVisionGrid;\n\n\n if (showMovementCircle === true && this.nodes.circle === undefined) {\n this.nodes.circle = createCircleNode(config);\n this.nodes.container.appendChild(this.nodes.circle);\n }\n\n if (showMovementCircle === false && this.nodes.circle !== undefined) {\n this.nodes.container.removeChild(this.nodes.circle);\n delete this.nodes.circle;\n }\n\n if (showVisionGrid === true && this.nodes.vision === undefined) {\n this.nodes.vision = createVisionNode(config, this.grids);\n // visionNode.appendChild(div);\n this.nodes.container.appendChild(this.nodes.vision);\n }\n\n if (showMovementCircle === false && this.nodes.circle !== undefined) {\n this.nodes.container.removeChild(this.nodes.vision);\n delete this.nodes.vision;\n }\n\n // if (config.showVisionGrid === false && this.nodes.vision !== undefined) {\n // // this.nodes.container.removeChild(this.vision);\n // // delete this.vision;\n //\n // // this.visionGrid.forEach(point => {\n // // this.vision.removeChild(point.div);\n // // });\n // // this.visionGrid = [];\n // }\n};\n\n// ===== DOM CREATION =====\n\nfunction createBodyNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-body';\n node.style.backgroundColor = config.color;\n return node;\n}\n\nfunction createCircleNode(config) {\n if (config.showMovementCircle === false) {\n return undefined;\n }\n\n var node = document.createElement('div');\n node.className = 'particle-movement-circle';\n node.style.borderColor = config.color;\n return node;\n}\n\nfunction createContainerNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-container';\n return node;\n}\n\nfunction createVisionNode(config) {\n if (config.showVisionGrid === false) {\n return undefined;\n }\n\n var node = document.createElement('div');\n node.className = 'particle-vision';\n\n return node;\n}\n\nfunction createVisionGridNodes(config, grids) {\n if (config.showVisionGrid === false) {\n return undefined;\n }\n\n return grids.visionGrid.forEach(function (acc, _ref) {\n var x = _ref.x,\n y = _ref.y;\n\n var div = document.createElement('div');\n div.className = 'particle-vision-dot';\n // div.style.backgroundColor = config.color;\n div.style.left = x + config.visionRadius + 'px';\n div.style.top = y + config.visionRadius + 'px';\n\n if (acc[x] === undefined) {\n acc[x] = {};\n }\n\n acc[x][y] = div;\n\n return acc;\n }, {});\n}\n\n// ===== CALCULATIONS =====\n\nfunction updateArc(arc, _ref2) {\n var bounds = _ref2.bounds,\n randomize = _ref2.randomize,\n speed = _ref2.speed;\n\n // Randomly change radius and rotation direction.\n if (arc.length <= 0) {\n arc.length = random.num(_enums.RAD.t90, _enums.RAD.t360);\n\n if (randomize === true) {\n arc = moveArc(arc, random.num(100, 200));\n\n if (random.bool(0.8)) {\n arc.clockwise = !arc.clockwise;\n arc = changeDirection(arc);\n }\n }\n }\n\n // Ensure constant velocity and theta between 0 and 2π.\n var delta = speed / arc.radius;\n arc.length -= delta;\n\n arc.theta += arc.clockwise ? -delta : +delta;\n arc.theta = arc.theta > 0 ? arc.theta % _enums.RAD.t360 : _enums.RAD.t360 + arc.theta;\n\n arc.endX = arc.centerX + arc.radius * Math.cos(arc.theta);\n arc.endY = arc.centerY - arc.radius * Math.sin(arc.theta);\n\n // // Overflow.\n if (arc.endX < 0) {\n arc.endX += bounds.width;\n arc.centerX += bounds.width;\n } else if (arc.endX > bounds.width) {\n arc.endX -= bounds.width;\n arc.centerX -= bounds.width;\n }\n\n if (arc.endY < 0) {\n arc.endY += bounds.height;\n arc.centerY += bounds.height;\n } else if (arc.endY > bounds.height) {\n arc.endY -= bounds.height;\n arc.centerY -= bounds.height;\n }\n\n return arc;\n}\n\n// function updateVisionGrid(visionGrid, globalGrid, particle) {\n// return visionGrid.reduce((acc, point) => {\n// // Location of point on grid\n// const x = Math.round(particle.x + point.x);\n// const y = Math.round(particle.y + point.y);\n//\n// const gridX = x - x % 5;\n// const gridY = y - y % 5;\n//\n// // console.warn(gridX, particle.x, point.x);\n// point.touch = (globalGrid[gridX] !== undefined && globalGrid[gridX][gridY] !== undefined);\n//\n// if (point.touch) {\n// console.warn('yay');\n// }\n//\n// return acc.concat(point);\n// }, []);\n// }\n//\nfunction moveArc(arc, newRadius) {\n var r0 = arc.radius;\n var r1 = newRadius;\n\n // Moves arc center to new radius while keeping theta constant.\n arc.centerX -= (r1 - r0) * Math.cos(arc.theta);\n arc.centerY += (r1 - r0) * Math.sin(arc.theta);\n arc.radius = r1;\n\n return arc;\n}\n\nfunction changeDirection(arc) {\n arc.theta = (arc.theta + _enums.RAD.t180) % _enums.RAD.t360;\n arc.centerX -= 2 * arc.radius * Math.cos(arc.theta);\n arc.centerY += 2 * arc.radius * Math.sin(arc.theta);\n\n return arc;\n}\n\nfunction calculateVisionGrid(config) {\n if (config.showVisionGrid === false) {\n return null;\n }\n\n var side = config.gridSize,\n radius = config.visionRadius;\n\n var r0 = Math.pow(radius, 2);\n var r1 = Math.pow(radius - side, 2);\n\n var points = [];\n for (var x = -radius; x <= radius; x += side) {\n for (var y = -radius; y <= radius; y += side) {\n // Half of triangle\n if (x > -y) {\n continue;\n }\n\n // Vision band\n var p = Math.pow(x, 2) + Math.pow(y, 2);\n if (p > r0 || p < r1) {\n continue;\n }\n\n points.push({ x: x, y: y, touch: false });\n }\n }\n\n return points;\n}\n\n// ===== RENDERING =====\nfunction repaintContainer(node, arc) {\n node.style.left = arc.endX + 'px';\n node.style.top = arc.endY + 'px';\n}\n\nfunction repaintBody(node, arc) {\n var rad = arc.clockwise ? _enums.RAD.t180 - arc.theta : _enums.RAD.t360 - arc.theta;\n\n node.style.transform = 'rotate(' + (rad + _enums.RAD.t45) + 'rad)';\n}\n\nfunction repaintCircle(node, arc) {\n if (node === undefined) {\n return;\n }\n\n node.style.width = 2 * arc.radius + 'px';\n node.style.height = 2 * arc.radius + 'px';\n\n node.style.left = '-' + (arc.radius + arc.radius * Math.cos(arc.theta)) + 'px';\n node.style.top = '-' + (arc.radius - arc.radius * Math.sin(arc.theta)) + 'px';\n\n node.style.borderRadius = arc.radius + 'px';\n}\n\n// function repaintVision(arc, visionNode, visionGrid, visionGridDivs) {\n// if (visionNode === undefined) {\n// return;\n// }\n//\n// const rad = arc.clockwise\n// ? RAD.t180 - arc.theta\n// : RAD.t360 - arc.theta;\n//\n// // visionNode.style.transform = `rotate(${rad + RAD.t45}rad)`;\n//\n// visionGrid.forEach(({ x, y, touch }) => {\n// if (touch === true) {\n// console.warn(x, y)\n// visionGridDivs[x][y].style.background = 'black';\n// }\n// });\n// }\n\nexports.default = Particle;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgUkFEIH0gZnJvbSAnLi9lbnVtcyc7XG5pbXBvcnQgU3RvcmUgZnJvbSAnLi9zdG9yZSc7XG5cbmNvbnN0IHJhbmRvbSA9IHtcbiAgICBib29sOiAod2VpZ2h0KSA9PiBNYXRoLnJhbmRvbSgpIDwgKHdlaWdodCB8fCAwLjUpLFxuICAgIGNvbG9yOiAoKSA9PiBgcmdiKCR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU1KX0sICR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU1KX0sICR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjU1KX0pYCxcbiAgICBudW06IChtaW4sIG1heCkgPT4gbWluICsgTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogbWF4KSxcbn1cblxuLy8gPT09PT0gQ29uc3RydWN0b3IgPT09PT1cblxuZnVuY3Rpb24gUGFydGljbGUocGFyZW50LCBib3VuZHMsIGNvbmZpZywgZ2xvYmFsR3JpZCkge1xuICAgIHRoaXMuY29uZmlnID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgY29sb3I6IHJhbmRvbS5jb2xvcigpLFxuICAgICAgICBncmlkU2l6ZTogNSxcbiAgICAgICAgcmFuZG9taXplOiBmYWxzZSxcbiAgICAgICAgc2hvd01vdmVtZW50Q2lyY2xlOiBmYWxzZSxcbiAgICAgICAgc2hvd1Zpc2lvbkdyaWQ6IGZhbHNlLFxuICAgICAgICBzcGVlZDogNCxcbiAgICAgICAgdmlzaW9uUmFkaXVzOiA1MFxuICAgIH0sIGNvbmZpZyk7XG5cbiAgICB0aGlzLmdyaWRzID0ge1xuICAgICAgICBnbG9iYWw6IGdsb2JhbEdyaWQsXG4gICAgICAgIHZpc2lvbjogY2FsY3VsYXRlVmlzaW9uR3JpZCh0aGlzLmNvbmZpZylcbiAgICB9O1xuXG4gICAgdGhpcy5hcmMgPSB7XG4gICAgICAgIGNlbnRlclg6IHJhbmRvbS5udW0oMCwgYm91bmRzLndpZHRoKSxcbiAgICAgICAgY2VudGVyWTogcmFuZG9tLm51bSgwLCBib3VuZHMuaGVpZ2h0KSxcbiAgICAgICAgY2xvY2t3aXNlOiByYW5kb20uYm9vbCgpLFxuICAgICAgICBlbmRYOiAwLFxuICAgICAgICBlbmRZOiAwLFxuICAgICAgICBsZW5ndGg6IHJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApLFxuICAgICAgICByYWRpdXM6IHJhbmRvbS5udW0oMTAwLCAyMDApLFxuICAgICAgICB0aGV0YTogcmFuZG9tLm51bShSQUQudDkwLCBSQUQudDM2MCksXG4gICAgfTtcblxuICAgIHRoaXMubm9kZXMgPSB7XG4gICAgICAgIGJvZHk6IGNyZWF0ZUJvZHlOb2RlKHRoaXMuY29uZmlnKSxcbiAgICAgICAgY2lyY2xlOiB1bmRlZmluZWQsXG4gICAgICAgIGNvbnRhaW5lcjogY3JlYXRlQ29udGFpbmVyTm9kZSh0aGlzLmNvbmZpZyksXG4gICAgICAgIHBhcmVudCxcbiAgICAgICAgdmlzaW9uOiB1bmRlZmluZWQsXG4gICAgICAgIHZpc2lvbkdyaWQ6IHVuZGVmaW5lZCxcbiAgICB9O1xuXG4gICAgdGhpcy5ub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5ub2Rlcy5ib2R5KTtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5ub2Rlcy5jb250YWluZXIpO1xuXG4gICAgdGhpcy51cGRhdGVDb25maWcodGhpcy5jb25maWcpO1xuICAgIHRoaXMubmV4dEZyYW1lKCk7XG59O1xuXG4vLyA9PT09PSBQUk9UT1RZUEUgPT09PT1cblxuUGFydGljbGUucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMubm9kZXMucGFyZW50LnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY29udGFpbmVyKTtcbiAgICByZXR1cm4gdGhpcztcbn1cblxuUGFydGljbGUucHJvdG90eXBlLm5leHRGcmFtZSA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIHRoaXMudmlzaW9uR3JpZCA9IHVwZGF0ZVZpc2lvbkdyaWQodGhpcy52aXNpb25HcmlkLCB0aGlzLmdsb2JhbEdyaWQsIHRoaXMucGFydGljbGUpO1xuICAgIHRoaXMuYXJjID0gdXBkYXRlQXJjKHRoaXMuYXJjLCB0aGlzLmNvbmZpZyk7XG5cbiAgICByZXBhaW50Q29udGFpbmVyKHRoaXMubm9kZXMuY29udGFpbmVyLCB0aGlzLmFyYyk7XG4gICAgcmVwYWludEJvZHkodGhpcy5ub2Rlcy5ib2R5LCB0aGlzLmFyYyk7XG4gICAgcmVwYWludENpcmNsZSh0aGlzLm5vZGVzLmNpcmNsZSwgdGhpcy5hcmMpO1xuICAgIC8vIHJlcGFpbnRWaXNpb24odGhpcy5hcmMsIHRoaXMubm9kZXMudmlzaW9uLCB0aGlzLnZpc2lvbkdyaWQsIHRoaXMudmlzaW9uR3JpZERpdnMpO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUudXBkYXRlQ29uZmlnID0gZnVuY3Rpb24oY29uZmlnKSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLmNvbmZpZywgY29uZmlnKTtcblxuICAgIGNvbnN0IHsgc2hvd01vdmVtZW50Q2lyY2xlLCBzaG93VmlzaW9uR3JpZCB9ID0gdGhpcy5jb25maWc7XG5cbiAgICBpZiAoc2hvd01vdmVtZW50Q2lyY2xlID09PSB0cnVlICYmIHRoaXMubm9kZXMuY2lyY2xlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5jaXJjbGUgPSBjcmVhdGVDaXJjbGVOb2RlKGNvbmZpZyk7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbiAgICB9XG5cbiAgICBpZiAoc2hvd01vdmVtZW50Q2lyY2xlID09PSBmYWxzZSAmJiB0aGlzLm5vZGVzLmNpcmNsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbiAgICAgICAgZGVsZXRlIHRoaXMubm9kZXMuY2lyY2xlO1xuICAgIH1cblxuICAgIGlmIChzaG93VmlzaW9uR3JpZCA9PT0gdHJ1ZSAmJiB0aGlzLm5vZGVzLnZpc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubm9kZXMudmlzaW9uID0gY3JlYXRlVmlzaW9uTm9kZShjb25maWcsIHRoaXMuZ3JpZHMpO1xuICAgICAgICAvLyB2aXNpb25Ob2RlLmFwcGVuZENoaWxkKGRpdik7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMubm9kZXMudmlzaW9uKTtcbiAgICB9XG5cbiAgICBpZiAoc2hvd01vdmVtZW50Q2lyY2xlID09PSBmYWxzZSAmJiB0aGlzLm5vZGVzLmNpcmNsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMubm9kZXMudmlzaW9uKTtcbiAgICAgICAgZGVsZXRlIHRoaXMubm9kZXMudmlzaW9uO1xuICAgIH1cblxuICAgIC8vIGlmIChjb25maWcuc2hvd1Zpc2lvbkdyaWQgPT09IGZhbHNlICYmIHRoaXMubm9kZXMudmlzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyAgICAgLy8gdGhpcy5ub2Rlcy5jb250YWluZXIucmVtb3ZlQ2hpbGQodGhpcy52aXNpb24pO1xuICAgIC8vICAgICAvLyBkZWxldGUgdGhpcy52aXNpb247XG4gICAgLy9cbiAgICAvLyAgICAgLy8gdGhpcy52aXNpb25HcmlkLmZvckVhY2gocG9pbnQgPT4ge1xuICAgIC8vICAgICAvLyAgICAgdGhpcy52aXNpb24ucmVtb3ZlQ2hpbGQocG9pbnQuZGl2KTtcbiAgICAvLyAgICAgLy8gfSk7XG4gICAgLy8gICAgIC8vIHRoaXMudmlzaW9uR3JpZCA9IFtdO1xuICAgIC8vIH1cbn1cblxuLy8gPT09PT0gRE9NIENSRUFUSU9OID09PT09XG5cbmZ1bmN0aW9uIGNyZWF0ZUJvZHlOb2RlKGNvbmZpZykge1xuICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub2RlLmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS1ib2R5JztcbiAgICBub2RlLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2lyY2xlTm9kZShjb25maWcpIHtcbiAgICBpZiAoY29uZmlnLnNob3dNb3ZlbWVudENpcmNsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgbm9kZS5jbGFzc05hbWUgPSAncGFydGljbGUtbW92ZW1lbnQtY2lyY2xlJztcbiAgICBub2RlLnN0eWxlLmJvcmRlckNvbG9yID0gY29uZmlnLmNvbG9yO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVDb250YWluZXJOb2RlKGNvbmZpZykge1xuICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub2RlLmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS1jb250YWluZXInO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXNpb25Ob2RlKGNvbmZpZykge1xuICAgIGlmIChjb25maWcuc2hvd1Zpc2lvbkdyaWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLXZpc2lvbic7XG5cbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVmlzaW9uR3JpZE5vZGVzKGNvbmZpZywgZ3JpZHMpIHtcbiAgICBpZiAoY29uZmlnLnNob3dWaXNpb25HcmlkID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICByZXR1cm4gZ3JpZHMudmlzaW9uR3JpZC5mb3JFYWNoKChhY2MsIHsgeCwgeSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXYuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLXZpc2lvbi1kb3QnO1xuICAgICAgICAvLyBkaXYuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29uZmlnLmNvbG9yO1xuICAgICAgICBkaXYuc3R5bGUubGVmdCA9IGAke3ggKyBjb25maWcudmlzaW9uUmFkaXVzfXB4YDtcbiAgICAgICAgZGl2LnN0eWxlLnRvcCA9IGAke3kgKyBjb25maWcudmlzaW9uUmFkaXVzfXB4YDtcblxuICAgICAgICBpZiAoYWNjW3hdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGFjY1t4XSA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgYWNjW3hdW3ldID0gZGl2O1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xufVxuXG4vLyA9PT09PSBDQUxDVUxBVElPTlMgPT09PT1cblxuZnVuY3Rpb24gdXBkYXRlQXJjKGFyYywgeyBib3VuZHMsIHJhbmRvbWl6ZSwgc3BlZWQgfSkge1xuICAgIC8vIFJhbmRvbWx5IGNoYW5nZSByYWRpdXMgYW5kIHJvdGF0aW9uIGRpcmVjdGlvbi5cbiAgICBpZiAoYXJjLmxlbmd0aCA8PSAwKSB7XG4gICAgICAgIGFyYy5sZW5ndGggPSByYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKTtcblxuICAgICAgICBpZiAocmFuZG9taXplID09PSB0cnVlKSB7XG4gICAgICAgICAgICBhcmMgPSBtb3ZlQXJjKGFyYywgcmFuZG9tLm51bSgxMDAsIDIwMCkpO1xuXG4gICAgICAgICAgICBpZiAocmFuZG9tLmJvb2woMC44KSkge1xuICAgICAgICAgICAgICAgIGFyYy5jbG9ja3dpc2UgPSAhYXJjLmNsb2Nrd2lzZTtcbiAgICAgICAgICAgICAgICBhcmMgPSBjaGFuZ2VEaXJlY3Rpb24oYXJjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVuc3VyZSBjb25zdGFudCB2ZWxvY2l0eSBhbmQgdGhldGEgYmV0d2VlbiAwIGFuZCAyz4AuXG4gICAgY29uc3QgZGVsdGEgPSBzcGVlZCAvIGFyYy5yYWRpdXM7XG4gICAgYXJjLmxlbmd0aCAtPSBkZWx0YTtcblxuICAgIGFyYy50aGV0YSArPSAoYXJjLmNsb2Nrd2lzZSA/IC1kZWx0YSA6ICtkZWx0YSk7XG4gICAgYXJjLnRoZXRhID0gKGFyYy50aGV0YSA+IDAgPyBhcmMudGhldGEgJSBSQUQudDM2MCA6IFJBRC50MzYwICsgYXJjLnRoZXRhKTtcblxuICAgIGFyYy5lbmRYID0gYXJjLmNlbnRlclggKyBhcmMucmFkaXVzICogTWF0aC5jb3MoYXJjLnRoZXRhKTtcbiAgICBhcmMuZW5kWSA9IGFyYy5jZW50ZXJZIC0gYXJjLnJhZGl1cyAqIE1hdGguc2luKGFyYy50aGV0YSk7XG5cbiAgICAvLyAvLyBPdmVyZmxvdy5cbiAgICBpZiAoYXJjLmVuZFggPCAwKSB7XG4gICAgICAgIGFyYy5lbmRYICs9IGJvdW5kcy53aWR0aDtcbiAgICAgICAgYXJjLmNlbnRlclggKz0gYm91bmRzLndpZHRoXG4gICAgfSBlbHNlIGlmIChhcmMuZW5kWCA+IGJvdW5kcy53aWR0aCkge1xuICAgICAgICBhcmMuZW5kWCAtPSBib3VuZHMud2lkdGg7XG4gICAgICAgIGFyYy5jZW50ZXJYIC09IGJvdW5kcy53aWR0aFxuICAgIH1cblxuICAgIGlmIChhcmMuZW5kWSA8IDApIHtcbiAgICAgICAgYXJjLmVuZFkgKz0gYm91bmRzLmhlaWdodDsgXG4gICAgICAgIGFyYy5jZW50ZXJZICs9IGJvdW5kcy5oZWlnaHRcbiAgICB9IGVsc2UgaWYgKGFyYy5lbmRZID4gYm91bmRzLmhlaWdodCkge1xuICAgICAgICBhcmMuZW5kWSAtPSBib3VuZHMuaGVpZ2h0O1xuICAgICAgICBhcmMuY2VudGVyWSAtPSBib3VuZHMuaGVpZ2h0XG4gICAgfVxuXG4gICAgcmV0dXJuIGFyYztcbn1cblxuLy8gZnVuY3Rpb24gdXBkYXRlVmlzaW9uR3JpZCh2aXNpb25HcmlkLCBnbG9iYWxHcmlkLCBwYXJ0aWNsZSkge1xuLy8gICAgIHJldHVybiB2aXNpb25HcmlkLnJlZHVjZSgoYWNjLCBwb2ludCkgPT4ge1xuLy8gICAgICAgICAvLyBMb2NhdGlvbiBvZiBwb2ludCBvbiBncmlkXG4vLyAgICAgICAgIGNvbnN0IHggPSBNYXRoLnJvdW5kKHBhcnRpY2xlLnggKyBwb2ludC54KTtcbi8vICAgICAgICAgY29uc3QgeSA9IE1hdGgucm91bmQocGFydGljbGUueSArIHBvaW50LnkpO1xuLy9cbi8vICAgICAgICAgY29uc3QgZ3JpZFggPSB4IC0geCAlIDU7XG4vLyAgICAgICAgIGNvbnN0IGdyaWRZID0geSAtIHkgJSA1O1xuLy9cbi8vICAgICAgICAgLy8gY29uc29sZS53YXJuKGdyaWRYLCBwYXJ0aWNsZS54LCBwb2ludC54KTtcbi8vICAgICAgICAgcG9pbnQudG91Y2ggPSAoZ2xvYmFsR3JpZFtncmlkWF0gIT09IHVuZGVmaW5lZCAmJiBnbG9iYWxHcmlkW2dyaWRYXVtncmlkWV0gIT09IHVuZGVmaW5lZCk7XG4vL1xuLy8gICAgICAgICBpZiAocG9pbnQudG91Y2gpIHtcbi8vICAgICAgICAgICAgIGNvbnNvbGUud2FybigneWF5Jyk7XG4vLyAgICAgICAgIH1cbi8vXG4vLyAgICAgICAgIHJldHVybiBhY2MuY29uY2F0KHBvaW50KTtcbi8vICAgICB9LCBbXSk7XG4vLyB9XG4vL1xuZnVuY3Rpb24gbW92ZUFyYyhhcmMsIG5ld1JhZGl1cykge1xuICAgIGNvbnN0IHIwID0gYXJjLnJhZGl1cztcbiAgICBjb25zdCByMSA9IG5ld1JhZGl1cztcblxuICAgIC8vIE1vdmVzIGFyYyBjZW50ZXIgdG8gbmV3IHJhZGl1cyB3aGlsZSBrZWVwaW5nIHRoZXRhIGNvbnN0YW50LlxuICAgIGFyYy5jZW50ZXJYIC09IChyMSAtIHIwKSAqIE1hdGguY29zKGFyYy50aGV0YSk7XG4gICAgYXJjLmNlbnRlclkgKz0gKHIxIC0gcjApICogTWF0aC5zaW4oYXJjLnRoZXRhKTtcbiAgICBhcmMucmFkaXVzID0gcjE7XG5cbiAgICByZXR1cm4gYXJjO1xufVxuXG5mdW5jdGlvbiBjaGFuZ2VEaXJlY3Rpb24oYXJjKSB7XG4gICAgYXJjLnRoZXRhID0gKGFyYy50aGV0YSArIFJBRC50MTgwKSAlIFJBRC50MzYwO1xuICAgIGFyYy5jZW50ZXJYIC09ICgyICogYXJjLnJhZGl1cykgKiBNYXRoLmNvcyhhcmMudGhldGEpO1xuICAgIGFyYy5jZW50ZXJZICs9ICgyICogYXJjLnJhZGl1cykgKiBNYXRoLnNpbihhcmMudGhldGEpO1xuXG4gICAgcmV0dXJuIGFyYztcbn1cblxuZnVuY3Rpb24gY2FsY3VsYXRlVmlzaW9uR3JpZChjb25maWcpIHtcbiAgICBpZiAoY29uZmlnLnNob3dWaXNpb25HcmlkID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB7IGdyaWRTaXplOiBzaWRlLCB2aXNpb25SYWRpdXM6IHJhZGl1cyB9ID0gY29uZmlnO1xuICAgIGNvbnN0IHIwID0gTWF0aC5wb3cocmFkaXVzLCAyKTtcbiAgICBjb25zdCByMSA9IE1hdGgucG93KHJhZGl1cyAtIHNpZGUsIDIpO1xuXG4gICAgY29uc3QgcG9pbnRzID0gW107XG4gICAgZm9yIChsZXQgeCA9IC1yYWRpdXM7IHggPD0gcmFkaXVzOyB4ICs9IHNpZGUpIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IC1yYWRpdXM7IHkgPD0gcmFkaXVzOyB5ICs9IHNpZGUpIHtcbiAgICAgICAgICAgIC8vIEhhbGYgb2YgdHJpYW5nbGVcbiAgICAgICAgICAgIGlmICh4ID4gLXkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVmlzaW9uIGJhbmRcbiAgICAgICAgICAgIGNvbnN0IHAgPSBNYXRoLnBvdyh4LCAyKSArIE1hdGgucG93KHksIDIpO1xuICAgICAgICAgICAgaWYgKHAgPiByMCB8fCBwIDwgcjEpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcG9pbnRzLnB1c2goeyB4LCB5LCB0b3VjaDogZmFsc2UgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcG9pbnRzO1xufVxuXG4vLyA9PT09PSBSRU5ERVJJTkcgPT09PT1cbmZ1bmN0aW9uIHJlcGFpbnRDb250YWluZXIobm9kZSwgYXJjKSB7XG4gICAgbm9kZS5zdHlsZS5sZWZ0ID0gYCR7YXJjLmVuZFh9cHhgO1xuICAgIG5vZGUuc3R5bGUudG9wID0gYCR7YXJjLmVuZFl9cHhgO1xufVxuXG5mdW5jdGlvbiByZXBhaW50Qm9keShub2RlLCBhcmMpIHtcbiAgICBjb25zdCByYWQgPSBhcmMuY2xvY2t3aXNlXG4gICAgICAgID8gUkFELnQxODAgLSBhcmMudGhldGFcbiAgICAgICAgOiBSQUQudDM2MCAtIGFyYy50aGV0YTtcblxuICAgIG5vZGUuc3R5bGUudHJhbnNmb3JtID0gYHJvdGF0ZSgke3JhZCArIFJBRC50NDV9cmFkKWA7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRDaXJjbGUobm9kZSwgYXJjKSB7XG4gICAgaWYgKG5vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbm9kZS5zdHlsZS53aWR0aCA9IGAkezIgKiBhcmMucmFkaXVzfXB4YDtcbiAgICBub2RlLnN0eWxlLmhlaWdodCA9IGAkezIgKiBhcmMucmFkaXVzfXB4YDtcblxuICAgIG5vZGUuc3R5bGUubGVmdCA9IGAtJHthcmMucmFkaXVzICsgYXJjLnJhZGl1cyAqIE1hdGguY29zKGFyYy50aGV0YSl9cHhgO1xuICAgIG5vZGUuc3R5bGUudG9wID0gYC0ke2FyYy5yYWRpdXMgLSBhcmMucmFkaXVzICogTWF0aC5zaW4oYXJjLnRoZXRhKX1weGA7XG5cbiAgICBub2RlLnN0eWxlLmJvcmRlclJhZGl1cyA9IGAke2FyYy5yYWRpdXN9cHhgO1xufVxuXG4vLyBmdW5jdGlvbiByZXBhaW50VmlzaW9uKGFyYywgdmlzaW9uTm9kZSwgdmlzaW9uR3JpZCwgdmlzaW9uR3JpZERpdnMpIHtcbi8vICAgICBpZiAodmlzaW9uTm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4vLyAgICAgICAgIHJldHVybjtcbi8vICAgICB9XG4vL1xuLy8gICAgIGNvbnN0IHJhZCA9IGFyYy5jbG9ja3dpc2Vcbi8vICAgICAgICAgPyBSQUQudDE4MCAtIGFyYy50aGV0YVxuLy8gICAgICAgICA6IFJBRC50MzYwIC0gYXJjLnRoZXRhO1xuLy9cbi8vICAgICAvLyB2aXNpb25Ob2RlLnN0eWxlLnRyYW5zZm9ybSA9IGByb3RhdGUoJHtyYWQgKyBSQUQudDQ1fXJhZClgO1xuLy9cbi8vICAgICB2aXNpb25HcmlkLmZvckVhY2goKHsgeCwgeSwgdG91Y2ggfSkgPT4ge1xuLy8gICAgICAgICBpZiAodG91Y2ggPT09IHRydWUpIHtcbi8vICAgICAgICAgICAgIGNvbnNvbGUud2Fybih4LCB5KVxuLy8gICAgICAgICAgICAgdmlzaW9uR3JpZERpdnNbeF1beV0uc3R5bGUuYmFja2dyb3VuZCA9ICdibGFjayc7XG4vLyAgICAgICAgIH1cbi8vICAgICB9KTtcbi8vIH1cblxuZXhwb3J0IGRlZmF1bHQgUGFydGljbGU7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvcGFydGljbGUuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVJBO0FBQ0E7QUFVQTtBQUNBO0FBQ0E7QUFGQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUkE7QUFDQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBQUE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9");
/***/ }),
/* 34 */
@@ -974,7 +974,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 14);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _particle = __webpack_require__(/*! ./particle */ 33);\n\nvar _particle2 = _interopRequireDefault(_particle);\n\nvar _store = __webpack_require__(/*! ./store */ 22);\n\nvar _store2 = _interopRequireDefault(_store);\n\nvar _controls = __webpack_require__(/*! ./controls */ 21);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _enums = __webpack_require__(/*! ./enums */ 16);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction Animation2a() {\n this.options = {\n count: 1,\n maxCount: 10,\n randomize: true,\n showVisionGrid: true,\n showMovementCircle: false,\n speed: 4\n };\n\n this.container = document.getElementById('animation2a');\n this.bounds = this.container.getBoundingClientRect();\n\n this.particles = [];\n this.globalGrid = createGlobalGrid(this.container, this.bounds);\n\n var controls = new _controls2.default(document.getElementById('controls2a'), this.options);\n\n controls.mount().subscribe(this.subscriber.bind(this));\n\n this.updateAnimating(this.options.animating);\n this.updateCount(this.options.count);\n\n // TODO X dimension modified by core UI\n // TODO remove bottom padding from Disqus\n // TODO perf - cache trig or perform operations\n // TODO move animating into controls\n // TODO no randomize control except anim1\n\n // TODO ANIM2 put hazards in animation\n // TODO ANIM2 particle evade\n // TODO ANIM2 style hazards\n // TODO ANIM2a randomize hazards\n // TODO ANIM2a Vision grid touches\n // TODO ANIM2b Scale vision grid to 1000? particles\n\n // TODO ANIM3 Flocking\n};\n\nAnimation2a.prototype.subscriber = function (_ref) {\n var key = _ref.key,\n value = _ref.value;\n\n switch (key) {\n case _enums.CONTROLS.ANIMATING:\n this.updateAnimating(value);break;\n case _enums.CONTROLS.COUNT:\n this.updateCount(value);break;\n case _enums.CONTROLS.RANDOMIZE:\n this.updateRandomize(value);break;\n case _enums.CONTROLS.SPEED:\n this.updateSpeed(value);break;\n }\n};\n\nAnimation2a.prototype.nextFrame = function () {\n this.particles.forEach(function (p) {\n return p.nextFrame();\n });\n};\n\nAnimation2a.prototype.updateAnimating = function (isAnimating) {\n var _this = this;\n\n this.options.animating = isAnimating;\n\n if (isAnimating) {\n var fps$ = _rxjs2.default.Observable.interval(1000 / 32).takeWhile(function (_) {\n return _this.options.animating;\n });\n\n fps$.subscribe(this.nextFrame.bind(this));\n }\n};\n\nAnimation2a.prototype.updateCount = function (count) {\n while (this.particles.length >= count) {\n delete this.particles.pop().remove();\n }\n\n while (this.particles.length < count) {\n var p = new _particle2.default(this.container, this.bounds, this.options);\n this.particles.push(p);\n }\n};\n\nAnimation2a.prototype.updateRandomize = function (value) {\n this.options.randomize = value;\n this.particles.forEach(function (p) {\n return p.updateOptions({ randomize: value });\n });\n};\n\nAnimation2a.prototype.updateSpeed = function (value) {\n this.options.speed = value;\n this.particles.forEach(function (p) {\n return p.updateOptions({ speed: value });\n });\n};\n\nfunction createGlobalGrid(container, bounds) {\n var grid = {};\n var gridSize = 5;\n\n var hazards = [{ x: 100, y: 100, w: 100, h: 100 }, { x: 200, y: 200, w: 100, h: 100 }, { x: 600, y: 200, w: 100, h: 100 }];\n\n return hazards.reduce(function (acc, _ref2) {\n var x = _ref2.x,\n y = _ref2.y,\n w = _ref2.w,\n h = _ref2.h;\n\n var div = document.createElement('div');\n div.className = 'hazard';\n div.style.left = x + 'px';\n div.style.top = y + 'px';\n div.style.height = h + 'px';\n div.style.width = w + 'px';\n container.appendChild(div);\n\n for (var i = x; i <= x + w; i += gridSize) {\n for (var j = y; j <= y + h; j += gridSize) {\n if (acc[i] === undefined) {\n acc[i] = {};\n }\n\n if (acc[i][j] !== undefined) {\n continue;\n }\n\n var dot = document.createElement('dot');\n dot.className = 'hazard-dot';\n dot.style.left = i - x + 'px';\n dot.style.top = j - y + 'px';\n div.appendChild(dot);\n\n acc[i][j] = true;\n }\n }\n\n return acc;\n }, {});\n}\n\nexports.default = Animation2a;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uMmEuanM/YzJmNyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IFBhcnRpY2xlIGZyb20gJy4vcGFydGljbGUnO1xuaW1wb3J0IFN0b3JlIGZyb20gJy4vc3RvcmUnO1xuaW1wb3J0IENvbnRyb2xzIGZyb20gJy4vY29udHJvbHMnO1xuaW1wb3J0IHsgQ09OVFJPTFMgfSBmcm9tICcuL2VudW1zJztcblxuZnVuY3Rpb24gQW5pbWF0aW9uMmEoKSB7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICBjb3VudDogMSxcbiAgICAgICAgbWF4Q291bnQ6IDEwLFxuICAgICAgICByYW5kb21pemU6IHRydWUsXG4gICAgICAgIHNob3dWaXNpb25HcmlkOiB0cnVlLFxuICAgICAgICBzaG93TW92ZW1lbnRDaXJjbGU6IGZhbHNlLFxuICAgICAgICBzcGVlZDogNFxuICAgIH07XG5cbiAgICB0aGlzLmNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhbmltYXRpb24yYScpO1xuICAgIHRoaXMuYm91bmRzID0gdGhpcy5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB0aGlzLnBhcnRpY2xlcyA9IFtdO1xuICAgIHRoaXMuZ2xvYmFsR3JpZCA9IGNyZWF0ZUdsb2JhbEdyaWQodGhpcy5jb250YWluZXIsIHRoaXMuYm91bmRzKTtcblxuICAgIGNvbnN0IGNvbnRyb2xzID0gbmV3IENvbnRyb2xzKFxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29udHJvbHMyYScpLFxuICAgICAgICB0aGlzLm9wdGlvbnNcbiAgICApO1xuXG4gICAgY29udHJvbHMubW91bnQoKS5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVyLmJpbmQodGhpcykpO1xuXG4gICAgdGhpcy51cGRhdGVBbmltYXRpbmcodGhpcy5vcHRpb25zLmFuaW1hdGluZyk7XG4gICAgdGhpcy51cGRhdGVDb3VudCh0aGlzLm9wdGlvbnMuY291bnQpO1xuXG4gICAgLy8gVE9ETyBYIGRpbWVuc2lvbiBtb2RpZmllZCBieSBjb3JlIFVJXG4gICAgLy8gVE9ETyByZW1vdmUgYm90dG9tIHBhZGRpbmcgZnJvbSBEaXNxdXNcbiAgICAvLyBUT0RPIHBlcmYgLSBjYWNoZSB0cmlnIG9yIHBlcmZvcm0gb3BlcmF0aW9uc1xuICAgIC8vIFRPRE8gbW92ZSBhbmltYXRpbmcgaW50byBjb250cm9sc1xuICAgIC8vIFRPRE8gbm8gcmFuZG9taXplIGNvbnRyb2wgZXhjZXB0IGFuaW0xXG5cbiAgICAvLyBUT0RPIEFOSU0yIHB1dCBoYXphcmRzIGluIGFuaW1hdGlvblxuICAgIC8vIFRPRE8gQU5JTTIgcGFydGljbGUgZXZhZGVcbiAgICAvLyBUT0RPIEFOSU0yIHN0eWxlIGhhemFyZHNcbiAgICAvLyBUT0RPIEFOSU0yYSByYW5kb21pemUgaGF6YXJkc1xuICAgIC8vIFRPRE8gQU5JTTJhIFZpc2lvbiBncmlkIHRvdWNoZXNcbiAgICAvLyBUT0RPIEFOSU0yYiBTY2FsZSB2aXNpb24gZ3JpZCB0byAxMDAwPyBwYXJ0aWNsZXNcblxuICAgIC8vIFRPRE8gQU5JTTMgRmxvY2tpbmdcbn07XG5cbkFuaW1hdGlvbjJhLnByb3RvdHlwZS5zdWJzY3JpYmVyID0gZnVuY3Rpb24oeyBrZXksIHZhbHVlIH0pIHtcbiAgICBzd2l0Y2goa2V5KSB7XG4gICAgICAgIGNhc2UgQ09OVFJPTFMuQU5JTUFUSU5HOiB0aGlzLnVwZGF0ZUFuaW1hdGluZyh2YWx1ZSk7IGJyZWFrO1xuICAgICAgICBjYXNlIENPTlRST0xTLkNPVU5UOiB0aGlzLnVwZGF0ZUNvdW50KHZhbHVlKTsgYnJlYWs7XG4gICAgICAgIGNhc2UgQ09OVFJPTFMuUkFORE9NSVpFOiB0aGlzLnVwZGF0ZVJhbmRvbWl6ZSh2YWx1ZSk7IGJyZWFrO1xuICAgICAgICBjYXNlIENPTlRST0xTLlNQRUVEOiB0aGlzLnVwZGF0ZVNwZWVkKHZhbHVlKTsgYnJlYWs7XG4gICAgfVxufVxuXG5BbmltYXRpb24yYS5wcm90b3R5cGUubmV4dEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5wYXJ0aWNsZXMuZm9yRWFjaChwID0+IHAubmV4dEZyYW1lKCkpO1xufVxuXG5BbmltYXRpb24yYS5wcm90b3R5cGUudXBkYXRlQW5pbWF0aW5nID0gZnVuY3Rpb24oaXNBbmltYXRpbmcpIHtcbiAgICB0aGlzLm9wdGlvbnMuYW5pbWF0aW5nID0gaXNBbmltYXRpbmc7XG5cbiAgICBpZiAoaXNBbmltYXRpbmcpIHtcbiAgICAgICAgY29uc3QgZnBzJCA9IFJ4Lk9ic2VydmFibGUuaW50ZXJ2YWwoMTAwMCAvIDMyKVxuICAgICAgICAgICAgLnRha2VXaGlsZShfID0+IHRoaXMub3B0aW9ucy5hbmltYXRpbmcpO1xuXG4gICAgICAgIGZwcyQuc3Vic2NyaWJlKHRoaXMubmV4dEZyYW1lLmJpbmQodGhpcykpO1xuICAgIH1cbn1cblxuQW5pbWF0aW9uMmEucHJvdG90eXBlLnVwZGF0ZUNvdW50ID0gZnVuY3Rpb24oY291bnQpIHtcbiAgICB3aGlsZSAodGhpcy5wYXJ0aWNsZXMubGVuZ3RoID49IGNvdW50KSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnBhcnRpY2xlcy5wb3AoKS5yZW1vdmUoKTtcbiAgICB9XG5cbiAgICB3aGlsZSAodGhpcy5wYXJ0aWNsZXMubGVuZ3RoIDwgY291bnQpIHtcbiAgICAgICAgY29uc3QgcCA9IG5ldyBQYXJ0aWNsZSh0aGlzLmNvbnRhaW5lciwgdGhpcy5ib3VuZHMsIHRoaXMub3B0aW9ucyk7XG4gICAgICAgIHRoaXMucGFydGljbGVzLnB1c2gocCk7XG4gICAgfVxufVxuXG5BbmltYXRpb24yYS5wcm90b3R5cGUudXBkYXRlUmFuZG9taXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLm9wdGlvbnMucmFuZG9taXplID0gdmFsdWU7XG4gICAgdGhpcy5wYXJ0aWNsZXMuZm9yRWFjaChwID0+IHAudXBkYXRlT3B0aW9ucyh7IHJhbmRvbWl6ZTogdmFsdWUgfSkpO1xufVxuXG5BbmltYXRpb24yYS5wcm90b3R5cGUudXBkYXRlU3BlZWQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHRoaXMub3B0aW9ucy5zcGVlZCA9IHZhbHVlO1xuICAgIHRoaXMucGFydGljbGVzLmZvckVhY2gocCA9PiBwLnVwZGF0ZU9wdGlvbnMoeyBzcGVlZDogdmFsdWUgfSkpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVHbG9iYWxHcmlkKGNvbnRhaW5lciwgYm91bmRzKSB7XG4gICAgY29uc3QgZ3JpZCA9IHt9O1xuICAgIGNvbnN0IGdyaWRTaXplID0gNTtcblxuICAgIGNvbnN0IGhhemFyZHMgPSBbXG4gICAgICAgIHsgeDogMTAwLCB5OiAxMDAsIHc6IDEwMCwgaDogMTAwIH0sXG4gICAgICAgIHsgeDogMjAwLCB5OiAyMDAsIHc6IDEwMCwgaDogMTAwIH0sXG4gICAgICAgIHsgeDogNjAwLCB5OiAyMDAsIHc6IDEwMCwgaDogMTAwIH0sXG4gICAgXTtcblxuICAgIHJldHVybiBoYXphcmRzLnJlZHVjZSgoYWNjLCB7IHgsIHksIHcsIGggfSkgPT4ge1xuICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICdoYXphcmQnO1xuICAgICAgICBkaXYuc3R5bGUubGVmdCA9IGAke3h9cHhgO1xuICAgICAgICBkaXYuc3R5bGUudG9wID0gYCR7eX1weGA7XG4gICAgICAgIGRpdi5zdHlsZS5oZWlnaHQgPSBgJHtofXB4YDtcbiAgICAgICAgZGl2LnN0eWxlLndpZHRoID0gYCR7d31weGA7XG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChkaXYpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSB4OyBpIDw9ICh4ICsgdyk7IGkgKz0gZ3JpZFNpemUpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSB5OyBqIDw9ICh5ICsgaCk7IGogKz0gZ3JpZFNpemUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWNjW2ldID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgYWNjW2ldID0ge307XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGFjY1tpXVtqXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGRvdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RvdCcpO1xuICAgICAgICAgICAgICAgIGRvdC5jbGFzc05hbWUgPSAnaGF6YXJkLWRvdCc7XG4gICAgICAgICAgICAgICAgZG90LnN0eWxlLmxlZnQgPSBgJHtpIC0geH1weGA7XG4gICAgICAgICAgICAgICAgZG90LnN0eWxlLnRvcCA9IGAke2ogLSB5fXB4YDtcbiAgICAgICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoZG90KTtcblxuICAgICAgICAgICAgICAgIGFjY1tpXVtqXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBBbmltYXRpb24yYTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9hbmltYXRpb24yYS5qcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU5BO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFKQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=");
+eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 14);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _particle = __webpack_require__(/*! ./particle */ 33);\n\nvar _particle2 = _interopRequireDefault(_particle);\n\nvar _store = __webpack_require__(/*! ./store */ 22);\n\nvar _store2 = _interopRequireDefault(_store);\n\nvar _controls = __webpack_require__(/*! ./controls */ 21);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _enums = __webpack_require__(/*! ./enums */ 16);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction Animation2a() {\n this.options = {\n count: 1,\n maxCount: 10,\n randomize: true,\n showMovementCircle: true,\n showVisionGrid: true,\n speed: 4\n };\n\n this.container = document.getElementById('animation2a');\n this.bounds = this.container.getBoundingClientRect();\n\n this.particles = [];\n this.globalGrid = createGlobalGrid(this.container, this.bounds);\n\n var controls = new _controls2.default(document.getElementById('controls2a'), this.options);\n\n controls.mount().subscribe(this.subscriber.bind(this));\n\n this.updateAnimating(this.options.animating);\n this.updateCount(this.options.count);\n\n // TODO X dimension modified by core UI, maybe recalc grid in animation start?\n // TODO remove bottom padding from Disqus\n // TODO perf - cache trig or perform operations\n // TODO particle gridzie and vision rad into options\n\n // TODO ANIM2 particle evade\n // TODO ANIM2a Vision grid touches\n // TODO ANIM2a randomize hazards\n // TODO ANIM2b Scale vision grid to 1000? particles\n\n // TODO ANIM3 flocking\n};\n\nAnimation2a.prototype.subscriber = function (_ref) {\n var key = _ref.key,\n value = _ref.value;\n\n switch (key) {\n case _enums.CONTROLS.ANIMATING:\n this.updateAnimating(value);break;\n case _enums.CONTROLS.COUNT:\n this.updateCount(value);break;\n case _enums.CONTROLS.RANDOMIZE:\n this.updateRandomize(value);break;\n case _enums.CONTROLS.SPEED:\n this.updateSpeed(value);break;\n }\n};\n\nAnimation2a.prototype.nextFrame = function () {\n this.particles.forEach(function (p) {\n return p.nextFrame();\n });\n};\n\nAnimation2a.prototype.updateAnimating = function (isAnimating) {\n var _this = this;\n\n this.options.animating = isAnimating;\n\n if (isAnimating) {\n var fps$ = _rxjs2.default.Observable.interval(1000 / 32).takeWhile(function (_) {\n return _this.options.animating;\n });\n\n fps$.subscribe(this.nextFrame.bind(this));\n }\n};\n\nAnimation2a.prototype.updateCount = function (count) {\n while (this.particles.length >= count) {\n delete this.particles.pop().remove();\n }\n\n while (this.particles.length < count) {\n var p = new _particle2.default(this.container, this.bounds, this.options, this.globalGrid);\n this.particles.push(p);\n }\n};\n\nAnimation2a.prototype.updateRandomize = function (value) {\n this.options.randomize = value;\n this.particles.forEach(function (p) {\n return p.updateConfig({ randomize: value });\n });\n};\n\nAnimation2a.prototype.updateSpeed = function (value) {\n this.options.speed = value;\n this.particles.forEach(function (p) {\n return p.updateConfig({ speed: value });\n });\n};\n\nfunction createGlobalGrid(container, bounds) {\n var grid = {};\n var gridSize = 5;\n\n var hazards = [{ x: 100, y: 100, w: 200, h: 200 }, { x: 600, y: 200, w: 200, h: 200 }];\n\n return hazards.reduce(function (acc, _ref2) {\n var x = _ref2.x,\n y = _ref2.y,\n w = _ref2.w,\n h = _ref2.h;\n\n var div = document.createElement('div');\n div.className = 'hazard';\n div.style.left = x + 'px';\n div.style.top = y + 'px';\n div.style.height = h + 'px';\n div.style.width = w + 'px';\n container.appendChild(div);\n\n for (var i = x; i <= x + w; i += gridSize) {\n for (var j = y; j <= y + h; j += gridSize) {\n if (acc[i] === undefined) {\n acc[i] = {};\n }\n\n if (acc[i][j] !== undefined) {\n continue;\n }\n\n var dot = document.createElement('dot');\n dot.className = 'hazard-dot';\n dot.style.left = i - x + 'px';\n dot.style.top = j - y + 'px';\n div.appendChild(dot);\n\n acc[i][j] = true;\n }\n }\n\n return acc;\n }, {});\n}\n\nexports.default = Animation2a;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uMmEuanM/YzJmNyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IFBhcnRpY2xlIGZyb20gJy4vcGFydGljbGUnO1xuaW1wb3J0IFN0b3JlIGZyb20gJy4vc3RvcmUnO1xuaW1wb3J0IENvbnRyb2xzIGZyb20gJy4vY29udHJvbHMnO1xuaW1wb3J0IHsgQ09OVFJPTFMgfSBmcm9tICcuL2VudW1zJztcblxuZnVuY3Rpb24gQW5pbWF0aW9uMmEoKSB7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICBjb3VudDogMSxcbiAgICAgICAgbWF4Q291bnQ6IDEwLFxuICAgICAgICByYW5kb21pemU6IHRydWUsXG4gICAgICAgIHNob3dNb3ZlbWVudENpcmNsZTogdHJ1ZSxcbiAgICAgICAgc2hvd1Zpc2lvbkdyaWQ6IHRydWUsXG4gICAgICAgIHNwZWVkOiA0XG4gICAgfTtcblxuICAgIHRoaXMuY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FuaW1hdGlvbjJhJyk7XG4gICAgdGhpcy5ib3VuZHMgPSB0aGlzLmNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIHRoaXMucGFydGljbGVzID0gW107XG4gICAgdGhpcy5nbG9iYWxHcmlkID0gY3JlYXRlR2xvYmFsR3JpZCh0aGlzLmNvbnRhaW5lciwgdGhpcy5ib3VuZHMpO1xuXG4gICAgY29uc3QgY29udHJvbHMgPSBuZXcgQ29udHJvbHMoXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb250cm9sczJhJyksXG4gICAgICAgIHRoaXMub3B0aW9uc1xuICAgICk7XG5cbiAgICBjb250cm9scy5tb3VudCgpLnN1YnNjcmliZSh0aGlzLnN1YnNjcmliZXIuYmluZCh0aGlzKSk7XG5cbiAgICB0aGlzLnVwZGF0ZUFuaW1hdGluZyh0aGlzLm9wdGlvbnMuYW5pbWF0aW5nKTtcbiAgICB0aGlzLnVwZGF0ZUNvdW50KHRoaXMub3B0aW9ucy5jb3VudCk7XG5cbiAgICAvLyBUT0RPIFggZGltZW5zaW9uIG1vZGlmaWVkIGJ5IGNvcmUgVUksIG1heWJlIHJlY2FsYyBncmlkIGluIGFuaW1hdGlvbiBzdGFydD9cbiAgICAvLyBUT0RPIHJlbW92ZSBib3R0b20gcGFkZGluZyBmcm9tIERpc3F1c1xuICAgIC8vIFRPRE8gcGVyZiAtIGNhY2hlIHRyaWcgb3IgcGVyZm9ybSBvcGVyYXRpb25zXG4gICAgLy8gVE9ETyBwYXJ0aWNsZSBncmlkemllIGFuZCB2aXNpb24gcmFkIGludG8gb3B0aW9uc1xuXG4gICAgLy8gVE9ETyBBTklNMiBwYXJ0aWNsZSBldmFkZVxuICAgIC8vIFRPRE8gQU5JTTJhIFZpc2lvbiBncmlkIHRvdWNoZXNcbiAgICAvLyBUT0RPIEFOSU0yYSByYW5kb21pemUgaGF6YXJkc1xuICAgIC8vIFRPRE8gQU5JTTJiIFNjYWxlIHZpc2lvbiBncmlkIHRvIDEwMDA/IHBhcnRpY2xlc1xuXG4gICAgLy8gVE9ETyBBTklNMyBmbG9ja2luZ1xufTtcblxuQW5pbWF0aW9uMmEucHJvdG90eXBlLnN1YnNjcmliZXIgPSBmdW5jdGlvbih7IGtleSwgdmFsdWUgfSkge1xuICAgIHN3aXRjaChrZXkpIHtcbiAgICAgICAgY2FzZSBDT05UUk9MUy5BTklNQVRJTkc6IHRoaXMudXBkYXRlQW5pbWF0aW5nKHZhbHVlKTsgYnJlYWs7XG4gICAgICAgIGNhc2UgQ09OVFJPTFMuQ09VTlQ6IHRoaXMudXBkYXRlQ291bnQodmFsdWUpOyBicmVhaztcbiAgICAgICAgY2FzZSBDT05UUk9MUy5SQU5ET01JWkU6IHRoaXMudXBkYXRlUmFuZG9taXplKHZhbHVlKTsgYnJlYWs7XG4gICAgICAgIGNhc2UgQ09OVFJPTFMuU1BFRUQ6IHRoaXMudXBkYXRlU3BlZWQodmFsdWUpOyBicmVhaztcbiAgICB9XG59XG5cbkFuaW1hdGlvbjJhLnByb3RvdHlwZS5uZXh0RnJhbWUgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnBhcnRpY2xlcy5mb3JFYWNoKHAgPT4gcC5uZXh0RnJhbWUoKSk7XG59XG5cbkFuaW1hdGlvbjJhLnByb3RvdHlwZS51cGRhdGVBbmltYXRpbmcgPSBmdW5jdGlvbihpc0FuaW1hdGluZykge1xuICAgIHRoaXMub3B0aW9ucy5hbmltYXRpbmcgPSBpc0FuaW1hdGluZztcblxuICAgIGlmIChpc0FuaW1hdGluZykge1xuICAgICAgICBjb25zdCBmcHMkID0gUnguT2JzZXJ2YWJsZS5pbnRlcnZhbCgxMDAwIC8gMzIpXG4gICAgICAgICAgICAudGFrZVdoaWxlKF8gPT4gdGhpcy5vcHRpb25zLmFuaW1hdGluZyk7XG5cbiAgICAgICAgZnBzJC5zdWJzY3JpYmUodGhpcy5uZXh0RnJhbWUuYmluZCh0aGlzKSk7XG4gICAgfVxufVxuXG5BbmltYXRpb24yYS5wcm90b3R5cGUudXBkYXRlQ291bnQgPSBmdW5jdGlvbihjb3VudCkge1xuICAgIHdoaWxlICh0aGlzLnBhcnRpY2xlcy5sZW5ndGggPj0gY291bnQpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMucGFydGljbGVzLnBvcCgpLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIHdoaWxlICh0aGlzLnBhcnRpY2xlcy5sZW5ndGggPCBjb3VudCkge1xuICAgICAgICBjb25zdCBwID0gbmV3IFBhcnRpY2xlKHRoaXMuY29udGFpbmVyLCB0aGlzLmJvdW5kcywgdGhpcy5vcHRpb25zLCB0aGlzLmdsb2JhbEdyaWQpO1xuICAgICAgICB0aGlzLnBhcnRpY2xlcy5wdXNoKHApO1xuICAgIH1cbn1cblxuQW5pbWF0aW9uMmEucHJvdG90eXBlLnVwZGF0ZVJhbmRvbWl6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdGhpcy5vcHRpb25zLnJhbmRvbWl6ZSA9IHZhbHVlO1xuICAgIHRoaXMucGFydGljbGVzLmZvckVhY2gocCA9PiBwLnVwZGF0ZUNvbmZpZyh7IHJhbmRvbWl6ZTogdmFsdWUgfSkpO1xufVxuXG5BbmltYXRpb24yYS5wcm90b3R5cGUudXBkYXRlU3BlZWQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHRoaXMub3B0aW9ucy5zcGVlZCA9IHZhbHVlO1xuICAgIHRoaXMucGFydGljbGVzLmZvckVhY2gocCA9PiBwLnVwZGF0ZUNvbmZpZyh7IHNwZWVkOiB2YWx1ZSB9KSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUdsb2JhbEdyaWQoY29udGFpbmVyLCBib3VuZHMpIHtcbiAgICBjb25zdCBncmlkID0ge307XG4gICAgY29uc3QgZ3JpZFNpemUgPSA1O1xuXG4gICAgY29uc3QgaGF6YXJkcyA9IFtcbiAgICAgICAgeyB4OiAxMDAsIHk6IDEwMCwgdzogMjAwLCBoOiAyMDAgfSxcbiAgICAgICAgeyB4OiA2MDAsIHk6IDIwMCwgdzogMjAwLCBoOiAyMDAgfSxcbiAgICBdO1xuXG4gICAgcmV0dXJuIGhhemFyZHMucmVkdWNlKChhY2MsIHsgeCwgeSwgdywgaCB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXYuY2xhc3NOYW1lID0gJ2hhemFyZCc7XG4gICAgICAgIGRpdi5zdHlsZS5sZWZ0ID0gYCR7eH1weGA7XG4gICAgICAgIGRpdi5zdHlsZS50b3AgPSBgJHt5fXB4YDtcbiAgICAgICAgZGl2LnN0eWxlLmhlaWdodCA9IGAke2h9cHhgO1xuICAgICAgICBkaXYuc3R5bGUud2lkdGggPSBgJHt3fXB4YDtcbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGRpdik7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IHg7IGkgPD0gKHggKyB3KTsgaSArPSBncmlkU2l6ZSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IHk7IGogPD0gKHkgKyBoKTsgaiArPSBncmlkU2l6ZSkge1xuICAgICAgICAgICAgICAgIGlmIChhY2NbaV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBhY2NbaV0gPSB7fTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoYWNjW2ldW2pdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZG90ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZG90Jyk7XG4gICAgICAgICAgICAgICAgZG90LmNsYXNzTmFtZSA9ICdoYXphcmQtZG90JztcbiAgICAgICAgICAgICAgICBkb3Quc3R5bGUubGVmdCA9IGAke2kgLSB4fXB4YDtcbiAgICAgICAgICAgICAgICBkb3Quc3R5bGUudG9wID0gYCR7aiAtIHl9cHhgO1xuICAgICAgICAgICAgICAgIGRpdi5hcHBlbmRDaGlsZChkb3QpO1xuXG4gICAgICAgICAgICAgICAgYWNjW2ldW2pdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG5cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuaW1hdGlvbjJhO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGpzL2FuaW1hdGlvbjJhLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUpBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==");
/***/ }),
/* 76 */
@@ -1030,7 +1030,7 @@ eval("// removed by extract-text-webpack-plugin//# sourceMappingURL=data:applica
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 14);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _controls = __webpack_require__(/*! ./controls */ 21);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 73);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 74);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nvar _animation2a = __webpack_require__(/*! ./animation2a */ 75);\n\nvar _animation2a2 = _interopRequireDefault(_animation2a);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n__webpack_require__(/*! ../css/reset.scss */ 79);\n__webpack_require__(/*! ../css/index.scss */ 77);\n__webpack_require__(/*! ../css/particle.scss */ 78);\n__webpack_require__(/*! ../css/controls.scss */ 76);\n\nnew _animation1a2.default();\nnew _animation1b2.default();\nnew _animation2a2.default();//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IENvbnRyb2xzIGZyb20gJy4vY29udHJvbHMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuaW1wb3J0IEFuaW1hdGlvbjJhIGZyb20gJy4vYW5pbWF0aW9uMmEnO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG5uZXcgQW5pbWF0aW9uMWEoKTtcbm5ldyBBbmltYXRpb24xYigpO1xubmV3IEFuaW1hdGlvbjJhKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvaW5kZXguanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9");
+eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 14);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _controls = __webpack_require__(/*! ./controls */ 21);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 73);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 74);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nvar _animation2a = __webpack_require__(/*! ./animation2a */ 75);\n\nvar _animation2a2 = _interopRequireDefault(_animation2a);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n__webpack_require__(/*! ../css/reset.scss */ 79);\n__webpack_require__(/*! ../css/index.scss */ 77);\n__webpack_require__(/*! ../css/particle.scss */ 78);\n__webpack_require__(/*! ../css/controls.scss */ 76);\n\n// new Animation1a();\n// new Animation1b();\nnew _animation2a2.default();//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IENvbnRyb2xzIGZyb20gJy4vY29udHJvbHMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuaW1wb3J0IEFuaW1hdGlvbjJhIGZyb20gJy4vYW5pbWF0aW9uMmEnO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG4vLyBuZXcgQW5pbWF0aW9uMWEoKTtcbi8vIG5ldyBBbmltYXRpb24xYigpO1xubmV3IEFuaW1hdGlvbjJhKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvaW5kZXguanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9");
/***/ }),
/* 81 */
diff --git a/js/index.js b/js/index.js
index 9948777..75d373b 100644
--- a/js/index.js
+++ b/js/index.js
@@ -9,6 +9,6 @@ require('../css/index.scss');
require('../css/particle.scss');
require('../css/controls.scss');
-new Animation1a();
-new Animation1b();
+// new Animation1a();
+// new Animation1b();
new Animation2a();
diff --git a/js/particle.js b/js/particle.js
index ac9aba5..a663dbc 100644
--- a/js/particle.js
+++ b/js/particle.js
@@ -4,182 +4,268 @@ import Store from './store';
const random = {
bool: (weight) => Math.random() < (weight || 0.5),
+ color: () => `rgb(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)})`,
num: (min, max) => min + Math.round(Math.random() * max),
- color: () => `rgb(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)})`
}
-/* ===== Constructor ===== */
+// ===== Constructor =====
-function Particle(parent, bounds, options) {
- this.options = Object.assign({
+function Particle(parent, bounds, config, globalGrid) {
+ this.config = Object.assign({
+ bounds,
+ color: random.color(),
+ gridSize: 5,
randomize: false,
showMovementCircle: false,
showVisionGrid: false,
- speed: 4
- }, options);
+ speed: 4,
+ visionRadius: 50
+ }, config);
- this.arc = {
- r: random.num(100, 200),
- t: random.num(RAD.t90, RAD.t360),
- x: random.num(0, bounds.width),
- y: random.num(0, bounds.height)
- }
+ this.grids = {
+ global: globalGrid,
+ vision: calculateVisionGrid(this.config)
+ };
- this.particle = {
+ this.arc = {
+ centerX: random.num(0, bounds.width),
+ centerY: random.num(0, bounds.height),
clockwise: random.bool(),
- color: random.color(),
- x: 0,
- y: 0
- }
-
- this.visionGridPoints = [];
- this.interval = random.num(RAD.t90, RAD.t360);
-
- this.bounds = bounds;
- this.parent = parent;
-
- this.container = document.createElement('div');
- this.container.className = 'particle-container';
-
- this.body = document.createElement('div');
- this.body.className = 'particle-body';
- this.body.style.backgroundColor = this.particle.color;
-
- this.container.appendChild(this.body);
- this.parent.appendChild(this.container);
-
- this.updateOptions(this.options);
+ endX: 0,
+ endY: 0,
+ length: random.num(RAD.t90, RAD.t360),
+ radius: random.num(100, 200),
+ theta: random.num(RAD.t90, RAD.t360),
+ };
+
+ this.nodes = {
+ body: createBodyNode(this.config),
+ circle: undefined,
+ container: createContainerNode(this.config),
+ parent,
+ vision: undefined,
+ visionGrid: undefined,
+ };
+
+ this.nodes.container.appendChild(this.nodes.body);
+ parent.appendChild(this.nodes.container);
+
+ this.updateConfig(this.config);
this.nextFrame();
};
+// ===== PROTOTYPE =====
+
Particle.prototype.remove = function() {
- this.parent.removeChild(this.container);
+ this.nodes.parent.removeChild(this.nodes.container);
return this;
}
Particle.prototype.nextFrame = function() {
- this.move();
- repaintContainer(this.container, this.particle);
- repaintBody(this.arc, this.body, this.particle);
- repaintCircle(this.arc, this.circle, this.particle);
- repaintVision(this.arc, this.vision, this.particle);
-}
+ // this.visionGrid = updateVisionGrid(this.visionGrid, this.globalGrid, this.particle);
+ this.arc = updateArc(this.arc, this.config);
-Particle.prototype.updateBounds = function(bounds) {
- this.bounds = bounds;
+ repaintContainer(this.nodes.container, this.arc);
+ repaintBody(this.nodes.body, this.arc);
+ repaintCircle(this.nodes.circle, this.arc);
+ // repaintVision(this.arc, this.nodes.vision, this.visionGrid, this.visionGridDivs);
}
-Particle.prototype.updateOptions = function(options) {
- Object.assign(this.options, options);
+Particle.prototype.updateConfig = function(config) {
+ Object.assign(this.config, config);
+
+ const { showMovementCircle, showVisionGrid } = this.config;
+
+ if (showMovementCircle === true && this.nodes.circle === undefined) {
+ this.nodes.circle = createCircleNode(config);
+ this.nodes.container.appendChild(this.nodes.circle);
+ }
+
+ if (showMovementCircle === false && this.nodes.circle !== undefined) {
+ this.nodes.container.removeChild(this.nodes.circle);
+ delete this.nodes.circle;
+ }
+
+ if (showVisionGrid === true && this.nodes.vision === undefined) {
+ this.nodes.vision = createVisionNode(config, this.grids);
+ // visionNode.appendChild(div);
+ this.nodes.container.appendChild(this.nodes.vision);
+ }
- if (options.showMovementCircle === true && this.circle === undefined) {
- this.circle = document.createElement('div');
- this.circle.className = 'particle-movement-circle';
- this.circle.style.borderColor = this.particle.color;
- this.container.appendChild(this.circle);
+ if (showMovementCircle === false && this.nodes.circle !== undefined) {
+ this.nodes.container.removeChild(this.nodes.vision);
+ delete this.nodes.vision;
}
- if (options.showMovementCircle === false && this.circle !== undefined) {
- this.container.removeChild(this.circle);
- delete this.circle;
+ // if (config.showVisionGrid === false && this.nodes.vision !== undefined) {
+ // // this.nodes.container.removeChild(this.vision);
+ // // delete this.vision;
+ //
+ // // this.visionGrid.forEach(point => {
+ // // this.vision.removeChild(point.div);
+ // // });
+ // // this.visionGrid = [];
+ // }
+}
+
+// ===== DOM CREATION =====
+
+function createBodyNode(config) {
+ const node = document.createElement('div');
+ node.className = 'particle-body';
+ node.style.backgroundColor = config.color;
+ return node;
+}
+
+function createCircleNode(config) {
+ if (config.showMovementCircle === false) {
+ return undefined;
}
- if (options.showVisionGrid === true && this.vision === undefined) {
- this.vision = document.createElement('div');
- this.vision.className = 'particle-vision';
- this.container.appendChild(this.vision);
+ const node = document.createElement('div');
+ node.className = 'particle-movement-circle';
+ node.style.borderColor = config.color;
+ return node;
+}
- this.visionGridPoints = calculateVisionGridPoints(this.particle);
+function createContainerNode(config) {
+ const node = document.createElement('div');
+ node.className = 'particle-container';
+ return node;
+}
- this.visionGridPoints.forEach(point => {
- this.vision.appendChild(point.div);
- });
+function createVisionNode(config) {
+ if (config.showVisionGrid === false) {
+ return undefined;
}
- if (options.showVisionGrid === false && this.vision !== undefined) {
- // this.container.removeChild(this.vision);
- // delete this.vision;
- //
- // this.visionGridPoints.forEach(point => {
- // this.vision.removeChild(point.div);
- // });
- // this.visionGridPoints = [];
+ const node = document.createElement('div');
+ node.className = 'particle-vision';
+
+ return node;
+}
+
+function createVisionGridNodes(config, grids) {
+ if (config.showVisionGrid === false) {
+ return undefined;
}
+
+ return grids.visionGrid.forEach((acc, { x, y }) => {
+ const div = document.createElement('div');
+ div.className = 'particle-vision-dot';
+ // div.style.backgroundColor = config.color;
+ div.style.left = `${x + config.visionRadius}px`;
+ div.style.top = `${y + config.visionRadius}px`;
+
+ if (acc[x] === undefined) {
+ acc[x] = {};
+ }
+
+ acc[x][y] = div;
+
+ return acc;
+ }, {});
}
-Particle.prototype.move = function() {
+// ===== CALCULATIONS =====
+
+function updateArc(arc, { bounds, randomize, speed }) {
// Randomly change radius and rotation direction.
- if (this.interval <= 0) {
- this.interval = random.num(RAD.t90, RAD.t360);
+ if (arc.length <= 0) {
+ arc.length = random.num(RAD.t90, RAD.t360);
- if (this.options.randomize === true) {
- this.arc = moveArc(this.arc, random.num(100, 200));
+ if (randomize === true) {
+ arc = moveArc(arc, random.num(100, 200));
if (random.bool(0.8)) {
- this.particle.clockwise = !this.particle.clockwise;
- this.arc = changeDirection(this.arc);
+ arc.clockwise = !arc.clockwise;
+ arc = changeDirection(arc);
}
}
}
// Ensure constant velocity and theta between 0 and 2π.
- const delta = this.options.speed / this.arc.r;
- this.interval -= delta;
-
- 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
+ const delta = speed / arc.radius;
+ arc.length -= delta;
+
+ arc.theta += (arc.clockwise ? -delta : +delta);
+ arc.theta = (arc.theta > 0 ? arc.theta % RAD.t360 : RAD.t360 + arc.theta);
+
+ arc.endX = arc.centerX + arc.radius * Math.cos(arc.theta);
+ arc.endY = arc.centerY - arc.radius * Math.sin(arc.theta);
+
+ // // Overflow.
+ if (arc.endX < 0) {
+ arc.endX += bounds.width;
+ arc.centerX += bounds.width
+ } else if (arc.endX > bounds.width) {
+ arc.endX -= bounds.width;
+ arc.centerX -= 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
+ if (arc.endY < 0) {
+ arc.endY += bounds.height;
+ arc.centerY += bounds.height
+ } else if (arc.endY > bounds.height) {
+ arc.endY -= bounds.height;
+ arc.centerY -= bounds.height
}
+
+ return arc;
}
+// function updateVisionGrid(visionGrid, globalGrid, particle) {
+// return visionGrid.reduce((acc, point) => {
+// // Location of point on grid
+// const x = Math.round(particle.x + point.x);
+// const y = Math.round(particle.y + point.y);
+//
+// const gridX = x - x % 5;
+// const gridY = y - y % 5;
+//
+// // console.warn(gridX, particle.x, point.x);
+// point.touch = (globalGrid[gridX] !== undefined && globalGrid[gridX][gridY] !== undefined);
+//
+// if (point.touch) {
+// console.warn('yay');
+// }
+//
+// return acc.concat(point);
+// }, []);
+// }
+//
function moveArc(arc, newRadius) {
- const r0 = arc.r;
+ const r0 = arc.radius;
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;
+ arc.centerX -= (r1 - r0) * Math.cos(arc.theta);
+ arc.centerY += (r1 - r0) * Math.sin(arc.theta);
+ arc.radius = r1;
return arc;
}
function changeDirection(arc) {
- arc.t = (arc.t + RAD.t180) % RAD.t360;
- arc.x -= (2 * arc.r) * Math.cos(arc.t);
- arc.y += (2 * arc.r) * Math.sin(arc.t);
+ arc.theta = (arc.theta + RAD.t180) % RAD.t360;
+ arc.centerX -= (2 * arc.radius) * Math.cos(arc.theta);
+ arc.centerY += (2 * arc.radius) * Math.sin(arc.theta);
return arc;
}
-function calculateVisionGridPoints(particle) {
- const gridSize = 5;
- const visionRadius = 50;
+function calculateVisionGrid(config) {
+ if (config.showVisionGrid === false) {
+ return null;
+ }
- const r0 = Math.pow(visionRadius, 2);
- const r1 = Math.pow(visionRadius - gridSize, 2);
+ const { gridSize: side, visionRadius: radius } = config;
+ const r0 = Math.pow(radius, 2);
+ const r1 = Math.pow(radius - side, 2);
const points = [];
- for (let x = -visionRadius; x <= visionRadius; x += gridSize) {
- for (let y = -visionRadius; y <= visionRadius; y += gridSize) {
+ for (let x = -radius; x <= radius; x += side) {
+ for (let y = -radius; y <= radius; y += side) {
// Half of triangle
if (x > -y) {
continue;
@@ -191,56 +277,58 @@ function calculateVisionGridPoints(particle) {
continue;
}
- const div = document.createElement('div');
- div.className = 'particle-vision-dot';
- div.style.backgroundColor = particle.color;
- div.style.left = `${x + visionRadius}px`;
- div.style.top = `${y + visionRadius}px`;
-
- points.push({ x, y, div });
+ points.push({ x, y, touch: false });
}
}
return points;
}
-function repaintContainer(containerNode, particle) {
- containerNode.style.left = `${particle.x}px`;
- containerNode.style.top = `${particle.y}px`;
-}
-
-function repaintBody(arc, bodyNode, particle) {
- const rad = particle.clockwise
- ? RAD.t180 - arc.t
- : RAD.t360 - arc.t;
-
- bodyNode.style.transform = `rotate(${rad + RAD.t45}rad)`;
+// ===== RENDERING =====
+function repaintContainer(node, arc) {
+ node.style.left = `${arc.endX}px`;
+ node.style.top = `${arc.endY}px`;
}
-function repaintVision(arc, visionNode, particle) {
- if (visionNode === undefined) {
- return;
- }
-
- const rad = particle.clockwise
- ? RAD.t180 - arc.t
- : RAD.t360 - arc.t;
+function repaintBody(node, arc) {
+ const rad = arc.clockwise
+ ? RAD.t180 - arc.theta
+ : RAD.t360 - arc.theta;
- visionNode.style.transform = `rotate(${rad + RAD.t45}rad)`;
+ node.style.transform = `rotate(${rad + RAD.t45}rad)`;
}
-function repaintCircle(arc, circleNode) {
- if (circleNode === undefined) {
+function repaintCircle(node, arc) {
+ if (node === undefined) {
return;
}
- circleNode.style.width = `${2 * arc.r}px`;
- circleNode.style.height = `${2 * arc.r}px`;
+ node.style.width = `${2 * arc.radius}px`;
+ node.style.height = `${2 * arc.radius}px`;
- circleNode.style.left = `-${arc.r + arc.r * Math.cos(arc.t)}px`;
- circleNode.style.top = `-${arc.r - arc.r * Math.sin(arc.t)}px`;
+ node.style.left = `-${arc.radius + arc.radius * Math.cos(arc.theta)}px`;
+ node.style.top = `-${arc.radius - arc.radius * Math.sin(arc.theta)}px`;
- circleNode.style.borderRadius = `${arc.r}px`;
+ node.style.borderRadius = `${arc.radius}px`;
}
+// function repaintVision(arc, visionNode, visionGrid, visionGridDivs) {
+// if (visionNode === undefined) {
+// return;
+// }
+//
+// const rad = arc.clockwise
+// ? RAD.t180 - arc.theta
+// : RAD.t360 - arc.theta;
+//
+// // visionNode.style.transform = `rotate(${rad + RAD.t45}rad)`;
+//
+// visionGrid.forEach(({ x, y, touch }) => {
+// if (touch === true) {
+// console.warn(x, y)
+// visionGridDivs[x][y].style.background = 'black';
+// }
+// });
+// }
+
export default Particle;