UNPKG

@litecanvas/utils

Version:

Utilities to help build litecanvas games

266 lines (260 loc) 6.77 kB
(() => { var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // src/vector/index.js var index_exports = {}; __export(index_exports, { DOWN: () => DOWN, LEFT: () => LEFT, ONE: () => ONE, RIGHT: () => RIGHT, UP: () => UP, Vector: () => Vector, ZERO: () => ZERO, vec: () => vec, vecAbs: () => vecAbs, vecAdd: () => vecAdd, vecAngle: () => vecAngle, vecAngleBetween: () => vecAngleBetween, vecCeil: () => vecCeil, vecClamp: () => vecClamp, vecCross: () => vecCross, vecDist: () => vecDist, vecDist2: () => vecDist2, vecDiv: () => vecDiv, vecDot: () => vecDot, vecEq: () => vecEq, vecFloor: () => vecFloor, vecHeading: () => vecHeading, vecIsZero: () => vecIsZero, vecLerp: () => vecLerp, vecLimit: () => vecLimit, vecMag: () => vecMag, vecMag2: () => vecMag2, vecMove: () => vecMove, vecMult: () => vecMult, vecNorm: () => vecNorm, vecRand: () => vecRand, vecReflect: () => vecReflect, vecRem: () => vecRem, vecRotate: () => vecRotate, vecRound: () => vecRound, vecSet: () => vecSet, vecSetMag: () => vecSetMag, vecSub: () => vecSub, vecToArray: () => vecToArray }); // src/debug/assert.js var assert_default = (condition, message = "Assertion failed") => { if (!condition) throw new Error(message); }; // src/math/clamp.js var clamp_default = (value, min, max) => { DEV: assert_default( Number.isFinite(value), "[litecanvas/utils] clamp() 1st param must be a number" ); DEV: assert_default( Number.isFinite(min), "[litecanvas/utils] clamp() 2nd param must be a number" ); DEV: assert_default( Number.isFinite(max), "[litecanvas/utils] clamp() 3rd param must be a number" ); DEV: assert_default( max >= min, "[litecanvas/utils] clamp() the 2nd param must be less than the 3rd param" ); if (value < min) return min; if (value > max) return max; return value; }; // src/vector/index.js var cos = Math.cos; var sin = Math.sin; var PI2 = 2 * Math.PI; var float = parseFloat; var V = class { /** * @param {number} [x=0] * @param {number} [y] */ constructor(x = 0, y = x) { this.x = float(x) || 0; this.y = float(y) || 0; } /** * @returns {string} */ toString() { return `Vector (${this.x}, ${this.y})`; } }; var Vector = V; var isVector = (v) => v instanceof V; var vec = (x = 0, y = x) => { if (isVector(x)) { y = x.y; x = x.x; } return new V(x, y); }; var vecSet = (v, x, y = x) => { if (isVector(x)) { vecSet(v, x.x, x.y); } else { v.x = x; v.y = y; } return v; }; var vecAdd = (v, x, y = x) => { if (isVector(x)) { return vecAdd(v, x.x, x.y); } v.x += x; v.y += y; return v; }; var vecSub = (v, x, y = x) => { if (isVector(x)) { return vecSub(v, x.x, x.y); } v.x -= x; v.y -= y; return v; }; var vecMult = (v, x, y = x) => { if (isVector(x)) { return vecMult(v, x.x, x.y); } v.x *= x; v.y *= y; return v; }; var vecDiv = (v, x, y = x) => { if (isVector(x)) { return vecDiv(v, x.x, x.y); } v.x /= x || 1; v.y /= y || 1; return v; }; var vecRotate = (v, radians) => { const c = cos(radians), s = sin(radians); v.x = c * v.x - s * v.y; v.y = s * v.x + c * v.y; return v; }; var vecReflect = (v, normal) => { const normalCopy = vecNorm(vec(normal)); return vecSub(v, vecMult(normalCopy, 2 * vecDot(v, normalCopy))); }; var vecSetMag = (v, value) => vecMult(vecNorm(v), value); var vecMag = (v) => Math.hypot(v.x, v.y); var vecMag2 = (v) => v.x * v.x + v.y * v.y; var vecNorm = (v) => { const length = vecMag(v); if (length > 0) { vecDiv(v, length); } return v; }; var vecLimit = (v, max = 1) => { const sq = vecMag2(v); if (sq > max * max) { vecSetMag(v, max); } return v; }; var vecDist = (a, b) => { return Math.hypot(b.x - a.x, b.y - a.y); }; var vecDist2 = (a, b) => { const dx = a.x - b.x; const dy = a.y - b.y; return dx * dx + dy * dy; }; var vecHeading = (v) => Math.atan2(v.y, v.x); var vecAngle = (v) => vecHeading(v); var vecDot = (a, b) => a.x * b.x + a.y * b.y; var vecAngleBetween = (v1, v2) => { const mag1 = vecMag(v1); const mag2 = vecMag(v2); return mag2 - mag1 ? Math.acos(clamp_default(vecDot(v1, v2) / (mag1 * mag2), -1, 1)) : 0; }; var vecCross = (a, b) => a.x * b.y - a.y * b.x; var vecLerp = (a, b, t) => { a.x += (b.x - a.x) * t || 0; a.y += (b.y - a.y) * t || 0; return a; }; var vecAbs = (v) => { v.x = Math.abs(v.x); v.y = Math.abs(v.y); return v; }; var vecCeil = (v) => { v.x = Math.ceil(v.x); v.y = Math.ceil(v.y); return v; }; var vecFloor = (v) => { v.x = Math.floor(v.x); v.y = Math.floor(v.y); return v; }; var vecRound = (v) => { v.x = Math.round(v.x); v.y = Math.round(v.y); return v; }; var vecClamp = (v, min, max) => { return vecSet(v, clamp_default(v.x, min, max), clamp_default(v.y, min, max)); }; var vecRem = (v, value) => { v.x %= value; v.y %= value; return v; }; var vecMove = (from, to, step = 1) => { const dx = to.x - from.x; const dy = to.y - from.y; const distance = Math.hypot(dx, dy); step = Math.abs(step); if (distance <= step || distance === 0) { from.x = to.x; from.y = to.y; } else { const ratio = step / distance; from.x = from.x + dx * ratio; from.y = from.y + dy * ratio; } return from; }; var vecEq = (v, x, y = x, epsilon = 1e-5) => { if (isVector(x)) { return vecEq(v, x.x, x.y, epsilon); } return vecDist(v, x, y) <= epsilon; }; var vecIsZero = (v) => vecEq(v, ZERO); var vecToArray = (v) => [v.x, v.y]; var vecRand = (minlength = 1, maxlength = minlength, rng = globalThis.rand || Math.random) => { const angle = rng() * PI2; const radius = rng() * (maxlength - minlength) + minlength; return vec(cos(angle) * radius, sin(angle) * radius); }; var ZERO = /* @__PURE__ */ vec(0, 0); var ONE = /* @__PURE__ */ vec(1, 1); var UP = /* @__PURE__ */ vec(0, -1); var RIGHT = /* @__PURE__ */ vec(1, 0); var DOWN = /* @__PURE__ */ vec(0, 1); var LEFT = /* @__PURE__ */ vec(-1, 0); // src/vector/_web.js globalThis.utils = Object.assign(globalThis.utils || {}, index_exports); })();