Skip to content

Commit 9bd3f42

Browse files
committed
📹
1 parent ac2016e commit 9bd3f42

File tree

7 files changed

+72
-41
lines changed

7 files changed

+72
-41
lines changed

‎src/index.html‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@
1616
width: 100%;
1717
min-height: 100%;
1818
}
19+
#github-link{
20+
position: absolute;
21+
right:5px;
22+
bottom:5px;
23+
}
1924
</style>
2025
</head>
2126
<body>
2227
<canvas id="canvas"></canvas>
28+
<a id="github-link" href="https://github.com/Platane/hello-posthog">github</a>
2329
</body>
2430
</html>

‎src/index.ts‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ const gl = canvas.getContext("webgl2")!;
1313
const dpr = window.devicePixelRatio ?? 1;
1414

1515
gl.disable(gl.CULL_FACE);
16-
// gl.enable(gl.CULL_FACE);
17-
// gl.cullFace(gl.BACK);
1816

1917
gl.enable(gl.DEPTH_TEST);
2018
gl.depthFunc(gl.LESS);
@@ -49,10 +47,17 @@ window.addEventListener("mousemove", (e) => {
4947
state.pointer.x = e.clientX / window.innerWidth;
5048
state.pointer.y = e.clientY / window.innerHeight;
5149
});
50+
window.addEventListener("pointermove", (e) => {
51+
state.pointer.x = e.clientX / window.innerWidth;
52+
state.pointer.y = e.clientY / window.innerHeight;
53+
});
5254
window.addEventListener(
5355
"wheel",
5456
(e) => {
55-
state.zoom += e.deltaY;
57+
state.zoom = Math.min(
58+
1,
59+
Math.max(0, state.zoom + e.deltaY / window.innerHeight / 3),
60+
);
5661
},
5762
{ passive: true },
5863
);
@@ -61,13 +66,13 @@ const set = renderer.createSet();
6166
const sets = [set];
6267

6368
createSpriteAtlas().then((res) => {
69+
const searchParams = new URL(location.href).searchParams;
70+
const message = searchParams.get("message") || "Hello";
71+
const entityCount = parseInt(searchParams.get("n")) || 600;
72+
6473
renderer.updateSet(set, { colorTexture: res.texture });
65-
setInitialState(state, res.animationIndex);
66-
computeFinalPlacement(
67-
state,
68-
res.animationIndex,
69-
new URL(location.href).searchParams.get("message") || "Hello",
70-
);
74+
setInitialState(state, res.animationIndex, entityCount);
75+
computeFinalPlacement(state, res.animationIndex, message);
7176

7277
const loop = () => {
7378
state.time++;

‎src/logic/camera.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import type { State } from "./state";
44
export const stepCameraWobble = (state: State) => {
55
const phi = Math.PI / 7 + ((0.5 - state.pointer.y) * Math.PI) / 16;
66
const theta = (state.pointer.x - 0.5) * 0.4;
7-
const radius = 50;
7+
8+
const minRadius = 12;
9+
const maxRadius = state.worldSize[0] * 1.4;
10+
11+
const radius =
12+
minRadius + (maxRadius - minRadius) * (state.zoom * state.zoom);
813

914
state.camera.eye[0] = radius * Math.sin(theta) * Math.cos(phi);
1015
state.camera.eye[1] = radius * Math.cos(theta) * Math.cos(phi);

‎src/logic/computeFinalPlacement.ts‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,30 @@ export const computeFinalPlacement = (
4747
y: y - imageData.height * 0.5,
4848
});
4949

50-
const density = 0.1; // in entity per world unit square
50+
const density = 0.5; // in entity per world unit square
5151

5252
// density = N_Runner / area
5353
// density = N_Runner / ( N_cells * cellSize² )
54-
55-
// const s = Math.sqrt(game.runners.length / (density * cells.length));
56-
57-
const s = 30;
58-
59-
const k = s / imageData.height;
54+
const s = Math.sqrt(game.runners.length / (density * cells.length));
6055

6156
for (const runner of game.runners) {
6257
const { x, y } = cells[Math.floor(Math.random() * cells.length)];
6358

64-
runner.finalTarget[0] = (x + Math.random()) * k;
65-
runner.finalTarget[1] = (y + Math.random()) * k;
66-
runner.randomTargetCount = 0;
59+
runner.finalTarget[0] = (x + Math.random()) * s;
60+
runner.finalTarget[1] = (y + Math.random()) * s;
61+
runner.randomTargetCount = 1;
6762

6863
runner.animationIndex = animationIndex.walk;
6964
runner.animationFrameDuration = 3;
7065
}
66+
67+
let maxX = 0;
68+
let maxY = 0;
69+
for (const { x, y } of cells) {
70+
maxX = Math.max(maxX, (x + 1) * s);
71+
maxY = Math.max(maxY, (y + 1) * s);
72+
}
73+
74+
game.worldSize[0] = maxX * 2;
75+
game.worldSize[1] = maxY * 2;
7176
};

‎src/logic/crowd.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const stepRunnerLogic = (
2525
} else if (runner.randomTargetCount > 0) {
2626
(runner as Runner).goal = goal.goToTarget;
2727

28-
const A = 16 + Math.random() * 16;
28+
const A = (((1 + Math.random()) / 2) * state.worldSize[0]) / 2;
2929
const a = Math.random() * Math.PI * 2;
3030
vec2.set((runner as any).target, Math.sin(a) * A, Math.cos(a) * A);
3131

‎src/logic/sprites.ts‎

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,26 @@ export const deriveSprites = (
1515
let i = 0;
1616

1717
// shadows
18-
// vec3.set(s, 0.6, 0.6, 0.6);
19-
// quat.identity(q);
20-
// for (const runner of state.runners) {
21-
// const tr = state.objectTransforms[i];
22-
// vec3.set(v, runner.position[0] + 0.1, runner.position[1], -0.84 + i / 1000);
23-
// mat4.fromRotationTranslationScale(tr, q, v, s);
24-
25-
// const [min, max] = coords[animationIndex.shadow][0];
26-
// state.spriteBoxes[i * 4 + 0] = min[0];
27-
// state.spriteBoxes[i * 4 + 1] = min[1];
28-
// state.spriteBoxes[i * 4 + 2] = max[0];
29-
// state.spriteBoxes[i * 4 + 3] = max[1];
30-
31-
// i++;
32-
// }
18+
vec3.set(s, 0.6, 0.6, 0.6);
19+
quat.identity(q);
20+
for (const runner of state.runners) {
21+
const tr = state.objectTransforms[i];
22+
vec3.set(
23+
v,
24+
runner.position[0] + 0.1,
25+
runner.position[1],
26+
0 + (i % 500) * 0.0001,
27+
);
28+
mat4.fromRotationTranslationScale(tr, q, v, s);
29+
30+
const [min, max] = coords[animationIndex.shadow][0];
31+
state.spriteBoxes[i * 4 + 0] = min[0];
32+
state.spriteBoxes[i * 4 + 1] = min[1];
33+
state.spriteBoxes[i * 4 + 2] = max[0];
34+
state.spriteBoxes[i * 4 + 3] = max[1];
35+
36+
i++;
37+
}
3338

3439
// origin
3540
{

‎src/logic/state.ts‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { mat4, vec2, vec3 } from "gl-matrix";
22
import type { AnimationIndex } from "../sprites";
33

4-
export const MAX_ENTITIES = 10_000;
4+
export const MAX_ENTITIES = 8_000;
55

66
export const createState = () => {
77
const objectMatrices = new Float32Array(MAX_ENTITIES * 16);
@@ -17,7 +17,9 @@ export const createState = () => {
1717
return {
1818
time: 0,
1919
pointer: { x: 0.5, y: 0.5, down: false },
20-
zoom: 800,
20+
zoom: 0.9,
21+
22+
worldSize: [1, 1] as vec2,
2123

2224
camera: { eye: [0, 4, 4] as vec3 },
2325
viewMatrix,
@@ -74,6 +76,7 @@ export type State = ReturnType<typeof createState>;
7476
export const setInitialState = (
7577
state: State,
7678
animationIndex: AnimationIndex,
79+
entityCount: number,
7780
) => {
7881
const accessoriesIndex1 = [
7982
animationIndex.cap,
@@ -85,8 +88,7 @@ export const setInitialState = (
8588
];
8689
const accessoriesIndex2 = [animationIndex.glasses, animationIndex.sunglasses];
8790

88-
const N = 400;
89-
for (let i = N; i--; ) {
91+
for (let i = entityCount; i--; ) {
9092
const accessories: number[] = [];
9193

9294
const a1 =
@@ -102,7 +104,10 @@ export const setInitialState = (
102104
if (a2 !== undefined) accessories.push(a2);
103105

104106
state.runners.push({
105-
position: [(Math.random() * 2 - 1) * 10, (Math.random() * 2 - 1) * 10],
107+
position: [
108+
(Math.random() * 2 - 1) * 20 - 40,
109+
(Math.random() * 2 - 1) * 20,
110+
],
106111
velocity: [0, 0],
107112
animationIndex: animationIndex.walk,
108113
animationOffset: Math.floor(Math.random() * 10),

0 commit comments

Comments
 (0)