canvasbridge 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ <div align="center">
2
+
3
+ # Canvasbridge
4
+
5
+ ### Small adapters for rendering Artboards visual documents with Canvas 2D.
6
+
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![Module](https://img.shields.io/badge/module-ESM-f7df1e?logo=javascript&logoColor=111827)](package.json) [![Status](https://img.shields.io/badge/status-pre--alpha-f5a623)](https://artboards.dev)
8
+
9
+ [artboards.dev](https://artboards.dev)
10
+
11
+ </div>
12
+
13
+ `canvasbridge` is a small, framework-neutral Canvas 2D target for the portable
14
+ visual document primitives exported by `artboards`. The same document can be
15
+ sent to another renderer such as `svgbridge`.
16
+
17
+ ## Install
18
+
19
+ ```sh
20
+ npm i artboards canvasbridge
21
+ ```
22
+
23
+ ```ts
24
+ import { renderCanvas } from "canvasbridge";
25
+
26
+ renderCanvas(ctx, {
27
+ width: 320,
28
+ height: 180,
29
+ children: [
30
+ { type: "rect", x: 10, y: 10, width: 100, height: 80, fill: "#09f" },
31
+ ],
32
+ });
33
+ ```
34
+
35
+ ## Architecture
36
+
37
+ ```text
38
+ artboards.dev
39
+
40
+
41
+ artboards
42
+ portable visual model
43
+
44
+
45
+ canvasbridge
46
+
47
+
48
+ Canvas 2D
49
+ ```
50
+
51
+ Supported basics are groups, rectangles, ellipses, lines, portable path
52
+ commands, text, image references, transforms, fill/stroke, opacity, and
53
+ document sizing. Canvas state is scoped per node, so transforms and styles do
54
+ not leak between siblings. Advanced text shaping, gradients, clipping, masks,
55
+ asset fetching, layout, and application UI are out of scope until Artboards
56
+ defines portable equivalents.
@@ -0,0 +1,29 @@
1
+ import type { PathCommand, Transform, VisualDocument, VisualNode } from "artboards";
2
+ export type CanvasNode = VisualNode;
3
+ export type CanvasDocument = VisualDocument;
4
+ export interface CanvasRenderOptions {
5
+ readonly clear?: boolean;
6
+ /** Resolves caller-owned image data; this bridge never loads network assets. */
7
+ readonly resolveImage?: (href: string, node: CanvasNode) => CanvasImageSource | undefined;
8
+ }
9
+ /** Applies the portable transform in the same order used by SVG output. */
10
+ export declare function applyTransform(ctx: CanvasRenderingContext2D, transform: Transform | undefined): void;
11
+ /** Draws the shared portable path commands on the current Canvas path. */
12
+ export declare function drawPath(ctx: CanvasRenderingContext2D, commands?: readonly PathCommand[]): void;
13
+ /** Draws one node with a state scope that cannot leak into siblings. */
14
+ export declare function drawNode(ctx: CanvasRenderingContext2D, node: CanvasNode, options?: CanvasRenderOptions): void;
15
+ /** Renders a document and keeps all bridge-owned Canvas state scoped. */
16
+ export declare function renderCanvas(ctx: CanvasRenderingContext2D, document: CanvasDocument, options?: CanvasRenderOptions): void;
17
+ /** Sizes a canvas backing store without taking responsibility for page layout. */
18
+ export declare function setupCanvas(canvas: {
19
+ width: number;
20
+ height: number;
21
+ style?: {
22
+ width: string;
23
+ height: string;
24
+ };
25
+ }, options: {
26
+ readonly width: number;
27
+ readonly height: number;
28
+ readonly pixelRatio?: number;
29
+ }): number;
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ function h(i,e){e&&(e.matrix&&i.transform(...e.matrix),e.translate&&i.translate(e.translate.x,e.translate.y),e.origin&&i.translate(e.origin.x,e.origin.y),e.rotate!==void 0&&i.rotate(e.rotate),e.scale&&i.scale(e.scale.x,e.scale.y),e.origin&&i.translate(-e.origin.x,-e.origin.y))}function f(i,e=[]){for(const a of e)switch(a.type){case"moveTo":i.moveTo(a.x,a.y);break;case"lineTo":i.lineTo(a.x,a.y);break;case"quadraticCurveTo":i.quadraticCurveTo(a.cpx,a.cpy,a.x,a.y);break;case"bezierCurveTo":i.bezierCurveTo(a.cp1x,a.cp1y,a.cp2x,a.cp2y,a.x,a.y);break;case"arc":i.arc(a.x,a.y,a.radius,a.startAngle,a.endAngle,a.counterclockwise);break;case"closePath":i.closePath();break}}function s(i,e){e.fill!==void 0&&(i.fillStyle=e.fill),e.stroke!==void 0&&(i.strokeStyle=e.stroke),e.strokeWidth!==void 0&&(i.lineWidth=e.strokeWidth)}function l(i,e){e.fill!==void 0&&i.fill(),e.stroke!==void 0&&i.stroke()}function t(i,e,a={}){switch(i.save(),h(i,e.transform),e.opacity!==void 0&&(i.globalAlpha*=e.opacity),s(i,e),e.type){case"group":for(const r of e.children??[])t(i,r,a);break;case"rect":i.beginPath(),i.rect(e.x??0,e.y??0,e.width??0,e.height??0),l(i,e);break;case"ellipse":i.beginPath(),i.ellipse(e.cx??0,e.cy??0,e.rx??0,e.ry??0,0,0,Math.PI*2),l(i,e);break;case"line":i.beginPath(),i.moveTo(e.x1??0,e.y1??0),i.lineTo(e.x2??0,e.y2??0),e.stroke!==void 0&&i.stroke();break;case"path":i.beginPath(),f(i,e.path),l(i,e);break;case"text":e.fill!==void 0&&i.fillText(e.text??"",e.x??0,e.y??0),e.stroke!==void 0&&i.strokeText(e.text??"",e.x??0,e.y??0);break;case"image":{const r=e.href&&a.resolveImage?.(e.href,e);r&&i.drawImage(r,e.x??0,e.y??0,e.width??0,e.height??0);break}}i.restore()}function y(i,e,a={}){a.clear!==!1&&i.clearRect(0,0,e.width,e.height),i.save(),e.background!==void 0&&(i.fillStyle=e.background,i.fillRect(0,0,e.width,e.height));for(const r of e.children??[])t(i,r,a);i.restore()}function g(i,e){const a=e.pixelRatio??1;return i.width=Math.round(e.width*a),i.height=Math.round(e.height*a),i.style&&(i.style.width=`${e.width}px`,i.style.height=`${e.height}px`),a}export{h as applyTransform,t as drawNode,f as drawPath,y as renderCanvas,g as setupCanvas};
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "canvasbridge",
3
+ "version": "0.1.0",
4
+ "description": "Small adapters for rendering Artboards visual documents with Canvas 2D.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "default": "./dist/index.js" } },
9
+ "files": ["dist", "README.md"],
10
+ "sideEffects": false,
11
+ "scripts": { "build": "tsc --project tsconfig.json", "postbuild": "npm run dist --prefix \"$npm_config_local_prefix\" -- \"$PWD\"", "prepack": "npm run build", "prepublishOnly": "npm run build", "pretest": "npm run build", "test": "node --test test/*.test.mjs" },
12
+ "keywords": ["artboards", "canvas", "canvas2d", "renderer"],
13
+ "homepage": "https://artboards.dev",
14
+ "repository": { "type": "git", "url": "git+https://github.com/mosanic/mosa-platform.git", "directory": "packages/canvasbridge" },
15
+ "license": "MIT",
16
+ "engines": { "node": ">=20" },
17
+ "publishConfig": { "access": "public" },
18
+ "dependencies": { "artboards": "^0.0.1" },
19
+ "devDependencies": { "typescript": "^5.9.3" }
20
+ }