@shotstack/shotstack-canvas 2.0.15 → 2.0.16

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 CHANGED
@@ -1,13 +1,72 @@
1
- # @shotstack/shotstack-canvas
2
-
3
- One package identical text shaping/wrapping/animation on Web & Node.
4
- - HarfBuzz WASM for shaping and glyph outlines (via `harfbuzzjs`).
5
- - Device-independent draw-ops.
6
- - Painters: Canvas2D (web) and node-canvas (node).
7
- - Deterministic time-driven animations.
8
-
9
- ## Install
10
-
11
- ```bash
12
- pnpm add @shotstack/shotstack-canvas
13
- # or npm i / yarn add
1
+ # @shotstack/shotstack-canvas
2
+
3
+ Text layout and animation engine using HarfBuzz WASM. Identical rendering on Node.js and Web.
4
+
5
+ ## Features
6
+
7
+ - HarfBuzz WASM text shaping with glyph outlines
8
+ - Cross-platform DrawOp abstraction (Canvas2D for web, @napi-rs/canvas for Node.js)
9
+ - Rich text with fonts, stroke, shadow, gradients, backgrounds, and borders
10
+ - SVG asset rendering (11 shape types + SVG markup import)
11
+ - Rich caption support with word-level timing and 8 animation styles
12
+ - Video generation (H.264 MP4 via FFmpeg on Node.js, WebCodecs in browser)
13
+ - RTL and bidirectional text support
14
+ - Custom font registration (file, URL, or ArrayBuffer)
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ pnpm add @shotstack/shotstack-canvas
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### Node.js
25
+
26
+ ```js
27
+ import { createTextEngine } from "@shotstack/shotstack-canvas";
28
+
29
+ const engine = await createTextEngine({ width: 800, height: 400 });
30
+
31
+ const asset = engine.validate({
32
+ type: "rich-text",
33
+ text: "Hello World",
34
+ font: { family: "Open Sans", size: 48, color: "#ffffff" },
35
+ });
36
+
37
+ const drawOps = await engine.renderFrame(asset.value, 0);
38
+ const renderer = await engine.createRenderer({ width: 800, height: 400 });
39
+ const buffer = renderer.paint(drawOps);
40
+ ```
41
+
42
+ ### Web
43
+
44
+ ```js
45
+ import { createTextEngine } from "@shotstack/shotstack-canvas";
46
+
47
+ const engine = await createTextEngine({ width: 800, height: 400 });
48
+ const asset = engine.validate({ type: "rich-text", text: "Hello World" });
49
+ const drawOps = await engine.renderFrame(asset.value, 0);
50
+ const renderer = engine.createRenderer(canvas);
51
+ renderer.paint(drawOps);
52
+ ```
53
+
54
+ ## Development
55
+
56
+ ```bash
57
+ pnpm install
58
+ pnpm build
59
+ pnpm test
60
+ ```
61
+
62
+ ## Release
63
+
64
+ Releases are automated via [semantic-release](https://github.com/semantic-release/semantic-release). Pushing to `main` with Conventional Commit messages triggers a release:
65
+
66
+ - `fix: ...` — patch release (e.g., 2.0.15 → 2.0.16)
67
+ - `feat: ...` — minor release (e.g., 2.0.15 → 2.1.0)
68
+ - `feat!: ...` or `BREAKING CHANGE:` — major release (e.g., 2.0.15 → 3.0.0)
69
+
70
+ ## License
71
+
72
+ MIT
package/package.json CHANGED
@@ -1,66 +1,78 @@
1
- {
2
- "name": "@shotstack/shotstack-canvas",
3
- "version": "2.0.15",
4
- "description": "Text layout & animation engine (HarfBuzz) for Node & Web - fully self-contained.",
5
- "type": "module",
6
- "main": "./dist/entry.node.cjs",
7
- "module": "./dist/entry.node.js",
8
- "browser": "./dist/entry.web.js",
9
- "types": "./dist/entry.node.d.ts",
10
- "exports": {
11
- ".": {
12
- "node": {
13
- "import": "./dist/entry.node.js",
14
- "require": "./dist/entry.node.cjs"
15
- },
16
- "browser": "./dist/entry.web.js",
17
- "default": "./dist/entry.web.js"
18
- }
19
- },
20
- "files": [
21
- "dist/**",
22
- "scripts/postinstall.js",
23
- "README.md",
24
- "LICENSE"
25
- ],
26
- "scripts": {
27
- "dev": "tsup --watch",
28
- "build": "tsup",
29
- "postinstall": "node scripts/postinstall.js",
30
- "vendor:harfbuzz": "node scripts/vendor-harfbuzz.js",
31
- "example:node": "node examples/node-example.mjs",
32
- "example:video": "node examples/node-video.mjs",
33
- "example:web": "vite dev examples/web-example",
34
- "test:caption-web": "vite dev examples/caption-tests",
35
- "prepublishOnly": "npm run build"
36
- },
37
- "publishConfig": {
38
- "access": "public",
39
- "registry": "https://registry.npmjs.org/"
40
- },
41
- "engines": {
42
- "node": ">=18"
43
- },
44
- "sideEffects": false,
45
- "dependencies": {
46
- "@resvg/resvg-js": "^2.6.2",
47
- "@resvg/resvg-wasm": "^2.6.2",
48
- "bidi-js": "^1.0.3",
49
- "@shotstack/schemas": "1.8.7",
50
- "canvas": "npm:@napi-rs/canvas@^0.1.54",
51
- "ffmpeg-static": "^5.2.0",
52
- "fontkit": "^2.0.4",
53
- "harfbuzzjs": "0.4.12",
54
- "lru-cache": "^11.2.5",
55
- "mp4-muxer": "^5.1.3",
56
- "zod": "^4.2.0"
57
- },
58
- "devDependencies": {
59
- "@types/node": "^20.14.10",
60
- "tsup": "^8.2.3",
61
- "typescript": "^5.5.3",
62
- "vite": "^5.3.3",
63
- "vite-plugin-top-level-await": "1.6.0",
64
- "vite-plugin-wasm": "3.5.0"
65
- }
66
- }
1
+ {
2
+ "name": "@shotstack/shotstack-canvas",
3
+ "version": "2.0.16",
4
+ "description": "Text layout & animation engine (HarfBuzz) for Node & Web - fully self-contained.",
5
+ "type": "module",
6
+ "main": "./dist/entry.node.cjs",
7
+ "module": "./dist/entry.node.js",
8
+ "browser": "./dist/entry.web.js",
9
+ "types": "./dist/entry.node.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "node": {
13
+ "import": "./dist/entry.node.js",
14
+ "require": "./dist/entry.node.cjs"
15
+ },
16
+ "browser": "./dist/entry.web.js",
17
+ "default": "./dist/entry.web.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist/**",
22
+ "scripts/postinstall.js",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "scripts": {
27
+ "dev": "tsup --watch",
28
+ "build": "tsup",
29
+ "postinstall": "node scripts/postinstall.js",
30
+ "vendor:harfbuzz": "node scripts/vendor-harfbuzz.js",
31
+ "example:node": "node examples/node-example.mjs",
32
+ "example:video": "node examples/node-video.mjs",
33
+ "example:web": "vite dev examples/web-example",
34
+ "test:caption-web": "vite dev examples/caption-tests",
35
+ "prepublishOnly": "node scripts/publish-guard.cjs && pnpm build",
36
+ "test": "node --test tests/build-verify.mjs"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public",
40
+ "registry": "https://registry.npmjs.org/"
41
+ },
42
+ "engines": {
43
+ "node": ">=18"
44
+ },
45
+ "sideEffects": false,
46
+ "dependencies": {
47
+ "@resvg/resvg-js": "^2.6.2",
48
+ "@resvg/resvg-wasm": "^2.6.2",
49
+ "@shotstack/schemas": "1.8.7",
50
+ "bidi-js": "^1.0.3",
51
+ "canvas": "npm:@napi-rs/canvas@^0.1.54",
52
+ "ffmpeg-static": "^5.2.0",
53
+ "fontkit": "^2.0.4",
54
+ "harfbuzzjs": "0.4.12",
55
+ "lru-cache": "^11.2.5",
56
+ "mp4-muxer": "^5.1.3",
57
+ "zod": "^4.2.0"
58
+ },
59
+ "devDependencies": {
60
+ "@semantic-release/changelog": "^6.0.3",
61
+ "@semantic-release/commit-analyzer": "^13.0.1",
62
+ "@semantic-release/git": "^10.0.1",
63
+ "@semantic-release/github": "^12.0.6",
64
+ "@semantic-release/npm": "^13.1.5",
65
+ "@semantic-release/release-notes-generator": "^14.1.0",
66
+ "@types/node": "^20.14.10",
67
+ "semantic-release": "^25.0.3",
68
+ "tsup": "^8.2.3",
69
+ "typescript": "^5.5.3",
70
+ "vite": "^5.3.3",
71
+ "vite-plugin-top-level-await": "1.6.0",
72
+ "vite-plugin-wasm": "3.5.0"
73
+ },
74
+ "repository": {
75
+ "type": "git",
76
+ "url": "https://github.com/shotstack/shotstack-canvas.git"
77
+ }
78
+ }
@@ -1,58 +1,58 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Postinstall script to verify native canvas bindings are available
5
- * This helps catch issues early and provides helpful guidance
6
- */
7
-
8
- import { platform as _platform, arch as _arch } from 'os';
9
- import { dirname } from 'path';
10
- import { readdirSync } from 'fs';
11
- import { createRequire } from 'module';
12
-
13
- const require = createRequire(import.meta.url);
14
-
15
- const platform = _platform();
16
- const arch = _arch();
17
-
18
- // Map platform/arch to package names
19
- const platformMap = {
20
- 'darwin-arm64': '@napi-rs/canvas-darwin-arm64',
21
- 'darwin-x64': '@napi-rs/canvas-darwin-x64',
22
- 'linux-arm64': '@napi-rs/canvas-linux-arm64-gnu',
23
- 'linux-x64': '@napi-rs/canvas-linux-x64-gnu',
24
- 'win32-x64': '@napi-rs/canvas-win32-x64-msvc',
25
- 'linux-arm': '@napi-rs/canvas-linux-arm-gnueabihf',
26
- 'android-arm64': '@napi-rs/canvas-android-arm64',
27
- };
28
-
29
- const platformKey = `${platform}-${arch}`;
30
- const requiredPackage = platformMap[platformKey];
31
-
32
- if (!requiredPackage) {
33
- console.warn(`\n⚠️ Warning: Unsupported platform ${platformKey} for @napi-rs/canvas`);
34
- console.warn(' Canvas rendering may not work on this platform.\n');
35
- process.exit(0);
36
- }
37
-
38
- // Check if the native binding package is installed
39
- try {
40
- const packagePath = require.resolve(`${requiredPackage}/package.json`);
41
- const packageDir = dirname(packagePath);
42
-
43
- // Verify the .node file exists
44
- const nodeFiles = readdirSync(packageDir).filter(f => f.endsWith('.node'));
45
-
46
- if (nodeFiles.length > 0) {
47
- console.log(`✅ @shotstack/shotstack-canvas: Native canvas binding found for ${platformKey}`);
48
- } else {
49
- throw new Error('No .node file found');
50
- }
51
- } catch (error) {
52
- console.warn(`\n⚠️ Warning: Native canvas binding not found for ${platformKey}`);
53
- console.warn(` Expected package: ${requiredPackage}`);
54
- console.warn('\n If you see "Cannot find native binding" errors, try:');
55
- console.warn(' 1. Delete node_modules and package-lock.json');
56
- console.warn(' 2. Run: npm install');
57
- console.warn(` 3. Or manually install: npm install ${requiredPackage}\n`);
58
- }
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall script to verify native canvas bindings are available
5
+ * This helps catch issues early and provides helpful guidance
6
+ */
7
+
8
+ import { platform as _platform, arch as _arch } from 'os';
9
+ import { dirname } from 'path';
10
+ import { readdirSync } from 'fs';
11
+ import { createRequire } from 'module';
12
+
13
+ const require = createRequire(import.meta.url);
14
+
15
+ const platform = _platform();
16
+ const arch = _arch();
17
+
18
+ // Map platform/arch to package names
19
+ const platformMap = {
20
+ 'darwin-arm64': '@napi-rs/canvas-darwin-arm64',
21
+ 'darwin-x64': '@napi-rs/canvas-darwin-x64',
22
+ 'linux-arm64': '@napi-rs/canvas-linux-arm64-gnu',
23
+ 'linux-x64': '@napi-rs/canvas-linux-x64-gnu',
24
+ 'win32-x64': '@napi-rs/canvas-win32-x64-msvc',
25
+ 'linux-arm': '@napi-rs/canvas-linux-arm-gnueabihf',
26
+ 'android-arm64': '@napi-rs/canvas-android-arm64',
27
+ };
28
+
29
+ const platformKey = `${platform}-${arch}`;
30
+ const requiredPackage = platformMap[platformKey];
31
+
32
+ if (!requiredPackage) {
33
+ console.warn(`\n⚠️ Warning: Unsupported platform ${platformKey} for @napi-rs/canvas`);
34
+ console.warn(' Canvas rendering may not work on this platform.\n');
35
+ process.exit(0);
36
+ }
37
+
38
+ // Check if the native binding package is installed
39
+ try {
40
+ const packagePath = require.resolve(`${requiredPackage}/package.json`);
41
+ const packageDir = dirname(packagePath);
42
+
43
+ // Verify the .node file exists
44
+ const nodeFiles = readdirSync(packageDir).filter(f => f.endsWith('.node'));
45
+
46
+ if (nodeFiles.length > 0) {
47
+ console.log(`✅ @shotstack/shotstack-canvas: Native canvas binding found for ${platformKey}`);
48
+ } else {
49
+ throw new Error('No .node file found');
50
+ }
51
+ } catch (error) {
52
+ console.warn(`\n⚠️ Warning: Native canvas binding not found for ${platformKey}`);
53
+ console.warn(` Expected package: ${requiredPackage}`);
54
+ console.warn('\n If you see "Cannot find native binding" errors, try:');
55
+ console.warn(' 1. Delete node_modules and package-lock.json');
56
+ console.warn(' 2. Run: npm install');
57
+ console.warn(` 3. Or manually install: npm install ${requiredPackage}\n`);
58
+ }