@shotstack/shotstack-canvas 2.0.2 → 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 +34 -20
- package/dist/entry.node.js +34 -20
- package/dist/entry.web.js +167 -159
- 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"),
|
|
@@ -1217,8 +1217,15 @@ var FontRegistry = class _FontRegistry {
|
|
|
1217
1217
|
if (this.registeredCanvasFonts.has(family)) {
|
|
1218
1218
|
return;
|
|
1219
1219
|
}
|
|
1220
|
+
if (typeof window !== "undefined") {
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1220
1223
|
try {
|
|
1221
|
-
const
|
|
1224
|
+
const moduleName = "canvas";
|
|
1225
|
+
const canvasMod = await import(
|
|
1226
|
+
/* @vite-ignore */
|
|
1227
|
+
moduleName
|
|
1228
|
+
);
|
|
1222
1229
|
const GlobalFonts = canvasMod.GlobalFonts;
|
|
1223
1230
|
if (GlobalFonts && typeof GlobalFonts.register === "function") {
|
|
1224
1231
|
const buffer = Buffer.from(bytes);
|
|
@@ -4860,7 +4867,7 @@ function extractFontConfig(asset) {
|
|
|
4860
4867
|
const font = asset.font;
|
|
4861
4868
|
const active = asset.active?.font;
|
|
4862
4869
|
return {
|
|
4863
|
-
family: font?.family ??
|
|
4870
|
+
family: font?.family ?? CANVAS_CONFIG.DEFAULTS.fontFamily,
|
|
4864
4871
|
size: font?.size ?? 24,
|
|
4865
4872
|
weight: String(font?.weight ?? "400"),
|
|
4866
4873
|
baseColor: font?.color ?? "#ffffff",
|
|
@@ -5766,15 +5773,14 @@ async function createNodeRawEncoder(config, options) {
|
|
|
5766
5773
|
}
|
|
5767
5774
|
|
|
5768
5775
|
// src/core/rich-caption-renderer.ts
|
|
5769
|
-
var
|
|
5770
|
-
|
|
5771
|
-
"300":
|
|
5772
|
-
"400":
|
|
5773
|
-
"500":
|
|
5774
|
-
"600":
|
|
5775
|
-
"700":
|
|
5776
|
-
"800":
|
|
5777
|
-
"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
|
|
5778
5784
|
};
|
|
5779
5785
|
var RichCaptionRenderer = class {
|
|
5780
5786
|
width;
|
|
@@ -5804,12 +5810,12 @@ var RichCaptionRenderer = class {
|
|
|
5804
5810
|
async initialize() {
|
|
5805
5811
|
this.fontRegistry = await FontRegistry.getSharedInstance(this.wasmBaseURL);
|
|
5806
5812
|
this.layoutEngine = new CaptionLayoutEngine(this.fontRegistry);
|
|
5807
|
-
const weightsToLoad = Object.keys(
|
|
5813
|
+
const weightsToLoad = Object.keys(OPEN_SANS_FONT_URLS);
|
|
5808
5814
|
const loadPromises = weightsToLoad.map(async (weight) => {
|
|
5809
|
-
const existingFace = await this.fontRegistry.getFace({ family: "
|
|
5815
|
+
const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
|
|
5810
5816
|
if (!existingFace) {
|
|
5811
|
-
const bytes = await loadFileOrHttpToArrayBuffer(
|
|
5812
|
-
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 });
|
|
5813
5819
|
}
|
|
5814
5820
|
});
|
|
5815
5821
|
await Promise.all(loadPromises);
|
|
@@ -5853,7 +5859,7 @@ var RichCaptionRenderer = class {
|
|
|
5853
5859
|
maxLines: asset.maxLines ?? 2,
|
|
5854
5860
|
position: asset.position ?? "bottom",
|
|
5855
5861
|
fontSize: font?.size ?? 24,
|
|
5856
|
-
fontFamily: font?.family ?? "
|
|
5862
|
+
fontFamily: font?.family ?? "Open Sans",
|
|
5857
5863
|
fontWeight: String(font?.weight ?? "400"),
|
|
5858
5864
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
5859
5865
|
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
@@ -5946,7 +5952,15 @@ var RichCaptionRenderer = class {
|
|
|
5946
5952
|
const elapsed = performance.now() - totalStart;
|
|
5947
5953
|
const fps = framesProcessed / (elapsed / 1e3);
|
|
5948
5954
|
const eta = (schedule.totalFrames - framesProcessed) / fps * 1e3;
|
|
5949
|
-
this.logProgress(
|
|
5955
|
+
this.logProgress(
|
|
5956
|
+
pct,
|
|
5957
|
+
framesProcessed,
|
|
5958
|
+
schedule.totalFrames,
|
|
5959
|
+
i + 1,
|
|
5960
|
+
schedule.uniqueFrameCount,
|
|
5961
|
+
fps,
|
|
5962
|
+
eta
|
|
5963
|
+
);
|
|
5950
5964
|
}
|
|
5951
5965
|
if (i % 500 === 0 && i > 0) {
|
|
5952
5966
|
this.checkMemoryUsage();
|
|
@@ -6326,7 +6340,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6326
6340
|
}
|
|
6327
6341
|
}
|
|
6328
6342
|
const main = asset.font ?? {
|
|
6329
|
-
family: "
|
|
6343
|
+
family: "Open Sans",
|
|
6330
6344
|
weight: "400",
|
|
6331
6345
|
size: 48,
|
|
6332
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"),
|
|
@@ -828,8 +828,15 @@ var FontRegistry = class _FontRegistry {
|
|
|
828
828
|
if (this.registeredCanvasFonts.has(family)) {
|
|
829
829
|
return;
|
|
830
830
|
}
|
|
831
|
+
if (typeof window !== "undefined") {
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
831
834
|
try {
|
|
832
|
-
const
|
|
835
|
+
const moduleName = "canvas";
|
|
836
|
+
const canvasMod = await import(
|
|
837
|
+
/* @vite-ignore */
|
|
838
|
+
moduleName
|
|
839
|
+
);
|
|
833
840
|
const GlobalFonts = canvasMod.GlobalFonts;
|
|
834
841
|
if (GlobalFonts && typeof GlobalFonts.register === "function") {
|
|
835
842
|
const buffer = Buffer.from(bytes);
|
|
@@ -4471,7 +4478,7 @@ function extractFontConfig(asset) {
|
|
|
4471
4478
|
const font = asset.font;
|
|
4472
4479
|
const active = asset.active?.font;
|
|
4473
4480
|
return {
|
|
4474
|
-
family: font?.family ??
|
|
4481
|
+
family: font?.family ?? CANVAS_CONFIG.DEFAULTS.fontFamily,
|
|
4475
4482
|
size: font?.size ?? 24,
|
|
4476
4483
|
weight: String(font?.weight ?? "400"),
|
|
4477
4484
|
baseColor: font?.color ?? "#ffffff",
|
|
@@ -5377,15 +5384,14 @@ async function createNodeRawEncoder(config, options) {
|
|
|
5377
5384
|
}
|
|
5378
5385
|
|
|
5379
5386
|
// src/core/rich-caption-renderer.ts
|
|
5380
|
-
var
|
|
5381
|
-
|
|
5382
|
-
"300":
|
|
5383
|
-
"400":
|
|
5384
|
-
"500":
|
|
5385
|
-
"600":
|
|
5386
|
-
"700":
|
|
5387
|
-
"800":
|
|
5388
|
-
"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
|
|
5389
5395
|
};
|
|
5390
5396
|
var RichCaptionRenderer = class {
|
|
5391
5397
|
width;
|
|
@@ -5415,12 +5421,12 @@ var RichCaptionRenderer = class {
|
|
|
5415
5421
|
async initialize() {
|
|
5416
5422
|
this.fontRegistry = await FontRegistry.getSharedInstance(this.wasmBaseURL);
|
|
5417
5423
|
this.layoutEngine = new CaptionLayoutEngine(this.fontRegistry);
|
|
5418
|
-
const weightsToLoad = Object.keys(
|
|
5424
|
+
const weightsToLoad = Object.keys(OPEN_SANS_FONT_URLS);
|
|
5419
5425
|
const loadPromises = weightsToLoad.map(async (weight) => {
|
|
5420
|
-
const existingFace = await this.fontRegistry.getFace({ family: "
|
|
5426
|
+
const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
|
|
5421
5427
|
if (!existingFace) {
|
|
5422
|
-
const bytes = await loadFileOrHttpToArrayBuffer(
|
|
5423
|
-
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 });
|
|
5424
5430
|
}
|
|
5425
5431
|
});
|
|
5426
5432
|
await Promise.all(loadPromises);
|
|
@@ -5464,7 +5470,7 @@ var RichCaptionRenderer = class {
|
|
|
5464
5470
|
maxLines: asset.maxLines ?? 2,
|
|
5465
5471
|
position: asset.position ?? "bottom",
|
|
5466
5472
|
fontSize: font?.size ?? 24,
|
|
5467
|
-
fontFamily: font?.family ?? "
|
|
5473
|
+
fontFamily: font?.family ?? "Open Sans",
|
|
5468
5474
|
fontWeight: String(font?.weight ?? "400"),
|
|
5469
5475
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
5470
5476
|
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
@@ -5557,7 +5563,15 @@ var RichCaptionRenderer = class {
|
|
|
5557
5563
|
const elapsed = performance.now() - totalStart;
|
|
5558
5564
|
const fps = framesProcessed / (elapsed / 1e3);
|
|
5559
5565
|
const eta = (schedule.totalFrames - framesProcessed) / fps * 1e3;
|
|
5560
|
-
this.logProgress(
|
|
5566
|
+
this.logProgress(
|
|
5567
|
+
pct,
|
|
5568
|
+
framesProcessed,
|
|
5569
|
+
schedule.totalFrames,
|
|
5570
|
+
i + 1,
|
|
5571
|
+
schedule.uniqueFrameCount,
|
|
5572
|
+
fps,
|
|
5573
|
+
eta
|
|
5574
|
+
);
|
|
5561
5575
|
}
|
|
5562
5576
|
if (i % 500 === 0 && i > 0) {
|
|
5563
5577
|
this.checkMemoryUsage();
|
|
@@ -5937,7 +5951,7 @@ async function createTextEngine(opts = {}) {
|
|
|
5937
5951
|
}
|
|
5938
5952
|
}
|
|
5939
5953
|
const main = asset.font ?? {
|
|
5940
|
-
family: "
|
|
5954
|
+
family: "Open Sans",
|
|
5941
5955
|
weight: "400",
|
|
5942
5956
|
size: 48,
|
|
5943
5957
|
color: "#000000",
|