From 2ae236cc67c3792efad11f95d81eb5b6ee775f13 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 19 Aug 2026 17:17:46 +0200 Subject: [PATCH] refactor --- bezier-1.ts | 19 ++++++++++++------- metaballs.html | 22 ++++++++++++++++++++-- metaballs.ts | 36 +++++++++++++++++++++--------------- move.ts | 3 ++- vec.ts | 9 +++++++++ 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/bezier-1.ts b/bezier-1.ts index f3c2747..860ebfd 100644 --- a/bezier-1.ts +++ b/bezier-1.ts @@ -1,4 +1,4 @@ -import { Point, lerpPoint, drawCircle, drawLine, drawDashedLine, resizeCanvas } from "./common.js" +import { Point, lerpPoint, drawCircle, drawLine, drawDashedLine, resizeCanvas, drawCurve } from "./common.js" let points: Point[] = []; @@ -17,7 +17,8 @@ function update(ctx: CanvasRenderingContext2D, time: number) { drawDashedLine(ctx, ab, bc, 0xFF0000); drawCircle(ctx, ab, 1, 0xFF0000); drawCircle(ctx, bc, 1, 0xFF0000); - drawCircle(ctx, abc, 1, 0xFFFFFF); + + drawCircle(ctx, abc, 1, 0xFFFFFF); // Point on the bezier curve } else if (points.length === 4) { const [a, b, c, d] = points; const ab = lerpPoint(a, b, p); @@ -35,7 +36,8 @@ function update(ctx: CanvasRenderingContext2D, time: number) { drawCircle(ctx, cd, 1, 0xFF0000); drawCircle(ctx, abc, 1, 0xFFFF00); drawCircle(ctx, bcd, 1, 0xFFFF00); - drawCircle(ctx, abcd, 1, 0xFFFFFF); + + drawCircle(ctx, abcd, 1, 0xFFFFFF); // Point on the bezier curve } for (let i = 0; i < points.length - 1; ++i) { @@ -60,10 +62,13 @@ function init() { resizeCanvas(ctx); // Init canvas to full window size canvas.addEventListener("click", (evt) => { - const {clientX, clientY} = evt; - if (points.length < 4) { - points.push({x: clientX, y: clientY}); - } + const rect = canvas.getBoundingClientRect(); + if (points.length < 4) { + points.push({ + x: evt.clientX - rect.left, + y: evt.clientY - rect.top, + }); + } }); window.addEventListener('resize', () => resizeCanvas(ctx)); diff --git a/metaballs.html b/metaballs.html index 9d50c0b..d6e2948 100644 --- a/metaballs.html +++ b/metaballs.html @@ -3,9 +3,27 @@ - Hello typescript + Metaballs + - + diff --git a/metaballs.ts b/metaballs.ts index 10a3dcf..ba8c21f 100644 --- a/metaballs.ts +++ b/metaballs.ts @@ -1,3 +1,5 @@ +import { resizeCanvas } from "./common.js"; + let pos = { x: 0, y: 0 } function init() { @@ -5,20 +7,25 @@ function init() { if (!canvas) throw new Error("unable to get canvas HTML element"); const ctx = canvas.getContext("2d") as CanvasRenderingContext2D | null; if (!ctx) throw new Error("unable to get canvas 2D context"); + resizeCanvas(ctx); - ctx.canvas.width = window.innerWidth; - ctx.canvas.height = window.innerHeight; - - canvas.onmousemove = (evt) => { - const { clientX, clientY } = evt; + canvas.onmousemove = (evt) => { + const rect = canvas.getBoundingClientRect(); //const index = (clientY * canvas.width + clientX) * 4; - /*console.log("color", + /*console.log("color", pixels[index], pixels[index+1], pixels[index+2]);*/ - pos = { x: clientX, y: clientY }; + pos = { + x: (evt.clientX - rect.left) * canvas.width / rect.width, + y: (evt.clientY - rect.top) * canvas.height / rect.height, + }; } + // A canvas does not normally receive resize events. Use a resize observer + const observer = new ResizeObserver(() => resizeCanvas(ctx)); + observer.observe(canvas); + window.requestAnimationFrame(t => update(ctx, t)); } @@ -34,15 +41,15 @@ function update(ctx: CanvasRenderingContext2D, timestamp: number) { const d1 = 6000 / ((x - width/2)*(x - width/2) + (y - height/2)*(y - height/2)); const d2 = 8000 / ((x - pos.x)*(x - pos.x) + (y - pos.y)*(y - pos.y)); if (d1 + d2 >= 0.90 && d1 + d2 <= 1.00) { - pixels[index] = 255*d1; + pixels[index] = 255 * d1; pixels[index+1] = 0; - pixels[index+2] = 255*d2; - pixels[index+3] = 255; + pixels[index+2] = 255 * d2; + pixels[index+3] = 255; } else { - pixels[index] = 0; - pixels[index+1] = 0; - pixels[index+2] = 0; - pixels[index+3] = 255; + pixels[index] = 0; + pixels[index+1] = 0; + pixels[index+2] = 0; + pixels[index+3] = 0; } } } @@ -52,4 +59,3 @@ function update(ctx: CanvasRenderingContext2D, timestamp: number) { } init(); - diff --git a/move.ts b/move.ts index 845bcd1..8fe5869 100644 --- a/move.ts +++ b/move.ts @@ -99,7 +99,8 @@ function init() { canvas.onmousemove = (evt) => { const {clientX, clientY} = evt; - target = new Vec2d(clientX, clientY); + const rect = canvas.getBoundingClientRect(); + target = new Vec2d(clientX - rect.left, clientY - rect.top); } canvas.onclick = () => { diff --git a/vec.ts b/vec.ts index c3130a6..da8c318 100644 --- a/vec.ts +++ b/vec.ts @@ -38,9 +38,14 @@ export default class Vec2d implements Point { normalize(): Vec2d { const len = this.length(); + if (len === 0) return new Vec2d(0, 0); // avoid division by zero return new Vec2d(this.x / len, this.y / len); } + neg(): Vec2d { + return new Vec2d(-this.x, -this.y); + } + scale(scalar: number): Vec2d { return new Vec2d(this.x * scalar, this.y * scalar); } @@ -61,6 +66,10 @@ export default class Vec2d implements Point { return this.sub(other).length(); } + dot(other: Vec2d): number { + return this.x * other.x + this.y * other.y; + } + lerp(other: Vec2d, t: number): Vec2d { // (1-t)*A + B*t return this.scale(1 - t).add(other.scale(t));