-
setVisibility(v => !v)}
- >≡
-
- {fields.map((obj, i) =>
- {obj.label || obj.key} {obj.value}
- update(obj.key, Number(e.target.value))}
- />
- )}
+ return (
+
+
setVisibility((v) => !v)}
+ >
+ ≡
+
+
+ {fields.map((obj, i) => (
+
+
+ {obj.label || obj.key} {obj.value}
+
+ update(obj.key, Number(e.target.value))}
+ />
+
+ ))}
+
+
-
-
;
+ );
};
export default Dock;
diff --git a/src/components/Dot.css b/src/components/Dot.css
index f5530d2..06e9166 100644
--- a/src/components/Dot.css
+++ b/src/components/Dot.css
@@ -1,19 +1,20 @@
@keyframes emerge {
- from { transform: scale(0); }
- to { transform: scale(1); }
+ from {
+ transform: scale(0);
+ }
+ to {
+ transform: scale(1);
+ }
}
@keyframes highlight {
from {
- box-shadow:
- 0 0 80px var(--fg),
- 0 0 60px var(--fg),
- 0 0 60px var(--fg),
- 0 0 40px var(--fg),
- 0 0 40px var(--fg),
- 0 0 20px var(--fg),
+ box-shadow: 0 0 80px var(--fg), 0 0 60px var(--fg), 0 0 60px var(--fg),
+ 0 0 40px var(--fg), 0 0 40px var(--fg), 0 0 20px var(--fg),
0 0 20px var(--fg);
}
- to { box-shadow: none; }
+ to {
+ box-shadow: none;
+ }
}
.dot {
@@ -22,5 +23,5 @@
width: 10px;
height: 10px;
border-radius: 100vmax;
- animation: .05s emerge, 1s highlight;
+ animation: 0.05s emerge, 1s highlight;
}
diff --git a/src/components/Dot.tsx b/src/components/Dot.tsx
index 619cc13..39a6590 100644
--- a/src/components/Dot.tsx
+++ b/src/components/Dot.tsx
@@ -1,24 +1,26 @@
-import React from 'react';
-import './Dot.css';
+import React from "react";
+import "./Dot.css";
interface Props {
- posX: number,
- posY: number,
- radius: number,
- opacity?: number
+ posX: number;
+ posY: number;
+ radius: number;
+ opacity?: number;
}
const Dot: React.FC
= ({ posX, posY, radius, opacity }) => {
- return
;
+ return (
+
+ );
};
export default Dot;
diff --git a/src/index.tsx b/src/index.tsx
index b597a44..c24e9d8 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,5 +1,5 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
+import React from "react";
+import ReactDOM from "react-dom";
+import App from "./App";
-ReactDOM.render( , document.getElementById('root'));
+ReactDOM.render( , document.getElementById("root"));
diff --git a/src/logic/Ant.test.ts b/src/logic/Ant.test.ts
index 29b8024..2fb17fd 100644
--- a/src/logic/Ant.test.ts
+++ b/src/logic/Ant.test.ts
@@ -1,17 +1,27 @@
-import Ant from './Ant';
+import Ant from "./Ant";
-[[10, 20], [300, 25], [10003, 30001]].forEach(pos => test(`ant position (${pos[0]}, ${pos[1]})`, () => {
- const [posX, posY] = pos;
- const ant = new Ant({ posX, posY });
- expect(ant.posX).toBe(posX);
- expect(ant.posY).toBe(posY);
- expect(ant.velX).toBe(0);
- expect(ant.velY).toBe(0);
- ant.updateVelocity([]);
- expect(ant.velX).not.toBe(0);
- expect(ant.velY).not.toBe(0);
- ant.updatePosition();
- expect(Math.round(ant.posX)).toBe(Math.round((posX +ant.velX) %window.innerWidth));
- expect(Math.round(ant.posY)).toBe(Math.round((posY +ant.velY) %window.innerHeight));
- ant.velY
-}));
+[
+ [10, 20],
+ [300, 25],
+ [10003, 30001],
+].forEach((pos) =>
+ test(`ant position (${pos[0]}, ${pos[1]})`, () => {
+ const [posX, posY] = pos;
+ const ant = new Ant({ posX, posY });
+ expect(ant.posX).toBe(posX);
+ expect(ant.posY).toBe(posY);
+ expect(ant.velX).toBe(0);
+ expect(ant.velY).toBe(0);
+ ant.updateVelocity([]);
+ expect(ant.velX).not.toBe(0);
+ expect(ant.velY).not.toBe(0);
+ ant.updatePosition();
+ expect(Math.round(ant.posX)).toBe(
+ Math.round((posX + ant.velX) % window.innerWidth)
+ );
+ expect(Math.round(ant.posY)).toBe(
+ Math.round((posY + ant.velY) % window.innerHeight)
+ );
+ ant.velY;
+ })
+);
diff --git a/src/logic/Ant.ts b/src/logic/Ant.ts
index ac89046..1c32043 100644
--- a/src/logic/Ant.ts
+++ b/src/logic/Ant.ts
@@ -3,16 +3,14 @@ import {
angToVec,
degToRad,
getVecMagnitude,
- getVecDiffInLoopingGrid
-} from './Trig';
-
+ getVecDiffInLoopingGrid,
+} from "./Trig";
interface Push {
- posDiff: [number, number],
- distance: number
+ posDiff: [number, number];
+ distance: number;
}
-
export default class Ant {
posX: number;
posY: number;
@@ -54,17 +52,17 @@ export default class Ant {
distancingFactor: number;
constructor(options: {
- posX?: number,
- posY?: number,
- agility: number,
- speed: number,
- minSpeed: number,
- maxSpeed: number,
- distancingRange: number,
- distancingFactor: number
+ posX?: number;
+ posY?: number;
+ agility: number;
+ speed: number;
+ minSpeed: number;
+ maxSpeed: number;
+ distancingRange: number;
+ distancingFactor: number;
}) {
- this.posX = options.posX || (Math.random() *window.innerWidth);
- this.posY = options.posY || (Math.random() *window.innerHeight);
+ this.posX = options.posX || Math.random() * window.innerWidth;
+ this.posY = options.posY || Math.random() * window.innerHeight;
this.agility = options.agility;
this.speed = options.speed;
this.minSpeed = options.minSpeed;
@@ -74,37 +72,50 @@ export default class Ant {
}
getPushes(neighbours: (Ant | { pos: [number, number] })[]): Push[] {
- return neighbours.map((ant): Push | null => {
- if (ant !== this) {
- const posDiff = getVecDiffInLoopingGrid(this.pos, ant.pos, [window.innerWidth, window.innerHeight]);
- // avoid calculating the hypotenuse(magnitude) if not necessary
- if (posDiff[0] <= this.distancingRange && posDiff[1] <= this.distancingRange) {
- const distance = getVecMagnitude(posDiff);
- if (distance <= this.distancingRange) return { posDiff, distance };
- else return null;
+ return neighbours
+ .map((ant): Push | null => {
+ if (ant !== this) {
+ const posDiff = getVecDiffInLoopingGrid(this.pos, ant.pos, [
+ window.innerWidth,
+ window.innerHeight,
+ ]);
+ // avoid calculating the hypotenuse(magnitude) if not necessary
+ if (
+ posDiff[0] <= this.distancingRange &&
+ posDiff[1] <= this.distancingRange
+ ) {
+ const distance = getVecMagnitude(posDiff);
+ if (distance <= this.distancingRange) return { posDiff, distance };
+ else return null;
+ } else return null;
} else return null;
- } else return null;
- }).filter(push => push !== null) as Push[];
+ })
+ .filter((push) => push !== null) as Push[];
}
calcPush(distance: number) {
- return Math.min(this.minSpeed +this.distancingFactor *this.distancingRange /distance -1, this.maxSpeed);
+ return Math.min(
+ this.minSpeed +
+ (this.distancingFactor * this.distancingRange) / distance -
+ 1,
+ this.maxSpeed
+ );
}
updatePosition(): Ant {
- this.posX += window.innerWidth +this.velX;
- this.posY += window.innerHeight +this.velY;
+ this.posX += window.innerWidth + this.velX;
+ this.posY += window.innerHeight + this.velY;
this.posX %= window.innerWidth;
this.posY %= window.innerHeight;
return this;
- };
+ }
updateVelocity(neighbours: (Ant | { pos: [number, number] })[]): Ant {
const pushes = this.getPushes(neighbours);
if (pushes.length > 0) {
const vel: [number, number] = [0, 0];
- pushes.forEach(push => {
- const pushAngle = vecToAng(push.posDiff) +Math.PI;
+ pushes.forEach((push) => {
+ const pushAngle = vecToAng(push.posDiff) + Math.PI;
const pushVector = angToVec(pushAngle, this.calcPush(push.distance));
vel[0] += pushVector[0];
vel[1] += pushVector[1];
@@ -113,9 +124,9 @@ export default class Ant {
} else {
let angle = this.angle;
if (isNaN(angle)) angle = 0;
- angle += (Math.random() -.5) *2 *this._agility;
+ angle += (Math.random() - 0.5) * 2 * this._agility;
[this.velX, this.velY] = angToVec(angle, this.speed);
}
return this;
- };
+ }
}
diff --git a/src/logic/Trig.test.ts b/src/logic/Trig.test.ts
index 49c4196..38409f5 100644
--- a/src/logic/Trig.test.ts
+++ b/src/logic/Trig.test.ts
@@ -6,69 +6,69 @@ import {
vecToAng,
getVecMagnitude,
getVecSum,
- getVecDiffInLoopingGrid
-} from './Trig';
+ getVecDiffInLoopingGrid,
+} from "./Trig";
-test('radian <-> degree conversion', () => {
+test("radian <-> degree conversion", () => {
expect(radToDeg(Math.PI)).toBe(180);
expect(degToRad(180)).toBe(Math.PI);
- expect(radToDeg(Math.PI /2)).toBe(90);
- expect(degToRad(90)).toBe(Math.PI /2);
- expect(radToDeg(Math.PI *2)).toBe(360);
- expect(degToRad(360)).toBe(Math.PI *2);
+ expect(radToDeg(Math.PI / 2)).toBe(90);
+ expect(degToRad(90)).toBe(Math.PI / 2);
+ expect(radToDeg(Math.PI * 2)).toBe(360);
+ expect(degToRad(360)).toBe(Math.PI * 2);
expect(radToDeg(0)).toBe(0);
expect(degToRad(0)).toBe(0);
});
-test(
- 'fullTurn is 360°',
- () => expect(radToDeg(fullTurn)).toBe(360)
-);
+test("fullTurn is 360°", () => expect(radToDeg(fullTurn)).toBe(360));
-test(
- 'Angle 0 corresponds to vector vector (1, 0)',
- () => expect(angToVec(0)).toEqual([1, 0])
-);
+test("Angle 0 corresponds to vector vector (1, 0)", () =>
+ expect(angToVec(0)).toEqual([1, 0]));
-test(
- 'O-vector angle is NaN',
- () => expect(vecToAng(0, 0)).toBeNaN()
-);
+test("O-vector angle is NaN", () => expect(vecToAng(0, 0)).toBeNaN());
-[0, 45, 90, 135, 180, 225, 270, 315, 360].forEach(angle =>
+[0, 45, 90, 135, 180, 225, 270, 315, 360].forEach((angle) =>
test(`angle ${angle}° consistency`, () => {
const pos = angToVec(degToRad(angle));
- expect(Math.round(radToDeg(vecToAng(pos))))
- .toBe(angle %360);
- }));
-
-[[3, 4, 5], [5, 12, 13], [8, 15, 17], [7, 24, 25]].forEach(triple =>
- test(
- `hypotenuse for Pythagorean triple (${triple.join(', ')})`,
- () => expect(getVecMagnitude([triple[0], triple[1]]))
- .toBe(triple[2])
- ));
+ expect(Math.round(radToDeg(vecToAng(pos)))).toBe(angle % 360);
+ })
+);
[
- [[-91, -68], [23, 16]],
- [[-82, 84], [22, -41]]
-].forEach(set => test(
- `sum of (${set[0].join(', ')}) & (${set[1].join(', ')})`,
- () => expect(getVecSum(set[0], set[1]))
- .toEqual([
- set[0][0] +set[1][0],
- set[0][1] +set[1][1]
- ])
-));
-
-test(
- `diff of (91, 84) & (90, 89) in (99, 31)`,
- () => expect(getVecDiffInLoopingGrid([91, 84], [90, 89], [99, 31]))
- .toEqual([-1, 5])
+ [3, 4, 5],
+ [5, 12, 13],
+ [8, 15, 17],
+ [7, 24, 25],
+].forEach((triple) =>
+ test(`hypotenuse for Pythagorean triple (${triple.join(", ")})`, () =>
+ expect(getVecMagnitude([triple[0], triple[1]])).toBe(triple[2]))
);
-test(
- `diff of (2, 4) & (89, 64) in (90, 70)`,
- () => expect(getVecDiffInLoopingGrid([2, 4], [89, 64], [90, 70]))
- .toEqual([-3, -10])
+[
+ [
+ [-91, -68],
+ [23, 16],
+ ],
+ [
+ [-82, 84],
+ [22, -41],
+ ],
+].forEach((set) =>
+ test(`sum of (${set[0].join(", ")}) & (${set[1].join(", ")})`, () =>
+ expect(getVecSum(set[0], set[1])).toEqual([
+ set[0][0] + set[1][0],
+ set[0][1] + set[1][1],
+ ]))
);
+
+test(`diff of (91, 84) & (90, 89) in (99, 31)`, () =>
+ expect(getVecDiffInLoopingGrid([91, 84], [90, 89], [99, 31])).toEqual([
+ -1,
+ 5,
+ ]));
+
+test(`diff of (2, 4) & (89, 64) in (90, 70)`, () =>
+ expect(getVecDiffInLoopingGrid([2, 4], [89, 64], [90, 70])).toEqual([
+ -3,
+ -10,
+ ]));
diff --git a/src/logic/Trig.ts b/src/logic/Trig.ts
index e718941..8aac781 100644
--- a/src/logic/Trig.ts
+++ b/src/logic/Trig.ts
@@ -1,17 +1,20 @@
-export const fullTurn = Math.PI *2;
+export const fullTurn = Math.PI * 2;
export const vecToAng = (vec: [number, number]): number =>
- (fullTurn +Math.atan(vec[1] /vec[0]) +(vec[0] < 0 ? Math.PI : 0)) %fullTurn;
+ (fullTurn + Math.atan(vec[1] / vec[0]) + (vec[0] < 0 ? Math.PI : 0)) %
+ fullTurn;
-export const angToVec = (angle: number, length = 1): [number, number] =>
- [Math.cos(angle) *length, Math.sin(angle) *length];
+export const angToVec = (angle: number, length = 1): [number, number] => [
+ Math.cos(angle) * length,
+ Math.sin(angle) * length,
+];
export const getVecMagnitude = (vec: [number, number]): number =>
- (vec[0] **2 +vec[1] **2) **.5;
+ (vec[0] ** 2 + vec[1] ** 2) ** 0.5;
export const getVecSum = (...vectors: [number, number][]): [number, number] => {
const sum: [number, number] = [0, 0];
- vectors.forEach(vec => {
+ vectors.forEach((vec) => {
sum[0] += vec[0];
sum[1] += vec[1];
});
@@ -23,11 +26,11 @@ export const getVecDiffInLoopingGrid = (
vec1: [number, number],
loopSize: [number, number]
): [number, number] => {
- const posDiff: [number, number] = [vec1[0] -vec0[0], vec1[1] -vec0[1]];
- if (posDiff[0] > loopSize[0] /2) posDiff[0] -= loopSize[0];
- if (posDiff[1] > loopSize[1] /2) posDiff[1] -= loopSize[1];
+ const posDiff: [number, number] = [vec1[0] - vec0[0], vec1[1] - vec0[1]];
+ if (posDiff[0] > loopSize[0] / 2) posDiff[0] -= loopSize[0];
+ if (posDiff[1] > loopSize[1] / 2) posDiff[1] -= loopSize[1];
return posDiff;
-}
+};
-export const radToDeg = (rad: number): number => rad /Math.PI *180;
-export const degToRad = (deg: number): number => deg *Math.PI /180;
+export const radToDeg = (rad: number): number => (rad / Math.PI) * 180;
+export const degToRad = (deg: number): number => (deg * Math.PI) / 180;
diff --git a/tsconfig.json b/tsconfig.json
index f2850b7..af10394 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,7 @@
{
"compilerOptions": {
"target": "es5",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
@@ -19,7 +15,5 @@
"noEmit": true,
"jsx": "react"
},
- "include": [
- "src"
- ]
+ "include": ["src"]
}