@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 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
@@ -417,7 +417,7 @@ var CANVAS_CONFIG = {
417
417
  width: 800,
418
418
  height: 400,
419
419
  pixelRatio: 2,
420
- fontFamily: "Roboto",
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("Open Sans"),
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 canvasMod = await import("canvas");
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 ?? "Open Sans",
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 ROBOTO_FONT_URLS = {
5770
- "100": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbGmT.ttf",
5771
- "300": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabWmT.ttf",
5772
- "400": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbWmT.ttf",
5773
- "500": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWub2bWmT.ttf",
5774
- "600": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYaammT.ttf",
5775
- "700": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYjammT.ttf",
5776
- "800": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZEammT.ttf",
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(ROBOTO_FONT_URLS);
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: "Roboto", weight });
5815
+ const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
5810
5816
  if (!existingFace) {
5811
- const bytes = await loadFileOrHttpToArrayBuffer(ROBOTO_FONT_URLS[weight]);
5812
- await this.fontRegistry.registerFromBytes(bytes, { family: "Roboto", weight });
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 ?? "Roboto",
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(pct, framesProcessed, schedule.totalFrames, i + 1, schedule.uniqueFrameCount, fps, eta);
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: "Roboto",
6343
+ family: "Open Sans",
6330
6344
  weight: "400",
6331
6345
  size: 48,
6332
6346
  color: "#000000",
@@ -29,7 +29,7 @@ var CANVAS_CONFIG = {
29
29
  width: 800,
30
30
  height: 400,
31
31
  pixelRatio: 2,
32
- fontFamily: "Roboto",
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("Open Sans"),
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 canvasMod = await import("canvas");
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 ?? "Open Sans",
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 ROBOTO_FONT_URLS = {
5381
- "100": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbGmT.ttf",
5382
- "300": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabWmT.ttf",
5383
- "400": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbWmT.ttf",
5384
- "500": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWub2bWmT.ttf",
5385
- "600": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYaammT.ttf",
5386
- "700": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYjammT.ttf",
5387
- "800": "https://fonts.gstatic.com/s/roboto/v50/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZEammT.ttf",
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(ROBOTO_FONT_URLS);
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: "Roboto", weight });
5426
+ const existingFace = await this.fontRegistry.getFace({ family: "Open Sans", weight });
5421
5427
  if (!existingFace) {
5422
- const bytes = await loadFileOrHttpToArrayBuffer(ROBOTO_FONT_URLS[weight]);
5423
- await this.fontRegistry.registerFromBytes(bytes, { family: "Roboto", weight });
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 ?? "Roboto",
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(pct, framesProcessed, schedule.totalFrames, i + 1, schedule.uniqueFrameCount, fps, eta);
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: "Roboto",
5954
+ family: "Open Sans",
5941
5955
  weight: "400",
5942
5956
  size: 48,
5943
5957
  color: "#000000",