Vision grid finalized.

master
Ben Burlingham 8 years ago
parent 7b13230220
commit b38624af70
  1. 39
      css/animation3.scss
  2. 29
      css/style.css
  3. 172
      js/animation3.js
  4. 193
      js/bundle.js

@ -14,14 +14,17 @@
z-index: 1;
&::after {
border: 50px solid transparent;
border-right-color: lightgreen;
border: 50px solid;
border-color: lightgreen transparent transparent turquoise;
border-radius: 50px;
content: ' ';
height: 0;
left: -30px;
left: -50px;
margin: #{$side / 2} 0 0 #{$side / 2};
opacity: 0.5;
position: absolute;
top: -40px;
transform: rotate(45deg);
top: -50px;
width: 0;
}
}
@ -29,7 +32,7 @@
.anim3-movement-circle {
border: 2px dotted darkturquoise;
position: absolute;
transition: all 0.2s;
transition: left 0.2s, top 0.2s, height 0.2s, width 0.2s;
z-index: 0;
&:after {
@ -45,3 +48,29 @@
width: 4px;
}
}
.anim3-vision-grid {
height: 100px;
// margin-top: 50px;
// margin-left: 50px;
position: absolute;
transform-origin: left top;
width: 100px;
z-index: 99;
}
.anim3-dot {
$s: 2px;
background: red;
// border-radius: 2px;
height: $s;
position: absolute;
width: $s;
z-index: 99;
&.removed {
// background: purple;
background: yellow;
}
}

@ -58,20 +58,23 @@ body {
width: 20px;
z-index: 1; }
.anim3-particle::after {
border: 50px solid transparent;
border-right-color: lightgreen;
border: 50px solid;
border-color: lightgreen transparent transparent turquoise;
border-radius: 50px;
content: ' ';
height: 0;
left: -30px;
left: -50px;
margin: 10px 0 0 10px;
opacity: 0.5;
position: absolute;
top: -40px;
transform: rotate(45deg);
top: -50px;
width: 0; }
.anim3-movement-circle {
border: 2px dotted darkturquoise;
position: absolute;
transition: all 0.2s;
transition: left 0.2s, top 0.2s, height 0.2s, width 0.2s;
z-index: 0; }
.anim3-movement-circle:after {
background: darkturquoise;
@ -84,6 +87,22 @@ body {
position: absolute;
top: 50%;
width: 4px; }
.anim3-vision-grid {
height: 100px;
position: absolute;
transform-origin: left top;
width: 100px;
z-index: 99; }
.anim3-dot {
background: red;
height: 2px;
position: absolute;
width: 2px;
z-index: 99; }
.anim3-dot.removed {
background: yellow; }
.anim3-particle {
background: url(../res/seahorse.svg) no-repeat center top #aaa;
background-size: 20px 20px;

@ -12,33 +12,41 @@ import AnimationBase from './animation0';
import DOM from './dom';
import Store from './store';
const speed = 2;
const visionRadius = 50;
const speed = 6;
const grid = {};
const t45 = Math.PI / 4;
const t90 = Math.PI / 2;
const t270 = 3 * Math.PI / 2;
const t360 = Math.PI * 2;
const movementCircle = document.createElement('div');
movementCircle.className = 'anim3-movement-circle';
const visionCircle = document.createElement('div');
// visionCircle.className = 'anim3-vision-circle';
const visionGrid = document.createElement('div');
visionGrid.className = 'anim3-vision-grid';
const particle = document.createElement('div');
particle.className = 'anim3-particle';
const visionGridPoints = calculateVisionGridPoints();
function move(store) {
let {
clockwise,
interval,
particleX,
particleY,
circleX,
circleY,
radius,
theta
} = store.get();
if (interval <= 0) {
interval = Math.round(Math.random() * 10) + 50;
radius = Math.round(Math.random() * 200) + 50
const particleX = circleX + radius * Math.cos(theta);
const particleY = circleY - radius * Math.sin(theta);
interval = Math.round(Math.random() * 10) + 50;
radius = Math.round(Math.random() * 200) + 50;
// IF SEEING A WALL: tight 180
// if ( < visionRadius
@ -48,76 +56,163 @@ function move(store) {
// state.interval = Math.PI * 20 / speed;
// }
detectWall(store);
if (Math.random() < 0.5) {
clockwise = !clockwise;
theta = (theta > Math.PI ? theta - Math.PI : theta + Math.PI);
radius *= -1;
}
circleX = particleX - radius * Math.cos(theta);
circleY = particleY + radius * Math.sin(theta);
}
interval -= 1;
// interval -= 1;
const prevTheta = theta;
// TODO store delta
const delta = speed / radius;
theta += (clockwise ? -delta : delta);
particleX -= radius * Math.cos(theta) - radius * Math.cos(prevTheta);
particleY -= radius * Math.sin(theta) - radius * Math.sin(prevTheta);
theta += (clockwise ? -delta : +delta);
theta %= t360;
store.set({
clockwise,
interval,
particleX,
particleY,
circleX,
circleY,
radius,
theta
});
// detectWall(store);
}
function detectWall(store) {
const { particleX, particleY, radius, theta } = store.get();
// const { circleX, circleY, radius, theta } = store.get();
// const len = visionGridPoints.length;
//
// for (let i = 0; i < len; i++) {
// const { x, y } = visionGridPoints[i];
// if (grid[x] && grid[x][y] && grid[x][y].type === 'wall') {
// console.warn("Wall detected", x, y);
// return true;
// }
// }
//
// return false;
}
function paintMovementCircle(store) {
function transformMovementCircle(store) {
// TODO UPDATE ONLY IF THETA CHANGED - MUST HAVE PREVSTATE
const { particleX, particleY, radius, theta } = store.get();
const { circleX, circleY, radius, theta } = store.get();
movementCircle.style.left = `${particleX - radius - radius * Math.cos(theta)}px`;
movementCircle.style.top = `${particleY - radius + radius * Math.sin(theta)}px`;
movementCircle.style.left = `${circleX - radius}px`;
movementCircle.style.top = `${circleY - radius}px`;
movementCircle.style.height = `${2 * radius}px`;
movementCircle.style.width = `${2 * radius}px`;
movementCircle.style.borderRadius = `${radius}px`;
}
function paintParticle(store) {
const { clockwise, particleX, particleY, theta } = store.get();
const rad = (clockwise ? theta + Math.PI / 2 : theta - Math.PI / 2);
function transformParticle(store) {
const { clockwise, circleX, circleY, radius, theta } = store.get();
const rad = clockwise ? Math.PI - theta : t360 - theta;
particle.style.left = `${particleX}px`;
particle.style.top = `${particleY}px`;
particle.style.left = `${circleX + radius * Math.cos(theta)}px`;
particle.style.top = `${circleY - radius * Math.sin(theta)}px`;
particle.style.transform = `rotate(${rad}rad)`;
}
function transformVisionGrid(store) {
const { clockwise, circleX, circleY, radius, theta } = store.get();
const particleX = circleX + radius * Math.cos(theta);
const particleY = circleY - radius * Math.sin(theta);
const r0 = Math.min(theta, theta - Math.PI);
const r1 = Math.max(theta, theta + Math.PI);
visionGridPoints.forEach(({ x, y, alpha, div }) => {
if (alpha >= 0 && alpha <= r0) {
div.style.display = (clockwise ? 'none' : 'block');
} else if (alpha >= theta && alpha <= r1) {
div.style.display = (clockwise ? 'none' : 'block');
} else {
div.style.display = (clockwise ? 'block' : 'none');
}
div.style.left = `${x + particleX}px`;
div.style.top = `${-y + particleY}px`;
});
}
function calculateVisionGridPoints() {
const visionRadius = 50;
const gridSize = 5;
const squareGrid = [];
for (let x = -visionRadius; x <= visionRadius; x += gridSize) {
for (let y = -visionRadius; y <= visionRadius; y += gridSize) {
let alpha = Math.atan(y / x);
if (x === 0 && y === 0) {
alpha = 0;
} else if (x === 0 && y < 0) {
alpha = t270;
} else if (y === 0 && x < 0) {
alpha = Math.PI;
} else if (x === 0 && y > 0) {
alpha = t90;
} else if (x < 0 && y < 0) {
alpha = alpha + Math.PI;
} else if (x <= 0) {
alpha = Math.PI + alpha;
} else if (y < 0) {
alpha = 2 * Math.PI + alpha;
}
squareGrid.push({ x, y, alpha });
}
}
const visionRadiusSquared = Math.pow(visionRadius, 2);
return squareGrid.reduce((acc, point) => {
if ((Math.pow(point.x, 2) + Math.pow(point.y, 2)) > visionRadiusSquared) {
return acc;
}
const div = document.createElement('div');
div.className = 'anim3-dot';
acc.push(Object.assign(point, { div }));
return acc;
}, []);
}
function reset() {
while (DOM.container.childNodes.length) {
DOM.container.removeChild(DOM.container.firstChild);
}
const store = new Store({
clockwise: false,
clockwise: true,
interval: 10,
particleX: 300,
particleY: 150,
circleX: 300,
circleY: 300,
radius: 150,
theta: Math.PI / 2
theta: 0
});
move(store);
transformParticle(store);
transformMovementCircle(store);
transformVisionGrid(store);
DOM.container.appendChild(particle);
DOM.container.appendChild(movementCircle);
visionGridPoints.forEach(point => {
DOM.container.appendChild(point.div);
});
return store;
};
@ -135,14 +230,12 @@ function init() {
}
}
const a = Math.round(Math.random() * 180) + 20;
const b = Math.round(Math.random() * 180) + 20;
const stop$ = Rx.Observable.fromEvent(DOM.container, 'stop');
const fps$ = Rx.Observable.interval(1000 / 32)
.map(_ => store)
// .take(100)
.takeUntil(stop$); console.error("CLICK TO STOP");
.take(300)
// .take(0)
// .takeUntil(stop$); console.error("CLICK TO STOP");
const click$ = Rx.Observable.fromEvent(DOM.container, 'click');
click$.subscribe(() => {
@ -150,8 +243,9 @@ function init() {
});
fps$.subscribe(move);
fps$.subscribe(paintParticle);
// fps$.subscribe(paintMovementCircle);
fps$.subscribe(transformParticle);
fps$.subscribe(transformMovementCircle);
fps$.subscribe(transformVisionGrid);
};
const Animation3 = Object.assign({}, AnimationBase, { init, reset });

@ -6379,29 +6379,37 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
// number of frames have emitted. A smoothstep cubic curve was considered, but maintaining consistent entry and exit angles will affect
// performance for large particle counts.
var speed = 2;
var visionRadius = 50;
var speed = 6;
var grid = {};
var t45 = Math.PI / 4;
var t90 = Math.PI / 2;
var t270 = 3 * Math.PI / 2;
var t360 = Math.PI * 2;
var movementCircle = document.createElement('div');
movementCircle.className = 'anim3-movement-circle';
var visionCircle = document.createElement('div');
// visionCircle.className = 'anim3-vision-circle';
var visionGrid = document.createElement('div');
visionGrid.className = 'anim3-vision-grid';
var particle = document.createElement('div');
particle.className = 'anim3-particle';
var visionGridPoints = calculateVisionGridPoints();
function move(store) {
var _store$get = store.get(),
clockwise = _store$get.clockwise,
interval = _store$get.interval,
particleX = _store$get.particleX,
particleY = _store$get.particleY,
circleX = _store$get.circleX,
circleY = _store$get.circleY,
radius = _store$get.radius,
theta = _store$get.theta;
if (interval <= 0) {
var particleX = circleX + radius * Math.cos(theta);
var particleY = circleY - radius * Math.sin(theta);
interval = Math.round(Math.random() * 10) + 50;
radius = Math.round(Math.random() * 200) + 50;
@ -6413,68 +6421,155 @@ function move(store) {
// state.interval = Math.PI * 20 / speed;
// }
detectWall(store);
if (Math.random() < 0.5) {
clockwise = !clockwise;
theta = theta > Math.PI ? theta - Math.PI : theta + Math.PI;
radius *= -1;
}
circleX = particleX - radius * Math.cos(theta);
circleY = particleY + radius * Math.sin(theta);
}
interval -= 1;
// interval -= 1;
var prevTheta = theta;
// TODO store delta
var delta = speed / radius;
theta += clockwise ? -delta : delta;
particleX -= radius * Math.cos(theta) - radius * Math.cos(prevTheta);
particleY -= radius * Math.sin(theta) - radius * Math.sin(prevTheta);
theta += clockwise ? -delta : +delta;
theta %= t360;
store.set({
clockwise: clockwise,
interval: interval,
particleX: particleX,
particleY: particleY,
circleX: circleX,
circleY: circleY,
radius: radius,
theta: theta
});
// detectWall(store);
}
function detectWall(store) {
// const { circleX, circleY, radius, theta } = store.get();
// const len = visionGridPoints.length;
//
// for (let i = 0; i < len; i++) {
// const { x, y } = visionGridPoints[i];
// if (grid[x] && grid[x][y] && grid[x][y].type === 'wall') {
// console.warn("Wall detected", x, y);
// return true;
// }
// }
//
// return false;
}
function transformMovementCircle(store) {
// TODO UPDATE ONLY IF THETA CHANGED - MUST HAVE PREVSTATE
var _store$get2 = store.get(),
particleX = _store$get2.particleX,
particleY = _store$get2.particleY,
circleX = _store$get2.circleX,
circleY = _store$get2.circleY,
radius = _store$get2.radius,
theta = _store$get2.theta;
movementCircle.style.left = circleX - radius + 'px';
movementCircle.style.top = circleY - radius + 'px';
movementCircle.style.height = 2 * radius + 'px';
movementCircle.style.width = 2 * radius + 'px';
movementCircle.style.borderRadius = radius + 'px';
}
function paintMovementCircle(store) {
// TODO UPDATE ONLY IF THETA CHANGED - MUST HAVE PREVSTATE
function transformParticle(store) {
var _store$get3 = store.get(),
particleX = _store$get3.particleX,
particleY = _store$get3.particleY,
clockwise = _store$get3.clockwise,
circleX = _store$get3.circleX,
circleY = _store$get3.circleY,
radius = _store$get3.radius,
theta = _store$get3.theta;
movementCircle.style.left = particleX - radius - radius * Math.cos(theta) + 'px';
movementCircle.style.top = particleY - radius + radius * Math.sin(theta) + 'px';
movementCircle.style.height = 2 * radius + 'px';
movementCircle.style.width = 2 * radius + 'px';
movementCircle.style.borderRadius = radius + 'px';
var rad = clockwise ? Math.PI - theta : t360 - theta;
particle.style.left = circleX + radius * Math.cos(theta) + 'px';
particle.style.top = circleY - radius * Math.sin(theta) + 'px';
particle.style.transform = 'rotate(' + rad + 'rad)';
}
function paintParticle(store) {
function transformVisionGrid(store) {
var _store$get4 = store.get(),
clockwise = _store$get4.clockwise,
particleX = _store$get4.particleX,
particleY = _store$get4.particleY,
circleX = _store$get4.circleX,
circleY = _store$get4.circleY,
radius = _store$get4.radius,
theta = _store$get4.theta;
var rad = clockwise ? theta + Math.PI / 2 : theta - Math.PI / 2;
var particleX = circleX + radius * Math.cos(theta);
var particleY = circleY - radius * Math.sin(theta);
particle.style.left = particleX + 'px';
particle.style.top = particleY + 'px';
particle.style.transform = 'rotate(' + rad + 'rad)';
var r0 = Math.min(theta, theta - Math.PI);
var r1 = Math.max(theta, theta + Math.PI);
visionGridPoints.forEach(function (_ref) {
var x = _ref.x,
y = _ref.y,
alpha = _ref.alpha,
div = _ref.div;
if (alpha >= 0 && alpha <= r0) {
div.style.display = clockwise ? 'none' : 'block';
} else if (alpha >= theta && alpha <= r1) {
div.style.display = clockwise ? 'none' : 'block';
} else {
div.style.display = clockwise ? 'block' : 'none';
}
div.style.left = x + particleX + 'px';
div.style.top = -y + particleY + 'px';
});
}
function calculateVisionGridPoints() {
var visionRadius = 50;
var gridSize = 5;
var squareGrid = [];
for (var x = -visionRadius; x <= visionRadius; x += gridSize) {
for (var y = -visionRadius; y <= visionRadius; y += gridSize) {
var alpha = Math.atan(y / x);
if (x === 0 && y === 0) {
alpha = 0;
} else if (x === 0 && y < 0) {
alpha = t270;
} else if (y === 0 && x < 0) {
alpha = Math.PI;
} else if (x === 0 && y > 0) {
alpha = t90;
} else if (x < 0 && y < 0) {
alpha = alpha + Math.PI;
} else if (x <= 0) {
alpha = Math.PI + alpha;
} else if (y < 0) {
alpha = 2 * Math.PI + alpha;
}
squareGrid.push({ x: x, y: y, alpha: alpha });
}
}
var visionRadiusSquared = Math.pow(visionRadius, 2);
return squareGrid.reduce(function (acc, point) {
if (Math.pow(point.x, 2) + Math.pow(point.y, 2) > visionRadiusSquared) {
return acc;
}
var div = document.createElement('div');
div.className = 'anim3-dot';
acc.push(Object.assign(point, { div: div }));
return acc;
}, []);
}
function reset() {
@ -6483,19 +6578,27 @@ function reset() {
}
var store = new _store2.default({
clockwise: false,
clockwise: true,
interval: 10,
particleX: 300,
particleY: 150,
circleX: 300,
circleY: 300,
radius: 150,
theta: Math.PI / 2
theta: 0
});
move(store);
transformParticle(store);
transformMovementCircle(store);
transformVisionGrid(store);
_dom2.default.container.appendChild(particle);
_dom2.default.container.appendChild(movementCircle);
visionGridPoints.forEach(function (point) {
_dom2.default.container.appendChild(point.div);
});
return store;
};
@ -6513,15 +6616,12 @@ function init() {
}
}
var a = Math.round(Math.random() * 180) + 20;
var b = Math.round(Math.random() * 180) + 20;
var stop$ = _rxjs2.default.Observable.fromEvent(_dom2.default.container, 'stop');
var fps$ = _rxjs2.default.Observable.interval(1000 / 32).map(function (_) {
return store;
})
// .take(100)
.takeUntil(stop$);console.error("CLICK TO STOP");
}).take(300);
// .take(0)
// .takeUntil(stop$); console.error("CLICK TO STOP");
var click$ = _rxjs2.default.Observable.fromEvent(_dom2.default.container, 'click');
click$.subscribe(function () {
@ -6529,8 +6629,9 @@ function init() {
});
fps$.subscribe(move);
fps$.subscribe(paintParticle);
// fps$.subscribe(paintMovementCircle);
fps$.subscribe(transformParticle);
fps$.subscribe(transformMovementCircle);
fps$.subscribe(transformVisionGrid);
};
var Animation3 = Object.assign({}, _animation2.default, { init: init, reset: reset });

Loading…
Cancel
Save