@shotstack/shotstack-canvas 2.0.3 → 2.0.4
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 +13 -13
- package/dist/entry.node.cjs +26 -19
- package/dist/entry.node.js +26 -19
- package/dist/entry.web.js +159 -158
- package/dist/{hb-HSWG3Q47.js → hb-V6YBF7AQ.js} +2 -2
- package/dist/{hbjs-VGYWXH44.js → hbjs-PXJWBHW7.js} +2 -2
- package/package.json +1 -1
- package/scripts/postinstall.js +58 -58
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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
|
+
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
|
package/dist/entry.node.cjs
CHANGED
|
@@ -417,7 +417,7 @@ var CANVAS_CONFIG = {
|
|
|
417
417
|
width: 800,
|
|
418
418
|
height: 400,
|
|
419
419
|
pixelRatio: 2,
|
|
420
|
-
fontFamily: "
|
|
420
|
+
fontFamily: "Open Sans",
|
|
421
421
|
fontSize: 48,
|
|
422
422
|
color: "#ffffff",
|
|
423
423
|
textAlign: "center"
|
|
@@ -572,7 +572,7 @@ var wordTimingSchema = import_zod2.wordTimingSchema.extend({
|
|
|
572
572
|
confidence: import_zod.z.number().min(0).max(1).optional()
|
|
573
573
|
});
|
|
574
574
|
var richCaptionFontSchema = import_zod.z.object({
|
|
575
|
-
family: import_zod.z.string().default(
|
|
575
|
+
family: import_zod.z.string().default(CANVAS_CONFIG.DEFAULTS.fontFamily),
|
|
576
576
|
size: import_zod.z.number().int().min(1).max(500).default(24),
|
|
577
577
|
weight: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).default("400"),
|
|
578
578
|
color: import_zod.z.string().regex(HEX6).default("#ffffff"),
|
|
@@ -4867,7 +4867,7 @@ function extractFontConfig(asset) {
|
|
|
4867
4867
|
const font = asset.font;
|
|
4868
4868
|
const active = asset.active?.font;
|
|
4869
4869
|
return {
|
|
4870
|
-
family: font?.family ??
|
|
4870
|
+
family: font?.family ?? CANVAS_CONFIG.DEFAULTS.fontFamily,
|
|
4871
4871
|
size: font?.size ?? 24,
|
|
4872
4872
|
weight: String(font?.weight ?? "400"),
|
|
4873
4873
|
baseColor: font?.color ?? "#ffffff",
|
|
@@ -5773,15 +5773,14 @@ async function createNodeRawEncoder(config, options) {
|
|
|
5773
5773
|
}
|
|
5774
5774
|
|
|
5775
5775
|
// src/core/rich-caption-renderer.ts
|
|
5776
|
-
var
|
|
5777
|
-
|
|
5778
|
-
"300":
|
|
5779
|
-
"400":
|
|
5780
|
-
"500":
|
|
5781
|
-
"600":
|
|
5782
|
-
"700":
|
|
5783
|
-
"800":
|
|
5784
|
-
"900": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtammT.ttf"
|
|
5776
|
+
var OPEN_SANS_FONT_URL = "https://fonts.gstatic.com/s/opensans/v44/mem8YaGs126MiZpBA-U1UpcaXcl0Aw.ttf";
|
|
5777
|
+
var OPEN_SANS_FONT_URLS = {
|
|
5778
|
+
"300": OPEN_SANS_FONT_URL,
|
|
5779
|
+
"400": OPEN_SANS_FONT_URL,
|
|
5780
|
+
"500": OPEN_SANS_FONT_URL,
|
|
5781
|
+
"600": OPEN_SANS_FONT_URL,
|
|
5782
|
+
"700": OPEN_SANS_FONT_URL,
|
|
5783
|
+
"800": OPEN_SANS_FONT_URL
|
|
5785
5784
|
};
|
|
5786
5785
|
var RichCaptionRenderer = class {
|
|
5787
5786
|
width;
|
|
@@ -5811,12 +5810,12 @@ var RichCaptionRenderer = class {
|
|
|
5811
5810
|
async initialize() {
|
|
5812
5811
|
this.fontRegistry = await FontRegistry.getSharedInstance(this.wasmBaseURL);
|
|
5813
5812
|
this.layoutEngine = new CaptionLayoutEngine(this.fontRegistry);
|
|
5814
|
-
const weightsToLoad = Object.keys(
|
|
5813
|
+
const weightsToLoad = Object.keys(OPEN_SANS_FONT_URLS);
|
|
5815
5814
|
const loadPromises = weightsToLoad.map(async (weight) => {
|
|
5816
|
-
const existingFace = await this.fontRegistry.getFace({ family: "
|
|
5815
|
+
const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
|
|
5817
5816
|
if (!existingFace) {
|
|
5818
|
-
const bytes = await loadFileOrHttpToArrayBuffer(
|
|
5819
|
-
await this.fontRegistry.registerFromBytes(bytes, { family: "
|
|
5817
|
+
const bytes = await loadFileOrHttpToArrayBuffer(OPEN_SANS_FONT_URLS[weight]);
|
|
5818
|
+
await this.fontRegistry.registerFromBytes(bytes, { family: "Open Sans", weight });
|
|
5820
5819
|
}
|
|
5821
5820
|
});
|
|
5822
5821
|
await Promise.all(loadPromises);
|
|
@@ -5860,7 +5859,7 @@ var RichCaptionRenderer = class {
|
|
|
5860
5859
|
maxLines: asset.maxLines ?? 2,
|
|
5861
5860
|
position: asset.position ?? "bottom",
|
|
5862
5861
|
fontSize: font?.size ?? 24,
|
|
5863
|
-
fontFamily: font?.family ?? "
|
|
5862
|
+
fontFamily: font?.family ?? "Open Sans",
|
|
5864
5863
|
fontWeight: String(font?.weight ?? "400"),
|
|
5865
5864
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
5866
5865
|
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
@@ -5953,7 +5952,15 @@ var RichCaptionRenderer = class {
|
|
|
5953
5952
|
const elapsed = performance.now() - totalStart;
|
|
5954
5953
|
const fps = framesProcessed / (elapsed / 1e3);
|
|
5955
5954
|
const eta = (schedule.totalFrames - framesProcessed) / fps * 1e3;
|
|
5956
|
-
this.logProgress(
|
|
5955
|
+
this.logProgress(
|
|
5956
|
+
pct,
|
|
5957
|
+
framesProcessed,
|
|
5958
|
+
schedule.totalFrames,
|
|
5959
|
+
i + 1,
|
|
5960
|
+
schedule.uniqueFrameCount,
|
|
5961
|
+
fps,
|
|
5962
|
+
eta
|
|
5963
|
+
);
|
|
5957
5964
|
}
|
|
5958
5965
|
if (i % 500 === 0 && i > 0) {
|
|
5959
5966
|
this.checkMemoryUsage();
|
|
@@ -6333,7 +6340,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6333
6340
|
}
|
|
6334
6341
|
}
|
|
6335
6342
|
const main = asset.font ?? {
|
|
6336
|
-
family: "
|
|
6343
|
+
family: "Open Sans",
|
|
6337
6344
|
weight: "400",
|
|
6338
6345
|
size: 48,
|
|
6339
6346
|
color: "#000000",
|
package/dist/entry.node.js
CHANGED
|
@@ -29,7 +29,7 @@ var CANVAS_CONFIG = {
|
|
|
29
29
|
width: 800,
|
|
30
30
|
height: 400,
|
|
31
31
|
pixelRatio: 2,
|
|
32
|
-
fontFamily: "
|
|
32
|
+
fontFamily: "Open Sans",
|
|
33
33
|
fontSize: 48,
|
|
34
34
|
color: "#ffffff",
|
|
35
35
|
textAlign: "center"
|
|
@@ -184,7 +184,7 @@ var wordTimingSchema = baseWordTimingSchema.extend({
|
|
|
184
184
|
confidence: z.number().min(0).max(1).optional()
|
|
185
185
|
});
|
|
186
186
|
var richCaptionFontSchema = z.object({
|
|
187
|
-
family: z.string().default(
|
|
187
|
+
family: z.string().default(CANVAS_CONFIG.DEFAULTS.fontFamily),
|
|
188
188
|
size: z.number().int().min(1).max(500).default(24),
|
|
189
189
|
weight: z.union([z.string(), z.number()]).default("400"),
|
|
190
190
|
color: z.string().regex(HEX6).default("#ffffff"),
|
|
@@ -4478,7 +4478,7 @@ function extractFontConfig(asset) {
|
|
|
4478
4478
|
const font = asset.font;
|
|
4479
4479
|
const active = asset.active?.font;
|
|
4480
4480
|
return {
|
|
4481
|
-
family: font?.family ??
|
|
4481
|
+
family: font?.family ?? CANVAS_CONFIG.DEFAULTS.fontFamily,
|
|
4482
4482
|
size: font?.size ?? 24,
|
|
4483
4483
|
weight: String(font?.weight ?? "400"),
|
|
4484
4484
|
baseColor: font?.color ?? "#ffffff",
|
|
@@ -5384,15 +5384,14 @@ async function createNodeRawEncoder(config, options) {
|
|
|
5384
5384
|
}
|
|
5385
5385
|
|
|
5386
5386
|
// src/core/rich-caption-renderer.ts
|
|
5387
|
-
var
|
|
5388
|
-
|
|
5389
|
-
"300":
|
|
5390
|
-
"400":
|
|
5391
|
-
"500":
|
|
5392
|
-
"600":
|
|
5393
|
-
"700":
|
|
5394
|
-
"800":
|
|
5395
|
-
"900": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtammT.ttf"
|
|
5387
|
+
var OPEN_SANS_FONT_URL = "https://fonts.gstatic.com/s/opensans/v44/mem8YaGs126MiZpBA-U1UpcaXcl0Aw.ttf";
|
|
5388
|
+
var OPEN_SANS_FONT_URLS = {
|
|
5389
|
+
"300": OPEN_SANS_FONT_URL,
|
|
5390
|
+
"400": OPEN_SANS_FONT_URL,
|
|
5391
|
+
"500": OPEN_SANS_FONT_URL,
|
|
5392
|
+
"600": OPEN_SANS_FONT_URL,
|
|
5393
|
+
"700": OPEN_SANS_FONT_URL,
|
|
5394
|
+
"800": OPEN_SANS_FONT_URL
|
|
5396
5395
|
};
|
|
5397
5396
|
var RichCaptionRenderer = class {
|
|
5398
5397
|
width;
|
|
@@ -5422,12 +5421,12 @@ var RichCaptionRenderer = class {
|
|
|
5422
5421
|
async initialize() {
|
|
5423
5422
|
this.fontRegistry = await FontRegistry.getSharedInstance(this.wasmBaseURL);
|
|
5424
5423
|
this.layoutEngine = new CaptionLayoutEngine(this.fontRegistry);
|
|
5425
|
-
const weightsToLoad = Object.keys(
|
|
5424
|
+
const weightsToLoad = Object.keys(OPEN_SANS_FONT_URLS);
|
|
5426
5425
|
const loadPromises = weightsToLoad.map(async (weight) => {
|
|
5427
|
-
const existingFace = await this.fontRegistry.getFace({ family: "
|
|
5426
|
+
const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
|
|
5428
5427
|
if (!existingFace) {
|
|
5429
|
-
const bytes = await loadFileOrHttpToArrayBuffer(
|
|
5430
|
-
await this.fontRegistry.registerFromBytes(bytes, { family: "
|
|
5428
|
+
const bytes = await loadFileOrHttpToArrayBuffer(OPEN_SANS_FONT_URLS[weight]);
|
|
5429
|
+
await this.fontRegistry.registerFromBytes(bytes, { family: "Open Sans", weight });
|
|
5431
5430
|
}
|
|
5432
5431
|
});
|
|
5433
5432
|
await Promise.all(loadPromises);
|
|
@@ -5471,7 +5470,7 @@ var RichCaptionRenderer = class {
|
|
|
5471
5470
|
maxLines: asset.maxLines ?? 2,
|
|
5472
5471
|
position: asset.position ?? "bottom",
|
|
5473
5472
|
fontSize: font?.size ?? 24,
|
|
5474
|
-
fontFamily: font?.family ?? "
|
|
5473
|
+
fontFamily: font?.family ?? "Open Sans",
|
|
5475
5474
|
fontWeight: String(font?.weight ?? "400"),
|
|
5476
5475
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
5477
5476
|
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
@@ -5564,7 +5563,15 @@ var RichCaptionRenderer = class {
|
|
|
5564
5563
|
const elapsed = performance.now() - totalStart;
|
|
5565
5564
|
const fps = framesProcessed / (elapsed / 1e3);
|
|
5566
5565
|
const eta = (schedule.totalFrames - framesProcessed) / fps * 1e3;
|
|
5567
|
-
this.logProgress(
|
|
5566
|
+
this.logProgress(
|
|
5567
|
+
pct,
|
|
5568
|
+
framesProcessed,
|
|
5569
|
+
schedule.totalFrames,
|
|
5570
|
+
i + 1,
|
|
5571
|
+
schedule.uniqueFrameCount,
|
|
5572
|
+
fps,
|
|
5573
|
+
eta
|
|
5574
|
+
);
|
|
5568
5575
|
}
|
|
5569
5576
|
if (i % 500 === 0 && i > 0) {
|
|
5570
5577
|
this.checkMemoryUsage();
|
|
@@ -5944,7 +5951,7 @@ async function createTextEngine(opts = {}) {
|
|
|
5944
5951
|
}
|
|
5945
5952
|
}
|
|
5946
5953
|
const main = asset.font ?? {
|
|
5947
|
-
family: "
|
|
5954
|
+
family: "Open Sans",
|
|
5948
5955
|
weight: "400",
|
|
5949
5956
|
size: 48,
|
|
5950
5957
|
color: "#000000",
|