diff --git a/bundle.js b/bundle.js index 9670324..4489c01 100644 --- a/bundle.js +++ b/bundle.js @@ -684,54 +684,6 @@ class OriginVector extends Vector { return new OriginVector(origin, v); } } -function satCollisionSpline(p, spline) { - for(let i = 0; i < 100; i++){ - const t1 = i / 100; - const t2 = (i + 1) / 100; - const segmentStart = spline.getPointAtT(t1); - const segmentEnd = spline.getPointAtT(t2); - if (segmentIntersectsPolygon(p, segmentStart, segmentEnd)) { - return true; - } - } - return false; -} -function segmentIntersectsPolygon(p, start, end) { - const edges = p.getEdges(); - for (const edge of edges){ - const axis = edge.copy().normal().normalize(); - const proj1 = projectPolygonOntoAxis(p, axis); - const proj2 = projectSegmentOntoAxis(start, end, axis); - if (!overlap(proj1, proj2)) { - return false; - } - } - return true; -} -function projectPolygonOntoAxis(p, axis) { - let min = Infinity; - let max = -Infinity; - for (const point of p.points){ - const dotProduct = point.copy().add(p.center).dot(axis); - min = Math.min(min, dotProduct); - max = Math.max(max, dotProduct); - } - return { - min, - max - }; -} -function projectSegmentOntoAxis(start, end, axis) { - const dotProductStart = start.dot(axis); - const dotProductEnd = end.dot(axis); - return { - min: Math.min(dotProductStart, dotProductEnd), - max: Math.max(dotProductStart, dotProductEnd) - }; -} -function overlap(proj1, proj2) { - return proj1.min <= proj2.max && proj1.max >= proj2.min; -} const easeInOut = (x)=>x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2; const map = (value, x1, y1, x2, y2)=>(value - x1) * (y2 - x2) / (y1 - x1) + x2; class Doodler { @@ -749,15 +701,24 @@ class Doodler { draggables = []; clickables = []; dragTarget; - constructor({ width, height, canvas, bg, framerate }, postInit){ + constructor({ width, height, fillScreen, canvas, bg, framerate }, postInit){ if (!canvas) { canvas = document.createElement("canvas"); document.body.append(canvas); } this.bg = bg || "white"; this.framerate = framerate || 60; - canvas.width = width; - canvas.height = height; + canvas.width = fillScreen ? document.body.clientWidth : width; + canvas.height = fillScreen ? document.body.clientHeight : height; + if (fillScreen) { + const resizeObserver = new ResizeObserver((entries)=>{ + for (const entry of entries){ + this._canvas.width = entry.target.clientWidth; + this._canvas.height = entry.target.clientHeight; + } + }); + resizeObserver.observe(document.body); + } this._canvas = canvas; const ctx = canvas.getContext("2d"); if (!ctx) throw "Unable to initialize Doodler: Canvas context not found"; @@ -1308,6 +1269,54 @@ const init = (opt, zoomable, postInit)=>{ window.doodler = zoomable ? new ZoomableDoodler(opt, postInit) : new Doodler(opt, postInit); window.doodler.init(); }; +function satCollisionSpline(p, spline) { + for(let i = 0; i < 100; i++){ + const t1 = i / 100; + const t2 = (i + 1) / 100; + const segmentStart = spline.getPointAtT(t1); + const segmentEnd = spline.getPointAtT(t2); + if (segmentIntersectsPolygon(p, segmentStart, segmentEnd)) { + return true; + } + } + return false; +} +function segmentIntersectsPolygon(p, start, end) { + const edges = p.getEdges(); + for (const edge of edges){ + const axis = edge.copy().normal().normalize(); + const proj1 = projectPolygonOntoAxis(p, axis); + const proj2 = projectSegmentOntoAxis(start, end, axis); + if (!overlap(proj1, proj2)) { + return false; + } + } + return true; +} +function projectPolygonOntoAxis(p, axis) { + let min = Infinity; + let max = -Infinity; + for (const point of p.points){ + const dotProduct = point.copy().add(p.center).dot(axis); + min = Math.min(min, dotProduct); + max = Math.max(max, dotProduct); + } + return { + min, + max + }; +} +function projectSegmentOntoAxis(start, end, axis) { + const dotProductStart = start.dot(axis); + const dotProductEnd = end.dot(axis); + return { + min: Math.min(dotProductStart, dotProductEnd), + max: Math.max(dotProductStart, dotProductEnd) + }; +} +function overlap(proj1, proj2) { + return proj1.min <= proj2.max && proj1.max >= proj2.min; +} class Polygon { points; center; @@ -1580,9 +1589,8 @@ class SplineSegment { } } init({ - width: 400, - height: 400, - framerate: 90 + fillScreen: true, + bg: "#333" }, true, (ctx)=>{ ctx.imageSmoothingEnabled = false; }); @@ -1590,7 +1598,48 @@ const img = new Image(); img.src = "./pixel fire.gif"; const p = new Vector(); const gif = new GIFAnimation("./fire-joypixels.gif", p, .5); +const spline = new SplineSegment([ + new Vector({ + x: -25, + y: -25 + }).mult(10).add(p), + new Vector({ + x: 25, + y: -25 + }).mult(10).add(p), + new Vector({ + x: -25, + y: -25 + }).mult(10).add(p), + new Vector({ + x: -25, + y: 25 + }).mult(10).add(p) +]); +const poly2 = Polygon.createPolygon(4); +poly2.center = p.copy().add(100, 100); doodler.createLayer((c, i, t)=>{ gif.draw(t); + for(let i = 0; i < c.canvas.width; i += 50){ + for(let j = 0; j < c.canvas.height; j += 50){ + doodler.drawSquare(new Vector(i, j), 50, { + color: "#00000010" + }); + } + } + poly2.circularHitbox; + const intersects = satCollisionSpline(poly2, spline); + const color = intersects ? "red" : "aqua"; + spline.draw(color); + poly2.draw(color); + const [gamepad] = navigator.getGamepads(); + if (gamepad) { + gamepad.axes[0]; + gamepad.axes[1]; + const rightX = gamepad.axes[2]; + const rightY = gamepad.axes[3]; + let mMulti = 10; + const mod = new Vector(Math.min(Math.max(rightX - 0.05, 0), rightX + 0.05), Math.min(Math.max(rightY - 0.05, 0), rightY + 0.05)); + poly2.center.add(mod.mult(mMulti)); + } }); -requestAnimationFrame; diff --git a/canvas.ts b/canvas.ts index 3ff90a5..8205014 100644 --- a/canvas.ts +++ b/canvas.ts @@ -6,7 +6,7 @@ import { postInit } from "./postInit.ts"; import { ZoomableDoodler } from "./zoomableCanvas.ts"; export const init = ( - opt: IDoodlerOptions, + opt: DoodlerOptions, zoomable: boolean, postInit?: postInit, ) => { @@ -19,13 +19,22 @@ export const init = ( window.doodler.init(); }; -export interface IDoodlerOptions { - width: number; - height: number; +type DoodlerOptionalOptions = { canvas?: HTMLCanvasElement; bg?: string; framerate?: number; -} +}; + +type DoodlerRequiredOptions = { + width: number; + height: number; + fillScreen?: false; +} | { + width?: 0; + height?: 0; + fillScreen: true; +}; +export type DoodlerOptions = DoodlerOptionalOptions & DoodlerRequiredOptions; type layer = ( ctx: CanvasRenderingContext2D, @@ -57,10 +66,11 @@ export class Doodler { constructor({ width, height, + fillScreen, canvas, bg, framerate, - }: IDoodlerOptions, postInit?: postInit) { + }: DoodlerOptions, postInit?: postInit) { if (!canvas) { canvas = document.createElement("canvas"); document.body.append(canvas); @@ -69,8 +79,19 @@ export class Doodler { this.bg = bg || "white"; this.framerate = framerate || 60; - canvas.width = width; - canvas.height = height; + canvas.width = fillScreen ? document.body.clientWidth : width; + canvas.height = fillScreen ? document.body.clientHeight : height; + + if (fillScreen) { + const resizeObserver = new ResizeObserver((entries) => { + for (const entry of entries) { + this._canvas.width = entry.target.clientWidth; + this._canvas.height = entry.target.clientHeight; + // this.ctx = this.c + } + }); + resizeObserver.observe(document.body); + } this._canvas = canvas; diff --git a/index.html b/index.html index 095b092..2e39be8 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,12 @@