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));