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 +56 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +1 -0
- package/package.json +20 -0
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
|
+
[](https://www.typescriptlang.org/) [](package.json) [](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.
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|