introduce prettierrc formatting

This commit is contained in:
John Gatward
2026-03-31 22:19:53 +01:00
parent 415b76532a
commit 7c58ce135c
100 changed files with 85618 additions and 11596 deletions

View File

@@ -19,223 +19,227 @@ let displayHeight = 1;
let resizeAnimationFrame = 0;
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
return Math.min(Math.max(value, min), max);
}
function getInitialBoidCount(width, height) {
const areaScale = (width * height) / (1920 * 1080);
const targetCount = Math.round(BOIDS_PER_1920X1080 * areaScale);
const clampedCount = clamp(targetCount, MIN_INITIAL_BOIDS, MAX_INITIAL_BOIDS);
return Math.round(clampedCount / BOID_STEP) * BOID_STEP;
const areaScale = (width * height) / (1920 * 1080);
const targetCount = Math.round(BOIDS_PER_1920X1080 * areaScale);
const clampedCount = clamp(targetCount, MIN_INITIAL_BOIDS, MAX_INITIAL_BOIDS);
return Math.round(clampedCount / BOID_STEP) * BOID_STEP;
}
function syncBoidCountToViewport(width, height) {
const targetCount = getInitialBoidCount(width, height);
let currentCount = sim.get_boid_count();
const targetCount = getInitialBoidCount(width, height);
let currentCount = sim.get_boid_count();
while (currentCount < targetCount) {
sim.add_boid();
currentCount = sim.get_boid_count();
}
while (currentCount < targetCount) {
sim.add_boid();
currentCount = sim.get_boid_count();
}
while (currentCount > targetCount) {
sim.remove_boid();
currentCount = sim.get_boid_count();
}
while (currentCount > targetCount) {
sim.remove_boid();
currentCount = sim.get_boid_count();
}
updateBoidCount();
updateBoidCount();
}
function updateControlsCollapsedState(isCollapsed) {
if (controls === null || controlsToggle === null) {
return;
}
if (controls === null || controlsToggle === null) {
return;
}
controls.classList.toggle('collapsed', isCollapsed);
controls.setAttribute('aria-expanded', String(!isCollapsed));
controlsToggle.setAttribute('aria-expanded', String(!isCollapsed));
controlsToggle.setAttribute('aria-label', isCollapsed ? 'Expand controls' : 'Collapse controls');
controlsToggle.textContent = isCollapsed ? '' : '';
controls.classList.toggle('collapsed', isCollapsed);
controls.setAttribute('aria-expanded', String(!isCollapsed));
controlsToggle.setAttribute('aria-expanded', String(!isCollapsed));
controlsToggle.setAttribute(
'aria-label',
isCollapsed ? 'Expand controls' : 'Collapse controls'
);
controlsToggle.textContent = isCollapsed ? '' : '';
}
function sizeCanvasToViewport() {
const dpr = window.devicePixelRatio || 1;
const nextDisplayWidth = Math.max(1, Math.floor(canvas.clientWidth));
const nextDisplayHeight = Math.max(1, Math.floor(canvas.clientHeight));
const nextBufferWidth = Math.max(1, Math.round(nextDisplayWidth * dpr));
const nextBufferHeight = Math.max(1, Math.round(nextDisplayHeight * dpr));
const dpr = window.devicePixelRatio || 1;
const nextDisplayWidth = Math.max(1, Math.floor(canvas.clientWidth));
const nextDisplayHeight = Math.max(1, Math.floor(canvas.clientHeight));
const nextBufferWidth = Math.max(1, Math.round(nextDisplayWidth * dpr));
const nextBufferHeight = Math.max(1, Math.round(nextDisplayHeight * dpr));
if (canvas.width !== nextBufferWidth || canvas.height !== nextBufferHeight) {
canvas.width = nextBufferWidth;
canvas.height = nextBufferHeight;
}
if (canvas.width !== nextBufferWidth || canvas.height !== nextBufferHeight) {
canvas.width = nextBufferWidth;
canvas.height = nextBufferHeight;
}
displayWidth = nextDisplayWidth;
displayHeight = nextDisplayHeight;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
document.getElementById('canvasSize').textContent = `${displayWidth}x${displayHeight}`;
displayWidth = nextDisplayWidth;
displayHeight = nextDisplayHeight;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
document.getElementById('canvasSize').textContent =
`${displayWidth}x${displayHeight}`;
return { width: displayWidth, height: displayHeight };
return { width: displayWidth, height: displayHeight };
}
function scheduleResize() {
if (resizeAnimationFrame !== 0) {
return;
}
if (resizeAnimationFrame !== 0) {
return;
}
resizeAnimationFrame = window.requestAnimationFrame(() => {
resizeAnimationFrame = 0;
const { width, height } = sizeCanvasToViewport();
if (sim !== null) {
sim.resize(width, height);
syncBoidCountToViewport(width, height);
}
});
resizeAnimationFrame = window.requestAnimationFrame(() => {
resizeAnimationFrame = 0;
const { width, height } = sizeCanvasToViewport();
if (sim !== null) {
sim.resize(width, height);
syncBoidCountToViewport(width, height);
}
});
}
function setupResizeObserver() {
controlsResizeObserver = new ResizeObserver(() => {
scheduleResize();
});
controlsResizeObserver.observe(document.getElementById('container'));
controlsResizeObserver.observe(controls);
controlsResizeObserver = new ResizeObserver(() => {
scheduleResize();
});
controlsResizeObserver.observe(document.getElementById('container'));
controlsResizeObserver.observe(controls);
}
async function run() {
wasm = await init();
wasm = await init();
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
controls = document.getElementById('controls');
controlsToggle = document.getElementById('controlsToggle');
updateControlsCollapsedState(false);
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
controls = document.getElementById('controls');
controlsToggle = document.getElementById('controlsToggle');
updateControlsCollapsedState(false);
const { width, height } = sizeCanvasToViewport();
sim = new SimulationWasm(width, height, getInitialBoidCount(width, height));
const { width, height } = sizeCanvasToViewport();
sim = new SimulationWasm(width, height, getInitialBoidCount(width, height));
setupControls();
setupResizeObserver();
updateBoidCount();
window.addEventListener('resize', scheduleResize);
setupControls();
setupResizeObserver();
updateBoidCount();
window.addEventListener('resize', scheduleResize);
animate();
animate();
}
function setupControls() {
const alignSlider = document.getElementById('alignSlider');
const cohesionSlider = document.getElementById('cohesionSlider');
const separationSlider = document.getElementById('separationSlider');
const addBtn = document.getElementById('addBtn');
const removeBtn = document.getElementById('removeBtn');
const alignSlider = document.getElementById('alignSlider');
const cohesionSlider = document.getElementById('cohesionSlider');
const separationSlider = document.getElementById('separationSlider');
const addBtn = document.getElementById('addBtn');
const removeBtn = document.getElementById('removeBtn');
controlsToggle.addEventListener('click', () => {
const isCollapsed = !controls.classList.contains('collapsed');
updateControlsCollapsedState(isCollapsed);
scheduleResize();
});
controlsToggle.addEventListener('click', () => {
const isCollapsed = !controls.classList.contains('collapsed');
updateControlsCollapsedState(isCollapsed);
scheduleResize();
});
alignSlider.addEventListener('input', (e) => {
const value = Number.parseFloat(e.target.value);
sim.set_align_mult(value);
document.getElementById('alignValue').textContent = value.toFixed(2);
});
alignSlider.addEventListener('input', (e) => {
const value = Number.parseFloat(e.target.value);
sim.set_align_mult(value);
document.getElementById('alignValue').textContent = value.toFixed(2);
});
cohesionSlider.addEventListener('input', (e) => {
const value = Number.parseFloat(e.target.value);
sim.set_cohesion_mult(value);
document.getElementById('cohesionValue').textContent = value.toFixed(2);
});
cohesionSlider.addEventListener('input', (e) => {
const value = Number.parseFloat(e.target.value);
sim.set_cohesion_mult(value);
document.getElementById('cohesionValue').textContent = value.toFixed(2);
});
separationSlider.addEventListener('input', (e) => {
const value = Number.parseFloat(e.target.value);
sim.set_separation_mult(value);
document.getElementById('separationValue').textContent = value.toFixed(2);
});
separationSlider.addEventListener('input', (e) => {
const value = Number.parseFloat(e.target.value);
sim.set_separation_mult(value);
document.getElementById('separationValue').textContent = value.toFixed(2);
});
addBtn.addEventListener('click', () => {
sim.add_boid();
updateBoidCount();
});
addBtn.addEventListener('click', () => {
sim.add_boid();
updateBoidCount();
});
removeBtn.addEventListener('click', () => {
sim.remove_boid();
updateBoidCount();
});
removeBtn.addEventListener('click', () => {
sim.remove_boid();
updateBoidCount();
});
}
function updateBoidCount() {
document.getElementById('boidCount').textContent = sim.get_boid_count();
document.getElementById('boidCount').textContent = sim.get_boid_count();
}
function getBoidView() {
const ptr = sim.boid_buffer_ptr();
const len = sim.boid_buffer_len();
return new Float32Array(wasm.memory.buffer, ptr, len);
const ptr = sim.boid_buffer_ptr();
const len = sim.boid_buffer_len();
return new Float32Array(wasm.memory.buffer, ptr, len);
}
function animate() {
ctx.fillStyle = '#121212';
ctx.fillRect(0, 0, displayWidth, displayHeight);
ctx.fillStyle = '#121212';
ctx.fillRect(0, 0, displayWidth, displayHeight);
sim.step();
const boidData = getBoidView();
const stride = sim.boid_buffer_stride();
sim.step();
const boidData = getBoidView();
const stride = sim.boid_buffer_stride();
for (let i = 0; i < boidData.length; i += stride) {
const x = boidData[i];
const y = boidData[i + 1];
const vx = boidData[i + 2];
const vy = boidData[i + 3];
const r = boidData[i + 4];
const g = boidData[i + 5];
const b = boidData[i + 6];
const a = boidData[i + 7];
for (let i = 0; i < boidData.length; i += stride) {
const x = boidData[i];
const y = boidData[i + 1];
const vx = boidData[i + 2];
const vy = boidData[i + 3];
const r = boidData[i + 4];
const g = boidData[i + 5];
const b = boidData[i + 6];
const a = boidData[i + 7];
const speedSq = vx * vx + vy * vy;
let dx;
let dy;
if (speedSq > 1e-6) {
const invSpeed = 1 / Math.sqrt(speedSq);
dx = vx * invSpeed;
dy = vy * invSpeed;
} else {
dx = 0;
dy = -1;
}
const size = 5;
const headMult = 3;
const px = -dy;
const py = dx;
const tipX = x + dx * size * headMult;
const tipY = y + dy * size * headMult;
const baseX = x - dx * size;
const baseY = y - dy * size;
const leftX = baseX + px * size;
const leftY = baseY + py * size;
const rightX = baseX - px * size;
const rightY = baseY - py * size;
ctx.strokeStyle = `rgba(${r},${g},${b},${a / 255})`;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(tipX, tipY);
ctx.lineTo(leftX, leftY);
ctx.lineTo(rightX, rightY);
ctx.closePath();
ctx.stroke();
const speedSq = vx * vx + vy * vy;
let dx;
let dy;
if (speedSq > 1e-6) {
const invSpeed = 1 / Math.sqrt(speedSq);
dx = vx * invSpeed;
dy = vy * invSpeed;
} else {
dx = 0;
dy = -1;
}
frameCount += 1;
const now = Date.now();
if (now - lastFpsUpdate >= 1000) {
document.getElementById('fps').textContent = frameCount;
frameCount = 0;
lastFpsUpdate = now;
}
const size = 5;
const headMult = 3;
const px = -dy;
const py = dx;
requestAnimationFrame(animate);
const tipX = x + dx * size * headMult;
const tipY = y + dy * size * headMult;
const baseX = x - dx * size;
const baseY = y - dy * size;
const leftX = baseX + px * size;
const leftY = baseY + py * size;
const rightX = baseX - px * size;
const rightY = baseY - py * size;
ctx.strokeStyle = `rgba(${r},${g},${b},${a / 255})`;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(tipX, tipY);
ctx.lineTo(leftX, leftY);
ctx.lineTo(rightX, rightY);
ctx.closePath();
ctx.stroke();
}
frameCount += 1;
const now = Date.now();
if (now - lastFpsUpdate >= 1000) {
document.getElementById('fps').textContent = frameCount;
frameCount = 0;
lastFpsUpdate = now;
}
requestAnimationFrame(animate);
}
await run();