{"_id":"@caetanoag/vectra","_rev":"2-9714205efd34cfa243bb9979ed2b3e8f","name":"@caetanoag/vectra","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@caetanoag/vectra","version":"0.1.0","author":{"name":"Caetanoag"},"license":"MIT","_id":"@caetanoag/vectra@0.1.0","maintainers":[{"name":"caetanoag","email":"caetanogoncalves@proton.me"}],"homepage":"https://github.com/caetanoag/Vectra#readme","bugs":{"url":"https://github.com/caetanoag/Vectra/issues"},"dist":{"shasum":"1529854810e1dacbfe70de32f504d427a152c939","tarball":"https://registry.npmjs.org/@caetanoag/vectra/-/vectra-0.1.0.tgz","fileCount":38,"integrity":"sha512-kUKn9Z70eSfh1MGaawsK3S1sreRzMifQkESqv8pegSrucAPwkmGV3cg1qkdqbdV1uxTnBHMZRYHYNaNSAklxkQ==","signatures":[{"sig":"MEYCIQDKtpycGy0DkApZp4KKeyDzDhyFEPublyDW0YQmrUOzDAIhAMiTSXmKEcxkjZsZgBE0QNPa1jPnvK5aSJknhZu2eZ9U","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":267682},"main":"lib/index.js","type":"module","types":"lib/index.d.ts","gitHead":"814a68138529e089543f21193be8c928a811b503","scripts":{"dev":"python3 -m http.server 3000","test":"vitest run","build":"tsc","clean":"rm -rf lib","commit":"tsc -p tsconfig.dev.json","test:watch":"vitest --watch","prepublishOnly":"npm run clean && npm run test && npm run build"},"_npmUser":{"name":"caetanoag","email":"caetanogoncalves@proton.me"},"repository":{"url":"git+https://github.com/caetanoag/Vectra.git","type":"git"},"_npmVersion":"12.0.2","description":"Biblioteca de programação gráfica com foco em matemática avançada e API intuitiva.","directories":{},"_nodeVersion":"26.8.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.11","@vitest/ui":"^4.1.11","typescript":"^7.0.2","@types/node":"^26.1.1"},"_npmOperationalInternal":{"tmp":"tmp/vectra_0.1.0_1788735064322_0.9314692726366383","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"_id":"@caetanoag/vectra@0.1.1","bugs":{"url":"https://github.com/caetanoag/Vectra/issues"},"dist":{"shasum":"f9444dbfda3e80d60fd9ba652609b657a29dc7f4","tarball":"https://registry.npmjs.org/@caetanoag/vectra/-/vectra-0.1.1.tgz","fileCount":38,"integrity":"sha512-To6FoH75nU58Bv/8nFluNLArISAe6ZJ/35bXuv5uPG05WD/iQ+jpSZqZ7eFOw0uFhBIhLTLSj3XZKgWg9vK5Pw==","signatures":[{"sig":"MEYCIQCBdLj97IBoeJNj4zWGQTrC513d1JBuNYgAsmnXOfQLjwIhAOSL+JgrP98Ttqri1iFT7kC33MYSizQg9fB9DRl66kZp","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBbWgqs4wdHs058bjpKc85LrNlAs67pXHd3pGkFsjxkfAiBjPWy1xRjHRf6MfHx2L+ASEmPKHaSNKUBdScDzygKRqQ=="}],"unpackedSize":271072},"main":"lib/index.js","name":"@caetanoag/vectra","type":"module","types":"lib/index.d.ts","author":{"name":"Caetanoag"},"gitHead":"f6e0ba2b576ebfa328c2d44cd95bc203943880ca","license":"MIT","scripts":{"dev":"python3 -m http.server 3000","test":"vitest run","build":"tsc","clean":"rm -rf lib","commit":"tsc -p tsconfig.dev.json","test:watch":"vitest --watch","prepublishOnly":"npm run clean && npm run test && npm run build"},"version":"0.1.1","_npmUser":{"name":"caetanoag","email":"caetanogoncalves@proton.me"},"homepage":"https://github.com/caetanoag/Vectra#readme","repository":{"url":"git+https://github.com/caetanoag/Vectra.git","type":"git"},"_npmVersion":"12.0.2","description":"Biblioteca de programação gráfica com foco em matemática avançada e API intuitiva.","directories":{},"maintainers":[{"name":"caetanoag","email":"caetanogoncalves@proton.me"}],"_nodeVersion":"26.8.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.11","@vitest/ui":"^4.1.11","typescript":"^7.0.2","@types/node":"^26.1.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vectra_0.1.1_1788735456385_0.7729365101832735"}}},"time":{"created":"2026-09-06T22:51:04.085Z","modified":"2026-09-06T22:57:36.630Z","0.1.0":"2026-09-06T22:51:04.456Z","0.1.1":"2026-09-06T22:57:36.482Z"},"bugs":{"url":"https://github.com/caetanoag/Vectra/issues"},"author":{"name":"Caetanoag"},"license":"MIT","homepage":"https://github.com/caetanoag/Vectra#readme","repository":{"url":"git+https://github.com/caetanoag/Vectra.git","type":"git"},"description":"Biblioteca de programação gráfica com foco em matemática avançada e API intuitiva.","maintainers":[{"name":"caetanoag","email":"caetanogoncalves@proton.me"}],"readme":"# Vectra – The HtmlCanvas Framework\n\nVectra is a lightweight 2D rendering and linear algebra library for the browser, built on top of the HTML Canvas API. It provides geometric primitives (`Vector2`, `Rect`, `Circle`), affine transformations (`Matrix3`, `Transform`), color manipulation (`Color`), user input handling (`InputManager`), and a renderer (`CanvasRenderer`) that abstracts the native Canvas context, allowing you to draw shapes, apply transformations, and manage scenes in a structured way.\n\n---\n\n## Import\n\n### Via CDN (jsDelivr)\n\n```javascript\nimport {\n  Vector2,\n  Rect,\n  Circle,\n  Color,\n  Matrix3,\n  Transform,\n  InputManager,\n  CanvasRenderer,\n} from \"https://cdn.jsdelivr.net/gh/caetanoag/Vectra/lib/index.js\";\n```\n\n### From local installation\n\nIf you clone the repository, you can import from the `lib/` folder — you only need that directory:\n\n```javascript\nimport {\n  Vector2,\n  Rect,\n  Circle,\n  Color,\n  Matrix3,\n  Transform,\n  InputManager,\n  CanvasRenderer,\n} from \"./lib/index.js\";\n```\n\n---\n\n## Installation\n\nVectra ships as a plain ES module — there are no runtime dependencies and no build step required.\n\n### From the repository\n\n```bash\ngit clone https://github.com/caetanoag/Vectra.git\ncd Vectra\n```\n\nThat clones the whole repository, but you only need the `lib/` directory. You can delete everything else. From the parent folder, first verify what will be removed:\n\n```bash\ncd ..\n# Prints everything that will be deleted; make sure it looks correct\nfind ./Vectra/ -mindepth 1 -path \"./Vectra/lib\" -prune -o -print\n```\n\nThen delete every file except `lib/`:\n\n```bash\n# Deletes everything in Vectra/, except the lib directory\nfind ./Vectra/ -mindepth 1 -path \"./Vectra/lib\" -prune -o -exec rm -rf {} +\n```\n\nNow import from `./Vectra/lib/index.js` (or copy the `lib/` folder into your project).\n\n> **Developers:** if you want to build from `src/`, run `yarn install && yarn build` — that generates the `lib/` folders with JavaScript files and TypeScript declarations.\n\n---\n\n## Minimal Example\n\n```javascript\nimport {\n  CanvasRenderer,\n  Circle,\n  Color,\n  Rect,\n  Vector2,\n} from \"https://cdn.jsdelivr.net/gh/caetanoag/Vectra/lib/index.js\";\n\nconst canvas = document.getElementById(\"canvas\");\nconst renderer = new CanvasRenderer(canvas);\nrenderer.setSize(800, 600);\n\n// Background\nrenderer.clear();\nrenderer.fillRect(new Rect(0, 0, 800, 600), Color.fromHex(\"#2c3e50\"));\n\n// Rectangle\nconst rect = new Rect(50, 50, 200, 100);\nrenderer.fillRect(rect, Color.fromRgb(52, 152, 219));\nrenderer.strokeRect(rect, Color.white(), 2);\n\n// Circle\nconst circle = new Circle(new Vector2(400, 200), 80);\nrenderer.fillCircle(circle, Color.fromRgb(231, 76, 60));\n```\n\n---\n\n## API Overview\n\n### Vector2\n\nImmutable 2D vector — all operations return new instances.\n\n- `new Vector2(x, y)` — `x` and `y` must be finite\n- `static zero` / `static one` / `static right` / `static up` — `Vector2` constants\n- `add(v): Vector2` / `subtract(v): Vector2`\n- `translate(dx, dy): Vector2` – adds a displacement\n- `scale(factor): Vector2` – multiplies by a scalar\n- `negate(): Vector2`\n- `truncate(): Vector2`\n- `clamp(min, max): Vector2` – clamps components to a box\n- `clampLength(min, max): Vector2` – clamps the magnitude (direction preserved)\n- `hadamar(v): Vector2` – component-wise (Hadamard) product\n- `dot(v): number` / `cross(v): number`\n- `lerp(v, t): Vector2` – linear interpolation, `t` in `[0, 1]`\n- `rotate(angle): Vector2` – counter-clockwise rotation (radians)\n- `distanceTo(v): number`\n- `length: number` (getter) / `lengthSq: number` (getter) – squared length for fast comparisons\n- `angle: number` (getter) – direction in radians\n- `getAngle(v): number` – angle from this vector to another\n- `angleTo(v): number` – signed angle in `[-π, π]`\n- `normalized(): Vector2`\n- `withLength(newLength): Vector2`\n- `withX(newX): Vector2` / `withY(newY): Vector2`\n- `equals(v, epsilon?): boolean` – tolerance-based comparison\n- `clone(): Vector2`\n- `toString(): string`\n- `static fromAngle(radians): Vector2` – unit vector from an angle\n- `static fromPolar(angle, length?): Vector2` – from polar coordinates\n\n### Rect\n\nAxis-aligned rectangle (AABB). Most methods mutate the instance and return `this` for chaining.\n\n- `new Rect(x, y, width, height)` — validates and normalizes (negative width/height are corrected automatically)\n- `setWidth(w): this` / `setHeight(h): this`\n- `moveTo(x, y): this` / `setPosition(v): this` / `setSize(v): this`\n- `translate(dx, dy): this` / `resize(dx, dy): this`\n- `inflate(dx, dy): this` – expands in all directions while keeping the center fixed\n- `scale(sx, sy): this` – scales from the top-left corner\n- `scaleFromCenter(sx, sy): this` – scales keeping the center fixed\n- `round(): this`\n- `contains(point: Vector2): boolean`\n- `containsBox(box: Rect): boolean`\n- `intersects(box: Rect): boolean`\n- `union(box: Rect): Rect` / `intersection(box: Rect): Rect | undefined`\n- `clampPoint(point: Vector2): Vector2` – clamps a point into the rectangle\n- `distanceToPoint(point: Vector2): number` / `distanceSquaredToPoint(point: Vector2): number`\n- `isEmpty(): boolean`\n- `equals(box: Rect): boolean`\n- `clone(): Rect`\n- `getWidth(): number` / `getHeight(): number`\n- `left, right, top, bottom` – getters (numbers)\n- `position, center, size` – getters (`Vector2`)\n- `area` – getter (number)\n- `aspectRatio` – getter (number)\n- `static fromCenter(center, size): Rect` / `static fromCorners(a, b): Rect`\n- `static generateRandomInside(boundary, minWidth?, minHeight?): Rect`\n\n### Circle\n\nCircle defined by a center point and a finite, non-negative radius. `center` and `radius` are public; mutators return `this` for chaining.\n\n- `new Circle(center: Vector2, radius)` — `radius` must be finite and `≥ 0`\n- `setRadius(r): this` / `setCenter(v): this`\n- `translate(dx, dy): this` / `scale(factor): this`\n- `area` – getter (`πr²`)\n- `circumference` – getter (`2πr`)\n- `diameter` – getter (`2r`)\n- `radiusSquared` – getter (`r²`)\n- `boundingBox: Rect` – getter, axis-aligned box that encloses the circle\n- `string: string` – getter, equivalent to `toString()`\n- `equationString: string` – getter, Cartesian equation `(x − h)² + (y − k)² = r²`\n- `containsPoint(point: Vector2, epsilon?): boolean` – inside or on the boundary\n- `isPointOnCircumference(point: Vector2, epsilon?): boolean`\n- `distanceTo(v: Vector2 | Circle): number` – distance between centers\n- `pointAt(angle): Vector2` – point on the circumference at an angle (radians)\n- `intersects(other: Circle, epsilon?): boolean` – overlap or touch\n- `containsCircle(other: Circle, epsilon?): boolean`\n- `containsBox(box: Rect, epsilon?): boolean`\n- `equals(other: Circle, epsilon?): boolean`\n- `clone(): Circle`\n- `withCenter(v): Circle` / `withRadius(r): Circle` – immutable variants\n- `toString(): string`\n\n### Color\n\nImmutable color with channels normalized to `[0, 1]`.\n\n- `new Color(r, g, b, a?)`\n- `static fromHex(hex: string): Color` – supports `#RGB`, `#RGBA`, `#RRGGBB`, `#RRGGBBAA`\n- `static fromRgb(r, g, b, a?): Color` – channels in `0-255`\n- `static fromHsl(h, s, l): Color` – hue in degrees, saturation/lightness in `0-1`\n- `hex: string` – `#RRGGBB` or `#RRGGBBAA`\n- `rgb: string` – CSS `rgb(...)`\n- `rgba: string` – CSS `rgba(...)`\n- `toArray: [number, number, number, number | undefined]`\n- `brightness: number` – approximate luminance\n- `hsl: { hue, saturation, lightness }` – HSL representation\n- `lerp(other, t): Color`\n- `withAlpha(alpha): Color`\n- `darken(amount): Color` / `lighten(amount): Color` – in HSL space\n- `clone(): Color`\n- `equals(other, epsilon?): boolean`\n- `static white() / black() / red() / green() / blue() / transparent(): Color`\n\n### Matrix3\n\n3x3 matrix for 2D affine transformations. Immutable — all operations return new instances. Row-major storage.\n\n- `new Matrix3(m00, m01, m02, m10, m11, m12, m20, m21, m22)`\n- `static identity(): Matrix3`\n- `static translation(tx, ty): Matrix3`\n- `static rotation(angle, center?): Matrix3` – optional `center`, defaults to the origin\n- `static scaling(sx, sy?): Matrix3` – optional `sy` (uniform scaling if omitted)\n- `multiply(other): Matrix3`\n- `translate(dx, dy): Matrix3` / `rotate(angle): Matrix3` / `scale(sx, sy?): Matrix3`\n- `applyToVector(v): Vector2`\n- `applyToDirection(v): Vector2` – ignores translation\n- `toCanvasTransform(): [a, b, c, d, e, f]` – format used by `CanvasRenderingContext2D.setTransform`\n- `invert(): Matrix3 | null`\n- `equals(other, epsilon?): boolean`\n- `clone(): Matrix3`\n- `toArray(): number[]`\n- `toString(): string`\n\n### Transform\n\nRepresents 2D position, rotation, and scale, with support for hierarchies via `parent`. Mutable — methods mutate the instance and return `this`.\n\n- `new Transform(position?, rotation?, scale?)` – defaults: `(0,0)`, `0`, `(1,1)`\n- `setPosition(v): this` / `setRotation(angle): this` / `setScale(v): this`\n- `translate(dx, dy): this`\n- `rotate(angle): this` – adds to the current rotation\n- `scaleBy(sx, sy): this` – multiplies the current scale\n- `lookAt(target): this` – rotates to face a point\n- `getMatrix(): Matrix3` – local matrix (order: scale → rotation → translation)\n- `parent: Transform | null` (getter) / `setParent(parent): void`\n- `getWorldMatrix(): Matrix3` – combines with the parent chain\n\n### InputManager\n\nManages keyboard, mouse, and touch input. `update()` must be called once per frame to clear \"pressed\" states.\n\n- `new InputManager(target: HTMLElement | Window)` – `target` receives mouse/touch events; keyboard events are always attached to `window`\n- `isKeyDown(key): boolean`\n- `isKeyPressed(key): boolean` – one-shot event, true only on the frame the key was pressed\n- `isMouseDown(button?): boolean` – `0` left, `1` middle, `2` right\n- `getMousePosition(): Vector2` – relative to the target element\n- `isMouseOver(): boolean`\n- `update(): void` – must be called once per frame, before checking inputs\n\n### CanvasRenderer\n\nWraps the HTML Canvas 2D context, providing a higher-level API for shapes, transforms, text, and state management.\n\n- `new CanvasRenderer(canvas: HTMLCanvasElement)`\n- `width, height` – getters\n- `boundingRect: Rect` – getter for `Rect(0, 0, width, height)`\n- `context: CanvasRenderingContext2D` – getter for the raw context (use cautiously)\n- `setSize(width, height): void`\n- `clear(rect?): void` – clears the whole canvas, or only the given region\n\n**Shapes**\n\n- `fillRect(rect, color): void`\n- `strokeRect(rect, color, lineWidth?): void`\n- `fillCircle(circle: Circle, color): void` – or `fillCircle(center: Vector2, radius, color)`\n- `strokeCircle(circle: Circle, color, lineWidth?): void` – or `strokeCircle(center: Vector2, radius, color, lineWidth?)`\n- `fillPolygon(points, color): void`\n- `strokePolygon(points, color, lineWidth?): void`\n- `drawLine(from, to, color, lineWidth?): void`\n\n**Transforms**\n\n- `translate(dx, dy): void` / `rotate(angle): void` / `scale(sx, sy): void` – apply directly to the canvas context\n- `save(): void` / `restore(): void`\n- `resetTransform(): void` – resets to identity\n- `applyMatrix(matrix: Matrix3): void` – multiplies the current transform by a `Matrix3`\n- `applyTransform(transform: Transform): void` – multiplies by a `Transform`'s world matrix\n- `setTransform(transform: Transform): void` – sets the current transform from a `Transform`'s world matrix\n\n**Text**\n\n- `fillText(text, position, color, options?): void`\n- `strokeText(text, position, color, options?): void`\n- `measureText(text, options?): TextMetrics`\n\nText options (`TextOptions`):\n\n| Field          | Default        | Description                                   |\n| -------------- | -------------- | ---------------------------------------------- |\n| `fontFamily`   | `'sans-serif'` | Font family                                     |\n| `fontSize`     | `16`           | Size in pixels                                  |\n| `fontStyle`    | `'normal'`     | `'normal'`, `'italic'`, or `'oblique'`          |\n| `fontWeight`   | `'normal'`     | Font weight                                     |\n| `textAlign`    | `'start'`      | Text alignment (`CanvasTextAlign`)              |\n| `textBaseline` | `'alphabetic'` | Text baseline (`CanvasTextBaseline`)            |\n| `maxWidth`     | —              | Maximum rendering width                         |\n\n---\n\n## Running Examples\n\nThe examples live in `docs/examples/` and need no build step — each page loads its own `main.js` directly. To browse them, serve the repository root with a local server:\n\n```bash\nyarn dev\n```\n\nwhich serves the current directory with python3 (if installed). Then open [http://localhost:3000/docs/examples/](http://localhost:3000/docs/examples/) in a browser. The examples hub is also linked from the navigation sidebar of the documentation.\n\n---","readmeFilename":"README.md"}