@shotstack/shotstack-canvas 2.1.6 → 2.1.8
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/dist/entry.node.cjs +15 -11
- package/dist/entry.node.d.cts +0 -13
- package/dist/entry.node.d.ts +0 -13
- package/dist/entry.node.js +15 -11
- package/dist/entry.web.d.ts +0 -13
- package/dist/entry.web.js +10 -8
- package/package.json +2 -2
package/dist/entry.node.cjs
CHANGED
|
@@ -503,6 +503,7 @@ var canvasStyleSchema = import_zod2.richTextStyleSchema.extend({
|
|
|
503
503
|
textDecoration: import_zod.z.enum(["none", "underline", "line-through"]).default("none"),
|
|
504
504
|
gradient: canvasGradientSchema.optional()
|
|
505
505
|
});
|
|
506
|
+
var captionStyleSchema = canvasStyleSchema.omit({ wordSpacing: true });
|
|
506
507
|
var canvasStrokeSchema = import_zod2.richTextStrokeSchema.extend({
|
|
507
508
|
width: import_zod.z.number().min(0).default(0),
|
|
508
509
|
color: import_zod.z.string().regex(HEX6).default("#000000"),
|
|
@@ -590,8 +591,7 @@ var richCaptionFontSchema = import_zod.z.object({
|
|
|
590
591
|
weight: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).default("400"),
|
|
591
592
|
color: import_zod.z.string().regex(HEX6).default("#ffffff"),
|
|
592
593
|
opacity: import_zod.z.number().min(0).max(1).default(1),
|
|
593
|
-
background: import_zod.z.string().regex(HEX6).optional()
|
|
594
|
-
textDecoration: import_zod.z.enum(["none", "underline", "line-through"]).default("none")
|
|
594
|
+
background: import_zod.z.string().regex(HEX6).optional()
|
|
595
595
|
});
|
|
596
596
|
var richCaptionActiveSchema = import_zod2.richCaptionActiveSchema.extend({
|
|
597
597
|
font: import_zod.z.object({
|
|
@@ -629,7 +629,7 @@ var richCaptionAssetSchema = import_zod.z.object({
|
|
|
629
629
|
src: import_zod.z.string().min(1).optional(),
|
|
630
630
|
words: import_zod.z.array(wordTimingSchema).max(1e5).optional(),
|
|
631
631
|
font: richCaptionFontSchema.optional(),
|
|
632
|
-
style:
|
|
632
|
+
style: captionStyleSchema.optional(),
|
|
633
633
|
stroke: canvasStrokeSchema.optional(),
|
|
634
634
|
shadow: canvasShadowSchema.optional(),
|
|
635
635
|
background: canvasBackgroundSchema.optional(),
|
|
@@ -1539,7 +1539,7 @@ var LayoutEngine = class {
|
|
|
1539
1539
|
}
|
|
1540
1540
|
async layout(params) {
|
|
1541
1541
|
try {
|
|
1542
|
-
const { textTransform, desc, fontSize, letterSpacing, width, emojiFallback } = params;
|
|
1542
|
+
const { textTransform, desc, fontSize, letterSpacing, wordSpacing = 0, width, emojiFallback } = params;
|
|
1543
1543
|
const input = this.transformText(params.text, textTransform);
|
|
1544
1544
|
if (!input || input.length === 0) {
|
|
1545
1545
|
return [];
|
|
@@ -1569,9 +1569,10 @@ var LayoutEngine = class {
|
|
|
1569
1569
|
char = String.fromCodePoint(codePoint);
|
|
1570
1570
|
}
|
|
1571
1571
|
}
|
|
1572
|
+
const isSpace = char === " ";
|
|
1572
1573
|
return {
|
|
1573
1574
|
id: g.g,
|
|
1574
|
-
xAdvance: g.ax * scale + letterSpacing,
|
|
1575
|
+
xAdvance: g.ax * scale + letterSpacing + (isSpace ? wordSpacing : 0),
|
|
1575
1576
|
xOffset: g.dx * scale,
|
|
1576
1577
|
yOffset: -g.dy * scale,
|
|
1577
1578
|
cluster: g.cl,
|
|
@@ -2848,10 +2849,10 @@ var CaptionLayoutEngine = class {
|
|
|
2848
2849
|
let spaceWidth;
|
|
2849
2850
|
if (config.measureTextWidth) {
|
|
2850
2851
|
const fontString = `${config.fontWeight} ${config.fontSize}px "${config.fontFamily}"`;
|
|
2851
|
-
spaceWidth = config.measureTextWidth(" ", fontString)
|
|
2852
|
+
spaceWidth = config.measureTextWidth(" ", fontString);
|
|
2852
2853
|
} else {
|
|
2853
2854
|
const spaceWord = await this.measureWord(" ", measurementConfig);
|
|
2854
|
-
spaceWidth = spaceWord.width
|
|
2855
|
+
spaceWidth = spaceWord.width;
|
|
2855
2856
|
}
|
|
2856
2857
|
const groups = wordGroups.flatMap((indices) => {
|
|
2857
2858
|
const groupWidths = indices.map((i) => store.widths[i]);
|
|
@@ -3423,7 +3424,7 @@ function extractCaptionBorder(asset) {
|
|
|
3423
3424
|
};
|
|
3424
3425
|
}
|
|
3425
3426
|
function extractTextDecoration(asset, isActive) {
|
|
3426
|
-
const baseDecoration = asset.
|
|
3427
|
+
const baseDecoration = asset.style?.textDecoration;
|
|
3427
3428
|
const activeDecoration = asset.active?.font?.textDecoration;
|
|
3428
3429
|
if (isActive && activeDecoration !== void 0) {
|
|
3429
3430
|
return activeDecoration === "none" ? void 0 : activeDecoration;
|
|
@@ -5486,11 +5487,14 @@ function extractSvgDimensions(svgString) {
|
|
|
5486
5487
|
}
|
|
5487
5488
|
|
|
5488
5489
|
// src/core/canvas-text-measurer.ts
|
|
5489
|
-
async function createCanvasTextMeasurer() {
|
|
5490
|
+
async function createCanvasTextMeasurer(letterSpacing) {
|
|
5490
5491
|
const canvasMod = await import("canvas");
|
|
5491
5492
|
const canvas = canvasMod.createCanvas(1, 1);
|
|
5492
5493
|
const ctx = canvas.getContext("2d");
|
|
5493
5494
|
ctx.textBaseline = "alphabetic";
|
|
5495
|
+
if (letterSpacing) {
|
|
5496
|
+
ctx.letterSpacing = `${letterSpacing}px`;
|
|
5497
|
+
}
|
|
5494
5498
|
let lastFont = "";
|
|
5495
5499
|
return (text, font) => {
|
|
5496
5500
|
if (font !== lastFont) {
|
|
@@ -6269,7 +6273,7 @@ var RichCaptionRenderer = class {
|
|
|
6269
6273
|
}
|
|
6270
6274
|
const font = asset.font;
|
|
6271
6275
|
const style = asset.style;
|
|
6272
|
-
const measureTextWidth = await createCanvasTextMeasurer();
|
|
6276
|
+
const measureTextWidth = await createCanvasTextMeasurer(style?.letterSpacing ?? 0);
|
|
6273
6277
|
const fontSize = font?.size ?? 24;
|
|
6274
6278
|
const lineHeight = style?.lineHeight ?? 1.2;
|
|
6275
6279
|
const padding = extractCaptionPadding(asset);
|
|
@@ -6290,7 +6294,6 @@ var RichCaptionRenderer = class {
|
|
|
6290
6294
|
fontFamily: font?.family ?? "Roboto",
|
|
6291
6295
|
fontWeight: String(font?.weight ?? "400"),
|
|
6292
6296
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
6293
|
-
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
6294
6297
|
lineHeight,
|
|
6295
6298
|
textTransform: style?.textTransform ?? "none",
|
|
6296
6299
|
pauseThreshold: this.currentAsset?.pauseThreshold ?? 500,
|
|
@@ -6844,6 +6847,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6844
6847
|
text: asset.text,
|
|
6845
6848
|
width: (asset.width ?? width) - padding2.left - padding2.right,
|
|
6846
6849
|
letterSpacing: asset.style?.letterSpacing ?? 0,
|
|
6850
|
+
wordSpacing: typeof asset.style?.wordSpacing === "number" ? asset.style.wordSpacing : 0,
|
|
6847
6851
|
fontSize: main.size,
|
|
6848
6852
|
lineHeight: asset.style?.lineHeight ?? 1.2,
|
|
6849
6853
|
desc,
|
package/dist/entry.node.d.cts
CHANGED
|
@@ -271,14 +271,8 @@ declare const richCaptionAssetSchema: z.ZodObject<{
|
|
|
271
271
|
color: z.ZodDefault<z.ZodString>;
|
|
272
272
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
273
273
|
background: z.ZodOptional<z.ZodString>;
|
|
274
|
-
textDecoration: z.ZodDefault<z.ZodEnum<{
|
|
275
|
-
none: "none";
|
|
276
|
-
underline: "underline";
|
|
277
|
-
"line-through": "line-through";
|
|
278
|
-
}>>;
|
|
279
274
|
}, z.core.$strip>>;
|
|
280
275
|
style: z.ZodOptional<z.ZodObject<{
|
|
281
|
-
wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
|
|
282
276
|
letterSpacing: z.ZodDefault<z.ZodNumber>;
|
|
283
277
|
lineHeight: z.ZodDefault<z.ZodNumber>;
|
|
284
278
|
textTransform: z.ZodDefault<z.ZodEnum<{
|
|
@@ -413,14 +407,8 @@ declare const CanvasRichCaptionAssetSchema: z.ZodObject<{
|
|
|
413
407
|
color: z.ZodDefault<z.ZodString>;
|
|
414
408
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
415
409
|
background: z.ZodOptional<z.ZodString>;
|
|
416
|
-
textDecoration: z.ZodDefault<z.ZodEnum<{
|
|
417
|
-
none: "none";
|
|
418
|
-
underline: "underline";
|
|
419
|
-
"line-through": "line-through";
|
|
420
|
-
}>>;
|
|
421
410
|
}, z.core.$strip>>;
|
|
422
411
|
style: z.ZodOptional<z.ZodObject<{
|
|
423
|
-
wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
|
|
424
412
|
letterSpacing: z.ZodDefault<z.ZodNumber>;
|
|
425
413
|
lineHeight: z.ZodDefault<z.ZodNumber>;
|
|
426
414
|
textTransform: z.ZodDefault<z.ZodEnum<{
|
|
@@ -661,7 +649,6 @@ interface CaptionLayoutConfig {
|
|
|
661
649
|
fontFamily: string;
|
|
662
650
|
fontWeight: string | number;
|
|
663
651
|
letterSpacing: number;
|
|
664
|
-
wordSpacing: number;
|
|
665
652
|
lineHeight: number;
|
|
666
653
|
textTransform: "none" | "uppercase" | "lowercase" | "capitalize";
|
|
667
654
|
pauseThreshold: number;
|
package/dist/entry.node.d.ts
CHANGED
|
@@ -271,14 +271,8 @@ declare const richCaptionAssetSchema: z.ZodObject<{
|
|
|
271
271
|
color: z.ZodDefault<z.ZodString>;
|
|
272
272
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
273
273
|
background: z.ZodOptional<z.ZodString>;
|
|
274
|
-
textDecoration: z.ZodDefault<z.ZodEnum<{
|
|
275
|
-
none: "none";
|
|
276
|
-
underline: "underline";
|
|
277
|
-
"line-through": "line-through";
|
|
278
|
-
}>>;
|
|
279
274
|
}, z.core.$strip>>;
|
|
280
275
|
style: z.ZodOptional<z.ZodObject<{
|
|
281
|
-
wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
|
|
282
276
|
letterSpacing: z.ZodDefault<z.ZodNumber>;
|
|
283
277
|
lineHeight: z.ZodDefault<z.ZodNumber>;
|
|
284
278
|
textTransform: z.ZodDefault<z.ZodEnum<{
|
|
@@ -413,14 +407,8 @@ declare const CanvasRichCaptionAssetSchema: z.ZodObject<{
|
|
|
413
407
|
color: z.ZodDefault<z.ZodString>;
|
|
414
408
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
415
409
|
background: z.ZodOptional<z.ZodString>;
|
|
416
|
-
textDecoration: z.ZodDefault<z.ZodEnum<{
|
|
417
|
-
none: "none";
|
|
418
|
-
underline: "underline";
|
|
419
|
-
"line-through": "line-through";
|
|
420
|
-
}>>;
|
|
421
410
|
}, z.core.$strip>>;
|
|
422
411
|
style: z.ZodOptional<z.ZodObject<{
|
|
423
|
-
wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
|
|
424
412
|
letterSpacing: z.ZodDefault<z.ZodNumber>;
|
|
425
413
|
lineHeight: z.ZodDefault<z.ZodNumber>;
|
|
426
414
|
textTransform: z.ZodDefault<z.ZodEnum<{
|
|
@@ -661,7 +649,6 @@ interface CaptionLayoutConfig {
|
|
|
661
649
|
fontFamily: string;
|
|
662
650
|
fontWeight: string | number;
|
|
663
651
|
letterSpacing: number;
|
|
664
|
-
wordSpacing: number;
|
|
665
652
|
lineHeight: number;
|
|
666
653
|
textTransform: "none" | "uppercase" | "lowercase" | "capitalize";
|
|
667
654
|
pauseThreshold: number;
|
package/dist/entry.node.js
CHANGED
|
@@ -100,6 +100,7 @@ var canvasStyleSchema = richTextStyleSchema.extend({
|
|
|
100
100
|
textDecoration: z.enum(["none", "underline", "line-through"]).default("none"),
|
|
101
101
|
gradient: canvasGradientSchema.optional()
|
|
102
102
|
});
|
|
103
|
+
var captionStyleSchema = canvasStyleSchema.omit({ wordSpacing: true });
|
|
103
104
|
var canvasStrokeSchema = richTextStrokeSchema.extend({
|
|
104
105
|
width: z.number().min(0).default(0),
|
|
105
106
|
color: z.string().regex(HEX6).default("#000000"),
|
|
@@ -187,8 +188,7 @@ var richCaptionFontSchema = z.object({
|
|
|
187
188
|
weight: z.union([z.string(), z.number()]).default("400"),
|
|
188
189
|
color: z.string().regex(HEX6).default("#ffffff"),
|
|
189
190
|
opacity: z.number().min(0).max(1).default(1),
|
|
190
|
-
background: z.string().regex(HEX6).optional()
|
|
191
|
-
textDecoration: z.enum(["none", "underline", "line-through"]).default("none")
|
|
191
|
+
background: z.string().regex(HEX6).optional()
|
|
192
192
|
});
|
|
193
193
|
var richCaptionActiveSchema = baseCaptionActiveSchema.extend({
|
|
194
194
|
font: z.object({
|
|
@@ -226,7 +226,7 @@ var richCaptionAssetSchema = z.object({
|
|
|
226
226
|
src: z.string().min(1).optional(),
|
|
227
227
|
words: z.array(wordTimingSchema).max(1e5).optional(),
|
|
228
228
|
font: richCaptionFontSchema.optional(),
|
|
229
|
-
style:
|
|
229
|
+
style: captionStyleSchema.optional(),
|
|
230
230
|
stroke: canvasStrokeSchema.optional(),
|
|
231
231
|
shadow: canvasShadowSchema.optional(),
|
|
232
232
|
background: canvasBackgroundSchema.optional(),
|
|
@@ -1135,7 +1135,7 @@ var LayoutEngine = class {
|
|
|
1135
1135
|
}
|
|
1136
1136
|
async layout(params) {
|
|
1137
1137
|
try {
|
|
1138
|
-
const { textTransform, desc, fontSize, letterSpacing, width, emojiFallback } = params;
|
|
1138
|
+
const { textTransform, desc, fontSize, letterSpacing, wordSpacing = 0, width, emojiFallback } = params;
|
|
1139
1139
|
const input = this.transformText(params.text, textTransform);
|
|
1140
1140
|
if (!input || input.length === 0) {
|
|
1141
1141
|
return [];
|
|
@@ -1165,9 +1165,10 @@ var LayoutEngine = class {
|
|
|
1165
1165
|
char = String.fromCodePoint(codePoint);
|
|
1166
1166
|
}
|
|
1167
1167
|
}
|
|
1168
|
+
const isSpace = char === " ";
|
|
1168
1169
|
return {
|
|
1169
1170
|
id: g.g,
|
|
1170
|
-
xAdvance: g.ax * scale + letterSpacing,
|
|
1171
|
+
xAdvance: g.ax * scale + letterSpacing + (isSpace ? wordSpacing : 0),
|
|
1171
1172
|
xOffset: g.dx * scale,
|
|
1172
1173
|
yOffset: -g.dy * scale,
|
|
1173
1174
|
cluster: g.cl,
|
|
@@ -2444,10 +2445,10 @@ var CaptionLayoutEngine = class {
|
|
|
2444
2445
|
let spaceWidth;
|
|
2445
2446
|
if (config.measureTextWidth) {
|
|
2446
2447
|
const fontString = `${config.fontWeight} ${config.fontSize}px "${config.fontFamily}"`;
|
|
2447
|
-
spaceWidth = config.measureTextWidth(" ", fontString)
|
|
2448
|
+
spaceWidth = config.measureTextWidth(" ", fontString);
|
|
2448
2449
|
} else {
|
|
2449
2450
|
const spaceWord = await this.measureWord(" ", measurementConfig);
|
|
2450
|
-
spaceWidth = spaceWord.width
|
|
2451
|
+
spaceWidth = spaceWord.width;
|
|
2451
2452
|
}
|
|
2452
2453
|
const groups = wordGroups.flatMap((indices) => {
|
|
2453
2454
|
const groupWidths = indices.map((i) => store.widths[i]);
|
|
@@ -3019,7 +3020,7 @@ function extractCaptionBorder(asset) {
|
|
|
3019
3020
|
};
|
|
3020
3021
|
}
|
|
3021
3022
|
function extractTextDecoration(asset, isActive) {
|
|
3022
|
-
const baseDecoration = asset.
|
|
3023
|
+
const baseDecoration = asset.style?.textDecoration;
|
|
3023
3024
|
const activeDecoration = asset.active?.font?.textDecoration;
|
|
3024
3025
|
if (isActive && activeDecoration !== void 0) {
|
|
3025
3026
|
return activeDecoration === "none" ? void 0 : activeDecoration;
|
|
@@ -5082,11 +5083,14 @@ function extractSvgDimensions(svgString) {
|
|
|
5082
5083
|
}
|
|
5083
5084
|
|
|
5084
5085
|
// src/core/canvas-text-measurer.ts
|
|
5085
|
-
async function createCanvasTextMeasurer() {
|
|
5086
|
+
async function createCanvasTextMeasurer(letterSpacing) {
|
|
5086
5087
|
const canvasMod = await import("canvas");
|
|
5087
5088
|
const canvas = canvasMod.createCanvas(1, 1);
|
|
5088
5089
|
const ctx = canvas.getContext("2d");
|
|
5089
5090
|
ctx.textBaseline = "alphabetic";
|
|
5091
|
+
if (letterSpacing) {
|
|
5092
|
+
ctx.letterSpacing = `${letterSpacing}px`;
|
|
5093
|
+
}
|
|
5090
5094
|
let lastFont = "";
|
|
5091
5095
|
return (text, font) => {
|
|
5092
5096
|
if (font !== lastFont) {
|
|
@@ -5865,7 +5869,7 @@ var RichCaptionRenderer = class {
|
|
|
5865
5869
|
}
|
|
5866
5870
|
const font = asset.font;
|
|
5867
5871
|
const style = asset.style;
|
|
5868
|
-
const measureTextWidth = await createCanvasTextMeasurer();
|
|
5872
|
+
const measureTextWidth = await createCanvasTextMeasurer(style?.letterSpacing ?? 0);
|
|
5869
5873
|
const fontSize = font?.size ?? 24;
|
|
5870
5874
|
const lineHeight = style?.lineHeight ?? 1.2;
|
|
5871
5875
|
const padding = extractCaptionPadding(asset);
|
|
@@ -5886,7 +5890,6 @@ var RichCaptionRenderer = class {
|
|
|
5886
5890
|
fontFamily: font?.family ?? "Roboto",
|
|
5887
5891
|
fontWeight: String(font?.weight ?? "400"),
|
|
5888
5892
|
letterSpacing: style?.letterSpacing ?? 0,
|
|
5889
|
-
wordSpacing: typeof style?.wordSpacing === "number" ? style.wordSpacing : 0,
|
|
5890
5893
|
lineHeight,
|
|
5891
5894
|
textTransform: style?.textTransform ?? "none",
|
|
5892
5895
|
pauseThreshold: this.currentAsset?.pauseThreshold ?? 500,
|
|
@@ -6440,6 +6443,7 @@ async function createTextEngine(opts = {}) {
|
|
|
6440
6443
|
text: asset.text,
|
|
6441
6444
|
width: (asset.width ?? width) - padding2.left - padding2.right,
|
|
6442
6445
|
letterSpacing: asset.style?.letterSpacing ?? 0,
|
|
6446
|
+
wordSpacing: typeof asset.style?.wordSpacing === "number" ? asset.style.wordSpacing : 0,
|
|
6443
6447
|
fontSize: main.size,
|
|
6444
6448
|
lineHeight: asset.style?.lineHeight ?? 1.2,
|
|
6445
6449
|
desc,
|
package/dist/entry.web.d.ts
CHANGED
|
@@ -271,14 +271,8 @@ declare const richCaptionAssetSchema: z.ZodObject<{
|
|
|
271
271
|
color: z.ZodDefault<z.ZodString>;
|
|
272
272
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
273
273
|
background: z.ZodOptional<z.ZodString>;
|
|
274
|
-
textDecoration: z.ZodDefault<z.ZodEnum<{
|
|
275
|
-
none: "none";
|
|
276
|
-
underline: "underline";
|
|
277
|
-
"line-through": "line-through";
|
|
278
|
-
}>>;
|
|
279
274
|
}, z.core.$strip>>;
|
|
280
275
|
style: z.ZodOptional<z.ZodObject<{
|
|
281
|
-
wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
|
|
282
276
|
letterSpacing: z.ZodDefault<z.ZodNumber>;
|
|
283
277
|
lineHeight: z.ZodDefault<z.ZodNumber>;
|
|
284
278
|
textTransform: z.ZodDefault<z.ZodEnum<{
|
|
@@ -413,14 +407,8 @@ declare const CanvasRichCaptionAssetSchema: z.ZodObject<{
|
|
|
413
407
|
color: z.ZodDefault<z.ZodString>;
|
|
414
408
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
415
409
|
background: z.ZodOptional<z.ZodString>;
|
|
416
|
-
textDecoration: z.ZodDefault<z.ZodEnum<{
|
|
417
|
-
none: "none";
|
|
418
|
-
underline: "underline";
|
|
419
|
-
"line-through": "line-through";
|
|
420
|
-
}>>;
|
|
421
410
|
}, z.core.$strip>>;
|
|
422
411
|
style: z.ZodOptional<z.ZodObject<{
|
|
423
|
-
wordSpacing: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>, z.ZodString]>>>;
|
|
424
412
|
letterSpacing: z.ZodDefault<z.ZodNumber>;
|
|
425
413
|
lineHeight: z.ZodDefault<z.ZodNumber>;
|
|
426
414
|
textTransform: z.ZodDefault<z.ZodEnum<{
|
|
@@ -661,7 +649,6 @@ interface CaptionLayoutConfig {
|
|
|
661
649
|
fontFamily: string;
|
|
662
650
|
fontWeight: string | number;
|
|
663
651
|
letterSpacing: number;
|
|
664
|
-
wordSpacing: number;
|
|
665
652
|
lineHeight: number;
|
|
666
653
|
textTransform: "none" | "uppercase" | "lowercase" | "capitalize";
|
|
667
654
|
pauseThreshold: number;
|
package/dist/entry.web.js
CHANGED
|
@@ -17978,6 +17978,7 @@ var canvasStyleSchema = richTextStyleSchema.extend({
|
|
|
17978
17978
|
textDecoration: external_exports.enum(["none", "underline", "line-through"]).default("none"),
|
|
17979
17979
|
gradient: canvasGradientSchema.optional()
|
|
17980
17980
|
});
|
|
17981
|
+
var captionStyleSchema = canvasStyleSchema.omit({ wordSpacing: true });
|
|
17981
17982
|
var canvasStrokeSchema = richTextStrokeSchema.extend({
|
|
17982
17983
|
width: external_exports.number().min(0).default(0),
|
|
17983
17984
|
color: external_exports.string().regex(HEX6).default("#000000"),
|
|
@@ -18065,8 +18066,7 @@ var richCaptionFontSchema = external_exports.object({
|
|
|
18065
18066
|
weight: external_exports.union([external_exports.string(), external_exports.number()]).default("400"),
|
|
18066
18067
|
color: external_exports.string().regex(HEX6).default("#ffffff"),
|
|
18067
18068
|
opacity: external_exports.number().min(0).max(1).default(1),
|
|
18068
|
-
background: external_exports.string().regex(HEX6).optional()
|
|
18069
|
-
textDecoration: external_exports.enum(["none", "underline", "line-through"]).default("none")
|
|
18069
|
+
background: external_exports.string().regex(HEX6).optional()
|
|
18070
18070
|
});
|
|
18071
18071
|
var richCaptionActiveSchema = baseCaptionActiveSchema.extend({
|
|
18072
18072
|
font: external_exports.object({
|
|
@@ -18104,7 +18104,7 @@ var richCaptionAssetSchema = external_exports.object({
|
|
|
18104
18104
|
src: external_exports.string().min(1).optional(),
|
|
18105
18105
|
words: external_exports.array(wordTimingSchema).max(1e5).optional(),
|
|
18106
18106
|
font: richCaptionFontSchema.optional(),
|
|
18107
|
-
style:
|
|
18107
|
+
style: captionStyleSchema.optional(),
|
|
18108
18108
|
stroke: canvasStrokeSchema.optional(),
|
|
18109
18109
|
shadow: canvasShadowSchema.optional(),
|
|
18110
18110
|
background: canvasBackgroundSchema.optional(),
|
|
@@ -33170,7 +33170,7 @@ var LayoutEngine = class {
|
|
|
33170
33170
|
}
|
|
33171
33171
|
async layout(params) {
|
|
33172
33172
|
try {
|
|
33173
|
-
const { textTransform, desc, fontSize, letterSpacing, width, emojiFallback } = params;
|
|
33173
|
+
const { textTransform, desc, fontSize, letterSpacing, wordSpacing = 0, width, emojiFallback } = params;
|
|
33174
33174
|
const input = this.transformText(params.text, textTransform);
|
|
33175
33175
|
if (!input || input.length === 0) {
|
|
33176
33176
|
return [];
|
|
@@ -33200,9 +33200,10 @@ var LayoutEngine = class {
|
|
|
33200
33200
|
char = String.fromCodePoint(codePoint);
|
|
33201
33201
|
}
|
|
33202
33202
|
}
|
|
33203
|
+
const isSpace = char === " ";
|
|
33203
33204
|
return {
|
|
33204
33205
|
id: g.g,
|
|
33205
|
-
xAdvance: g.ax * scale + letterSpacing,
|
|
33206
|
+
xAdvance: g.ax * scale + letterSpacing + (isSpace ? wordSpacing : 0),
|
|
33206
33207
|
xOffset: g.dx * scale,
|
|
33207
33208
|
yOffset: -g.dy * scale,
|
|
33208
33209
|
cluster: g.cl,
|
|
@@ -35037,10 +35038,10 @@ var CaptionLayoutEngine = class {
|
|
|
35037
35038
|
let spaceWidth;
|
|
35038
35039
|
if (config2.measureTextWidth) {
|
|
35039
35040
|
const fontString = `${config2.fontWeight} ${config2.fontSize}px "${config2.fontFamily}"`;
|
|
35040
|
-
spaceWidth = config2.measureTextWidth(" ", fontString)
|
|
35041
|
+
spaceWidth = config2.measureTextWidth(" ", fontString);
|
|
35041
35042
|
} else {
|
|
35042
35043
|
const spaceWord = await this.measureWord(" ", measurementConfig);
|
|
35043
|
-
spaceWidth = spaceWord.width
|
|
35044
|
+
spaceWidth = spaceWord.width;
|
|
35044
35045
|
}
|
|
35045
35046
|
const groups = wordGroups.flatMap((indices) => {
|
|
35046
35047
|
const groupWidths = indices.map((i) => store.widths[i]);
|
|
@@ -35612,7 +35613,7 @@ function extractCaptionBorder(asset) {
|
|
|
35612
35613
|
};
|
|
35613
35614
|
}
|
|
35614
35615
|
function extractTextDecoration(asset, isActive) {
|
|
35615
|
-
const baseDecoration = asset.
|
|
35616
|
+
const baseDecoration = asset.style?.textDecoration;
|
|
35616
35617
|
const activeDecoration = asset.active?.font?.textDecoration;
|
|
35617
35618
|
if (isActive && activeDecoration !== void 0) {
|
|
35618
35619
|
return activeDecoration === "none" ? void 0 : activeDecoration;
|
|
@@ -38115,6 +38116,7 @@ async function createTextEngine(opts = {}) {
|
|
|
38115
38116
|
text: asset.text,
|
|
38116
38117
|
width: (asset.width ?? width) - padding2.left - padding2.right,
|
|
38117
38118
|
letterSpacing: asset.style?.letterSpacing ?? 0,
|
|
38119
|
+
wordSpacing: typeof asset.style?.wordSpacing === "number" ? asset.style.wordSpacing : 0,
|
|
38118
38120
|
fontSize: main.size,
|
|
38119
38121
|
lineHeight: asset.style?.lineHeight ?? 1.2,
|
|
38120
38122
|
desc,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shotstack/shotstack-canvas",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "Text layout & animation engine (HarfBuzz) for Node & Web - fully self-contained.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/entry.node.cjs",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@resvg/resvg-js": "^2.6.2",
|
|
53
53
|
"@resvg/resvg-wasm": "^2.6.2",
|
|
54
|
-
"@shotstack/schemas": "1.9.
|
|
54
|
+
"@shotstack/schemas": "1.9.2",
|
|
55
55
|
"bidi-js": "^1.0.3",
|
|
56
56
|
"canvas": "npm:@napi-rs/canvas@^0.1.54",
|
|
57
57
|
"ffmpeg-static": "^5.2.0",
|