Refactors options and adds a fillScreen mode
This commit is contained in:
parent
31596774df
commit
e70787260a
159
bundle.js
159
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;
|
||||
|
37
canvas.ts
37
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;
|
||||
|
||||
|
@ -9,6 +9,12 @@
|
||||
<style>
|
||||
* {
|
||||
image-rendering: pixelated;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
img {
|
||||
|
13
main.ts
13
main.ts
@ -14,8 +14,9 @@ import { SplineSegment } from "./geometry/spline.ts";
|
||||
|
||||
initializeDoodler(
|
||||
{
|
||||
width: 2400,
|
||||
height: 1200,
|
||||
// width: 2400,
|
||||
fillScreen: true,
|
||||
// height: 1200,
|
||||
bg: "#333",
|
||||
},
|
||||
true,
|
||||
@ -35,11 +36,6 @@ img.src = "./pixel fire.gif";
|
||||
const p = new Vector();
|
||||
const gif = new GIFAnimation("./fire-joypixels.gif", p, .5);
|
||||
|
||||
doodler.createLayer((c, i, t) => {
|
||||
gif.draw(t);
|
||||
// c.drawImage(img, 0, 0);
|
||||
});
|
||||
|
||||
const spline = new SplineSegment([
|
||||
new Vector({ x: -25, y: -25 }).mult(10).add(p),
|
||||
new Vector({ x: 25, y: -25 }).mult(10).add(p),
|
||||
@ -53,7 +49,8 @@ const poly2 = Polygon.createPolygon(4);
|
||||
poly2.center = p.copy().add(100, 100);
|
||||
// poly.center.add(p);
|
||||
|
||||
doodler.createLayer((c) => {
|
||||
doodler.createLayer((c, i, t) => {
|
||||
gif.draw(t);
|
||||
// c.translate(1200, 600);
|
||||
for (let i = 0; i < c.canvas.width; i += 50) {
|
||||
for (let j = 0; j < c.canvas.height; j += 50) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Doodler, IDoodlerOptions } from "./canvas.ts";
|
||||
import { Doodler, DoodlerOptions } from "./canvas.ts";
|
||||
import { OriginVector, Point } from "./geometry/vector.ts";
|
||||
import { postInit } from "./postInit.ts";
|
||||
import { easeInOut } from "./timing/EaseInOut.ts";
|
||||
@ -29,7 +29,7 @@ export class ZoomableDoodler extends Doodler {
|
||||
|
||||
maxScale = 4;
|
||||
|
||||
constructor(options: IDoodlerOptions, postInit?: postInit) {
|
||||
constructor(options: DoodlerOptions, postInit?: postInit) {
|
||||
super(options, postInit);
|
||||
|
||||
this._canvas.addEventListener("wheel", (e) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user