@clypra/engine 1.1.1 → 1.1.2
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/index.cjs +413 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +157 -1
- package/dist/index.d.ts +157 -1
- package/dist/index.js +405 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var index_exports = {};
|
|
|
21
21
|
__export(index_exports, {
|
|
22
22
|
COMPOSITION_PRESETS: () => COMPOSITION_PRESETS,
|
|
23
23
|
CUSTOM_ENGINE_IDS: () => CUSTOM_ENGINE_IDS,
|
|
24
|
+
CanvasDevice: () => CanvasDevice,
|
|
24
25
|
DEFAULT_CANVAS_HEIGHT: () => DEFAULT_CANVAS_HEIGHT,
|
|
25
26
|
DEFAULT_CANVAS_WIDTH: () => DEFAULT_CANVAS_WIDTH,
|
|
26
27
|
DEFAULT_DURATION: () => DEFAULT_DURATION,
|
|
@@ -32,6 +33,7 @@ __export(index_exports, {
|
|
|
32
33
|
ENTRANCE_PRESETS: () => ENTRANCE_PRESETS,
|
|
33
34
|
EXIT_PRESETS: () => EXIT_PRESETS,
|
|
34
35
|
FONT_WEIGHT_OPTIONS: () => FONT_WEIGHT_OPTIONS,
|
|
36
|
+
FontLoader: () => FontLoader,
|
|
35
37
|
InkBrushEngine: () => InkBrushEngine,
|
|
36
38
|
LEGACY_RENDERER_MAP: () => LEGACY_RENDERER_MAP,
|
|
37
39
|
LOOP_PRESETS: () => LOOP_PRESETS,
|
|
@@ -43,6 +45,7 @@ __export(index_exports, {
|
|
|
43
45
|
TextEffectRenderer: () => TextEffectRenderer,
|
|
44
46
|
WEBM_EXPORT_MAX_FRAMES: () => WEBM_EXPORT_MAX_FRAMES,
|
|
45
47
|
WebGLCompositor: () => WebGLCompositor,
|
|
48
|
+
_buildConfig: () => _buildConfig,
|
|
46
49
|
_resetPlatformCache: () => _resetPlatformCache,
|
|
47
50
|
addImageLayer: () => addImageLayer,
|
|
48
51
|
addKeyframeAtTime: () => addKeyframeAtTime,
|
|
@@ -100,6 +103,7 @@ __export(index_exports, {
|
|
|
100
103
|
encodeGif: () => encodeGif,
|
|
101
104
|
ensureDefaultTimeline: () => ensureDefaultTimeline,
|
|
102
105
|
ensureFontInLottie: () => ensureFontInLottie,
|
|
106
|
+
ensureFontsLoaded: () => ensureFontsLoaded,
|
|
103
107
|
evaluateConfig: () => evaluateConfig,
|
|
104
108
|
evaluateScene: () => evaluateScene,
|
|
105
109
|
findTrackIndex: () => findTrackIndex,
|
|
@@ -107,6 +111,7 @@ __export(index_exports, {
|
|
|
107
111
|
getAnimatableParamDef: () => getAnimatableParamDef,
|
|
108
112
|
getAnimatableParamsForLayer: () => getAnimatableParamsForLayer,
|
|
109
113
|
getDefaultText: () => getDefaultText,
|
|
114
|
+
getFontLoader: () => getFontLoader,
|
|
110
115
|
getLayerById: () => getLayerById,
|
|
111
116
|
getPresetScene: () => getPresetScene,
|
|
112
117
|
getSceneTime: () => getSceneTime,
|
|
@@ -125,6 +130,7 @@ __export(index_exports, {
|
|
|
125
130
|
injectText: () => injectText,
|
|
126
131
|
injectTextStyle: () => injectTextStyle,
|
|
127
132
|
isWebMExportSupported: () => isWebMExportSupported,
|
|
133
|
+
layerToTextEffectConfig: () => layerToTextEffectConfig,
|
|
128
134
|
loadLottieFonts: () => loadLottieFonts,
|
|
129
135
|
lottieColorToHex: () => lottieColorToHex,
|
|
130
136
|
lottieJToAlign: () => lottieJToAlign,
|
|
@@ -147,10 +153,12 @@ __export(index_exports, {
|
|
|
147
153
|
renderPngSequence: () => renderPngSequence,
|
|
148
154
|
renderSceneWebM: () => renderSceneWebM,
|
|
149
155
|
renderTextEffectCore: () => renderTextEffectCore,
|
|
156
|
+
resetFontLoader: () => resetFontLoader,
|
|
150
157
|
resetSceneTime: () => resetSceneTime,
|
|
151
158
|
resizeCharFillColors: () => resizeCharFillColors,
|
|
152
159
|
resolveAnimatedScalar: () => resolveAnimatedScalar,
|
|
153
160
|
resolveCustomEngineId: () => resolveCustomEngineId,
|
|
161
|
+
resolveFontFamilyName: () => resolveFontFamilyName,
|
|
154
162
|
restoreLetterSpacing: () => restoreLetterSpacing,
|
|
155
163
|
scanLottieFonts: () => scanLottieFonts,
|
|
156
164
|
scanTextLayers: () => scanTextLayers,
|
|
@@ -568,6 +576,46 @@ function _resetPlatformCache() {
|
|
|
568
576
|
_offscreenCanvas = null;
|
|
569
577
|
_webgl2 = null;
|
|
570
578
|
}
|
|
579
|
+
var CanvasDevice = class {
|
|
580
|
+
static canvases = [];
|
|
581
|
+
static maxPoolSize = 10;
|
|
582
|
+
/**
|
|
583
|
+
* Acquire a Canvas context from the pool or create a new one.
|
|
584
|
+
* If a canvas is pulled from the pool, it is resized to the target dimensions.
|
|
585
|
+
*/
|
|
586
|
+
static acquire(width, height) {
|
|
587
|
+
let canvas;
|
|
588
|
+
if (this.canvases.length > 0) {
|
|
589
|
+
canvas = this.canvases.pop();
|
|
590
|
+
if (canvas.width !== width || canvas.height !== height) {
|
|
591
|
+
canvas.width = width;
|
|
592
|
+
canvas.height = height;
|
|
593
|
+
}
|
|
594
|
+
} else {
|
|
595
|
+
canvas = createCanvas(width, height);
|
|
596
|
+
}
|
|
597
|
+
return canvas;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Release a canvas back to the pool, or free its resources immediately if pool is full.
|
|
601
|
+
*/
|
|
602
|
+
static release(canvas) {
|
|
603
|
+
if (this.canvases.length < this.maxPoolSize) {
|
|
604
|
+
this.canvases.push(canvas);
|
|
605
|
+
} else {
|
|
606
|
+
releaseCanvas(canvas);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Disposes all pooled canvases to release GPU/memory backing stores.
|
|
611
|
+
*/
|
|
612
|
+
static clearPool() {
|
|
613
|
+
while (this.canvases.length > 0) {
|
|
614
|
+
const c = this.canvases.pop();
|
|
615
|
+
releaseCanvas(c);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
};
|
|
571
619
|
|
|
572
620
|
// src/engine/procedural/utils.ts
|
|
573
621
|
function getCanvas2DContext(canvas) {
|
|
@@ -2530,6 +2578,146 @@ function checkFontVariant(variantName) {
|
|
|
2530
2578
|
if (typeof document === "undefined" || !document.fonts) return false;
|
|
2531
2579
|
return document.fonts.check(`16px "${variantName}"`);
|
|
2532
2580
|
}
|
|
2581
|
+
var FontLoader = class {
|
|
2582
|
+
state = {
|
|
2583
|
+
loading: /* @__PURE__ */ new Set(),
|
|
2584
|
+
loaded: /* @__PURE__ */ new Set(),
|
|
2585
|
+
failed: /* @__PURE__ */ new Map(),
|
|
2586
|
+
promises: /* @__PURE__ */ new Map()
|
|
2587
|
+
};
|
|
2588
|
+
async ensureFont(descriptor) {
|
|
2589
|
+
const key = this.getFontKey(descriptor);
|
|
2590
|
+
if (this.state.loaded.has(key)) {
|
|
2591
|
+
return {
|
|
2592
|
+
font: descriptor,
|
|
2593
|
+
loaded: true,
|
|
2594
|
+
loadTimeMs: 0
|
|
2595
|
+
};
|
|
2596
|
+
}
|
|
2597
|
+
if (this.state.failed.has(key)) {
|
|
2598
|
+
return {
|
|
2599
|
+
font: descriptor,
|
|
2600
|
+
loaded: false,
|
|
2601
|
+
error: this.state.failed.get(key),
|
|
2602
|
+
loadTimeMs: 0
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2605
|
+
if (this.state.promises.has(key)) {
|
|
2606
|
+
return this.state.promises.get(key);
|
|
2607
|
+
}
|
|
2608
|
+
const promise = this.loadFont(descriptor);
|
|
2609
|
+
this.state.promises.set(key, promise);
|
|
2610
|
+
return promise;
|
|
2611
|
+
}
|
|
2612
|
+
async ensureFonts(descriptors) {
|
|
2613
|
+
return Promise.all(descriptors.map((desc) => this.ensureFont(desc)));
|
|
2614
|
+
}
|
|
2615
|
+
async waitForFontsReady() {
|
|
2616
|
+
if (typeof document === "undefined" || !document.fonts) {
|
|
2617
|
+
return;
|
|
2618
|
+
}
|
|
2619
|
+
await document.fonts.ready;
|
|
2620
|
+
}
|
|
2621
|
+
isLoaded(descriptor) {
|
|
2622
|
+
const key = this.getFontKey(descriptor);
|
|
2623
|
+
return this.state.loaded.has(key);
|
|
2624
|
+
}
|
|
2625
|
+
getStats() {
|
|
2626
|
+
return {
|
|
2627
|
+
loaded: this.state.loaded.size,
|
|
2628
|
+
loading: this.state.loading.size,
|
|
2629
|
+
failed: this.state.failed.size
|
|
2630
|
+
};
|
|
2631
|
+
}
|
|
2632
|
+
clear() {
|
|
2633
|
+
this.state.loading.clear();
|
|
2634
|
+
this.state.loaded.clear();
|
|
2635
|
+
this.state.failed.clear();
|
|
2636
|
+
this.state.promises.clear();
|
|
2637
|
+
}
|
|
2638
|
+
async loadFont(descriptor) {
|
|
2639
|
+
const key = this.getFontKey(descriptor);
|
|
2640
|
+
const startTime = performance.now();
|
|
2641
|
+
this.state.loading.add(key);
|
|
2642
|
+
try {
|
|
2643
|
+
if (typeof document === "undefined" || !document.fonts) {
|
|
2644
|
+
throw new Error("Font API not available");
|
|
2645
|
+
}
|
|
2646
|
+
const weight = this.normalizeFontWeight(descriptor.weight);
|
|
2647
|
+
const style = descriptor.style || "normal";
|
|
2648
|
+
const fontFace = `${style} ${weight} 16px "${descriptor.family}"`;
|
|
2649
|
+
if (document.fonts.check(fontFace)) {
|
|
2650
|
+
this.state.loaded.add(key);
|
|
2651
|
+
this.state.loading.delete(key);
|
|
2652
|
+
this.state.promises.delete(key);
|
|
2653
|
+
return {
|
|
2654
|
+
font: descriptor,
|
|
2655
|
+
loaded: true,
|
|
2656
|
+
loadTimeMs: performance.now() - startTime
|
|
2657
|
+
};
|
|
2658
|
+
}
|
|
2659
|
+
await document.fonts.load(fontFace);
|
|
2660
|
+
if (!document.fonts.check(fontFace)) {
|
|
2661
|
+
throw new Error(`Font "${descriptor.family}" failed to load`);
|
|
2662
|
+
}
|
|
2663
|
+
this.state.loaded.add(key);
|
|
2664
|
+
this.state.loading.delete(key);
|
|
2665
|
+
this.state.promises.delete(key);
|
|
2666
|
+
return {
|
|
2667
|
+
font: descriptor,
|
|
2668
|
+
loaded: true,
|
|
2669
|
+
loadTimeMs: performance.now() - startTime
|
|
2670
|
+
};
|
|
2671
|
+
} catch (error) {
|
|
2672
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
2673
|
+
this.state.failed.set(key, errorMessage);
|
|
2674
|
+
this.state.loading.delete(key);
|
|
2675
|
+
this.state.promises.delete(key);
|
|
2676
|
+
return {
|
|
2677
|
+
font: descriptor,
|
|
2678
|
+
loaded: false,
|
|
2679
|
+
error: errorMessage,
|
|
2680
|
+
loadTimeMs: performance.now() - startTime
|
|
2681
|
+
};
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
getFontKey(descriptor) {
|
|
2685
|
+
const weight = this.normalizeFontWeight(descriptor.weight);
|
|
2686
|
+
const style = descriptor.style || "normal";
|
|
2687
|
+
return `${descriptor.family}|${weight}|${style}`;
|
|
2688
|
+
}
|
|
2689
|
+
normalizeFontWeight(weight) {
|
|
2690
|
+
if (typeof weight === "number") {
|
|
2691
|
+
return weight;
|
|
2692
|
+
}
|
|
2693
|
+
if (!weight) return 400;
|
|
2694
|
+
const asNum = parseInt(weight, 10);
|
|
2695
|
+
if (!isNaN(asNum) && asNum >= 100 && asNum <= 900) {
|
|
2696
|
+
return asNum;
|
|
2697
|
+
}
|
|
2698
|
+
const weightMap = {
|
|
2699
|
+
normal: 400,
|
|
2700
|
+
bold: 700,
|
|
2701
|
+
lighter: 300,
|
|
2702
|
+
bolder: 700
|
|
2703
|
+
};
|
|
2704
|
+
return weightMap[weight] ?? 400;
|
|
2705
|
+
}
|
|
2706
|
+
};
|
|
2707
|
+
var globalFontLoader = null;
|
|
2708
|
+
function getFontLoader() {
|
|
2709
|
+
if (!globalFontLoader) {
|
|
2710
|
+
globalFontLoader = new FontLoader();
|
|
2711
|
+
}
|
|
2712
|
+
return globalFontLoader;
|
|
2713
|
+
}
|
|
2714
|
+
function resetFontLoader() {
|
|
2715
|
+
globalFontLoader = null;
|
|
2716
|
+
}
|
|
2717
|
+
async function ensureFontsLoaded(descriptors) {
|
|
2718
|
+
const loader = getFontLoader();
|
|
2719
|
+
return loader.ensureFonts(descriptors);
|
|
2720
|
+
}
|
|
2533
2721
|
|
|
2534
2722
|
// src/engine/timelineDefaults.ts
|
|
2535
2723
|
function ensureDefaultTimeline(doc) {
|
|
@@ -2901,6 +3089,212 @@ function mergeSceneIntoConfig(doc, base) {
|
|
|
2901
3089
|
const out = sceneToConfig({ ...doc, legacyConfig: base });
|
|
2902
3090
|
return out;
|
|
2903
3091
|
}
|
|
3092
|
+
function resolveFontFamilyName(fontFamily) {
|
|
3093
|
+
const f = fontFamily?.toLowerCase() || "";
|
|
3094
|
+
if (f.includes("inter")) return "Inter Variable";
|
|
3095
|
+
if (f.includes("montserrat")) return "Montserrat Variable";
|
|
3096
|
+
if (f.includes("geist")) return "Geist Variable";
|
|
3097
|
+
if (f.includes("space grotesk") || f.includes("grotesk")) return "Space Grotesk Variable";
|
|
3098
|
+
if (f.includes("outfit")) return "Outfit Variable";
|
|
3099
|
+
if (f.includes("roboto variable")) return "Roboto Variable";
|
|
3100
|
+
if (f.includes("roboto condensed")) return "Roboto Condensed";
|
|
3101
|
+
if (f === "roboto") return "Roboto Variable";
|
|
3102
|
+
if (f.includes("open sans")) return "Open Sans Variable";
|
|
3103
|
+
if (f.includes("raleway")) return "Raleway Variable";
|
|
3104
|
+
if (f.includes("oswald")) return "Oswald Variable";
|
|
3105
|
+
if (f.includes("playfair display")) return "Playfair Display Variable";
|
|
3106
|
+
if (f.includes("nunito")) return "Nunito Variable";
|
|
3107
|
+
if (f.includes("dancing script")) return "Dancing Script Variable";
|
|
3108
|
+
if (f === "lato") return "Lato";
|
|
3109
|
+
if (f === "anton") return "Anton";
|
|
3110
|
+
if (f === "bebas neue") return "Bebas Neue";
|
|
3111
|
+
if (f === "poppins") return "Poppins";
|
|
3112
|
+
if (f === "permanent marker") return "Permanent Marker";
|
|
3113
|
+
if (f === "bangers") return "Bangers";
|
|
3114
|
+
if (f === "press start 2p") return "Press Start 2P";
|
|
3115
|
+
if (f === "pacifico") return "Pacifico";
|
|
3116
|
+
return fontFamily;
|
|
3117
|
+
}
|
|
3118
|
+
function _buildConfig(effect, text, fontSize, canvasWidth, canvasHeight, time, clipStartTime, clipDuration) {
|
|
3119
|
+
const fill = effect.fills?.[0];
|
|
3120
|
+
const stroke = effect.strokes?.[0];
|
|
3121
|
+
const shadow = effect.shadows?.[0];
|
|
3122
|
+
const bevel = effect.bevel;
|
|
3123
|
+
const panel = effect.panel;
|
|
3124
|
+
const ratio = fontSize / 100;
|
|
3125
|
+
const config = {
|
|
3126
|
+
// Canvas / text
|
|
3127
|
+
width: canvasWidth,
|
|
3128
|
+
height: canvasHeight,
|
|
3129
|
+
canvasWidth,
|
|
3130
|
+
canvasHeight,
|
|
3131
|
+
text,
|
|
3132
|
+
time: time ?? 0,
|
|
3133
|
+
clipStartTime: clipStartTime ?? 0,
|
|
3134
|
+
clipDuration: clipDuration ?? 5,
|
|
3135
|
+
// Font
|
|
3136
|
+
fontFamily: resolveFontFamilyName(effect.font.family),
|
|
3137
|
+
fontWeight: effect.font.weight,
|
|
3138
|
+
fontStyle: effect.font.style,
|
|
3139
|
+
fontSize,
|
|
3140
|
+
letterSpacing: effect.font.letterSpacing,
|
|
3141
|
+
lineHeight: effect.font.lineHeight
|
|
3142
|
+
};
|
|
3143
|
+
if (effect.animation) {
|
|
3144
|
+
config.animation = effect.animation;
|
|
3145
|
+
}
|
|
3146
|
+
if (fill) {
|
|
3147
|
+
if (fill.type !== void 0) config.fillType = fill.type;
|
|
3148
|
+
if (fill.color !== void 0) config.fillColor = fill.color;
|
|
3149
|
+
if (fill.gradient?.angle !== void 0) config.fillGradientAngle = fill.gradient.angle;
|
|
3150
|
+
if (fill.gradient?.stops !== void 0) config.fillGradientStops = fill.gradient.stops;
|
|
3151
|
+
if (fill.patternType !== void 0) config.patternType = fill.patternType;
|
|
3152
|
+
if (fill.perCharFillEnabled !== void 0) config.perCharFillEnabled = fill.perCharFillEnabled;
|
|
3153
|
+
if (fill.charFillColors !== void 0) config.charFillColors = fill.charFillColors;
|
|
3154
|
+
} else {
|
|
3155
|
+
config.fillType = "none";
|
|
3156
|
+
}
|
|
3157
|
+
config.strokeEnabled = !!stroke;
|
|
3158
|
+
if (stroke) {
|
|
3159
|
+
if (stroke.color !== void 0) config.strokeColor = stroke.color;
|
|
3160
|
+
if (stroke.width !== void 0) config.strokeWidth = stroke.width * ratio;
|
|
3161
|
+
if (stroke.position !== void 0) config.strokePosition = stroke.position;
|
|
3162
|
+
if (stroke.opacity !== void 0) config.strokeOpacity = stroke.opacity;
|
|
3163
|
+
if (stroke.lineJoin !== void 0) config.strokeLineJoin = stroke.lineJoin;
|
|
3164
|
+
if (stroke.blur !== void 0) config.strokeBlur = stroke.blur * ratio;
|
|
3165
|
+
if (stroke.type !== void 0) config.strokeType = stroke.type;
|
|
3166
|
+
if (stroke.colorSecondary !== void 0) config.strokeColorSecondary = stroke.colorSecondary;
|
|
3167
|
+
if (stroke.widthSecondary !== void 0) config.strokeWidthSecondary = stroke.widthSecondary * ratio;
|
|
3168
|
+
if (stroke.fadeRange !== void 0) config.strokeFadeRange = stroke.fadeRange;
|
|
3169
|
+
}
|
|
3170
|
+
config.shadowEnabled = !!shadow;
|
|
3171
|
+
if (shadow) {
|
|
3172
|
+
if (shadow.color !== void 0) config.shadowColor = shadow.color;
|
|
3173
|
+
if (shadow.blur !== void 0) config.shadowBlur = shadow.blur * ratio;
|
|
3174
|
+
if (shadow.offsetX !== void 0) config.shadowOffsetX = shadow.offsetX * ratio;
|
|
3175
|
+
if (shadow.offsetY !== void 0) config.shadowOffsetY = shadow.offsetY * ratio;
|
|
3176
|
+
if (shadow.opacity !== void 0) config.shadowOpacity = shadow.opacity;
|
|
3177
|
+
if (shadow.type !== void 0) config.shadowType = shadow.type;
|
|
3178
|
+
}
|
|
3179
|
+
config.bevelEnabled = !!bevel;
|
|
3180
|
+
if (bevel) {
|
|
3181
|
+
if (bevel.depth !== void 0) config.bevelDepth = Math.round(bevel.depth * ratio);
|
|
3182
|
+
if (bevel.highlightColor !== void 0) config.bevelHighlight = bevel.highlightColor;
|
|
3183
|
+
if (bevel.shadowColor !== void 0) config.bevelShadow = bevel.shadowColor;
|
|
3184
|
+
if (bevel.direction !== void 0) config.bevelDirection = bevel.direction;
|
|
3185
|
+
if (bevel.coreColor !== void 0) config.bevelCoreColor = bevel.coreColor;
|
|
3186
|
+
if (bevel.edgeColor !== void 0) config.bevelEdgeColor = bevel.edgeColor;
|
|
3187
|
+
if (bevel.edgeWidth !== void 0) config.bevelEdgeWidth = bevel.edgeWidth * ratio;
|
|
3188
|
+
if (bevel.blur !== void 0) config.bevelBlur = bevel.blur * ratio;
|
|
3189
|
+
if (bevel.blurColor !== void 0) config.bevelBlurColor = bevel.blurColor;
|
|
3190
|
+
if (bevel.perspectiveEnabled !== void 0) config.bevelPerspectiveEnabled = bevel.perspectiveEnabled;
|
|
3191
|
+
if (bevel.vanishingPointX !== void 0) config.bevelVanishingPointX = bevel.vanishingPointX;
|
|
3192
|
+
if (bevel.vanishingPointY !== void 0) config.bevelVanishingPointY = bevel.vanishingPointY;
|
|
3193
|
+
if (bevel.focalLength !== void 0) config.bevelFocalLength = bevel.focalLength;
|
|
3194
|
+
}
|
|
3195
|
+
if (effect.stack) {
|
|
3196
|
+
config.stackEnabled = !!effect.stack.count;
|
|
3197
|
+
if (effect.stack.count !== void 0) config.stackCount = effect.stack.count;
|
|
3198
|
+
if (effect.stack.offsetX !== void 0) config.stackOffsetX = effect.stack.offsetX * ratio;
|
|
3199
|
+
if (effect.stack.offsetY !== void 0) config.stackOffsetY = effect.stack.offsetY * ratio;
|
|
3200
|
+
if (effect.stack.opacityDecay !== void 0) config.stackOpacityDecay = effect.stack.opacityDecay;
|
|
3201
|
+
if (effect.stack.color1 !== void 0) config.stackColor1 = effect.stack.color1;
|
|
3202
|
+
if (effect.stack.color2 !== void 0) config.stackColor2 = effect.stack.color2;
|
|
3203
|
+
if (effect.stack.color3 !== void 0) config.stackColor3 = effect.stack.color3;
|
|
3204
|
+
if (effect.stack.color4 !== void 0) config.stackColor4 = effect.stack.color4;
|
|
3205
|
+
}
|
|
3206
|
+
config.panelEnabled = !!panel;
|
|
3207
|
+
if (panel) {
|
|
3208
|
+
if (panel.color !== void 0) config.panelColor = panel.color;
|
|
3209
|
+
if (panel.opacity !== void 0) config.panelOpacity = panel.opacity;
|
|
3210
|
+
if (panel.radius !== void 0) config.panelRadius = panel.radius;
|
|
3211
|
+
if (panel.paddingX !== void 0) config.panelPaddingX = panel.paddingX * ratio;
|
|
3212
|
+
if (panel.paddingY !== void 0) config.panelPaddingY = panel.paddingY * ratio;
|
|
3213
|
+
if (panel.stroke !== void 0) {
|
|
3214
|
+
config.panelStrokeEnabled = !!panel.stroke;
|
|
3215
|
+
if (panel.stroke.color !== void 0) config.panelStrokeColor = panel.stroke.color;
|
|
3216
|
+
if (panel.stroke.width !== void 0) config.panelStrokeWidth = panel.stroke.width * ratio;
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
if (effect.glows) {
|
|
3220
|
+
config.glowLayers = effect.glows.map((g) => {
|
|
3221
|
+
const mappedGlow = {
|
|
3222
|
+
enabled: true,
|
|
3223
|
+
color: g.color,
|
|
3224
|
+
blur: typeof g.blur === "number" ? g.blur * ratio : g.blur ?? 0,
|
|
3225
|
+
opacity: g.opacity,
|
|
3226
|
+
type: g.type ?? "outer"
|
|
3227
|
+
};
|
|
3228
|
+
if (g.strength !== void 0) mappedGlow.strength = g.strength;
|
|
3229
|
+
if (g.spread !== void 0) mappedGlow.spread = g.spread * ratio;
|
|
3230
|
+
return mappedGlow;
|
|
3231
|
+
});
|
|
3232
|
+
}
|
|
3233
|
+
const standardKeys = /* @__PURE__ */ new Set([
|
|
3234
|
+
"id",
|
|
3235
|
+
"name",
|
|
3236
|
+
"category",
|
|
3237
|
+
"description",
|
|
3238
|
+
"tags",
|
|
3239
|
+
"font",
|
|
3240
|
+
"fills",
|
|
3241
|
+
"strokes",
|
|
3242
|
+
"shadows",
|
|
3243
|
+
"glows",
|
|
3244
|
+
"bevel",
|
|
3245
|
+
"panel",
|
|
3246
|
+
"text",
|
|
3247
|
+
"animation",
|
|
3248
|
+
"stack"
|
|
3249
|
+
]);
|
|
3250
|
+
for (const key of Object.keys(effect)) {
|
|
3251
|
+
if (!standardKeys.has(key)) {
|
|
3252
|
+
config[key] = effect[key];
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
return config;
|
|
3256
|
+
}
|
|
3257
|
+
function layerToTextEffectConfig(layer2) {
|
|
3258
|
+
const normWeight = typeof layer2.fontWeight === "number" ? layer2.fontWeight : layer2.fontWeight === "bold" ? 700 : 400;
|
|
3259
|
+
const config = {
|
|
3260
|
+
...defaultConfig,
|
|
3261
|
+
width: layer2.width,
|
|
3262
|
+
height: layer2.height,
|
|
3263
|
+
canvasWidth: layer2.width,
|
|
3264
|
+
canvasHeight: layer2.height,
|
|
3265
|
+
text: layer2.text,
|
|
3266
|
+
fontFamily: resolveFontFamilyName(layer2.fontFamily),
|
|
3267
|
+
fontWeight: normWeight,
|
|
3268
|
+
fontStyle: layer2.fontStyle || "normal",
|
|
3269
|
+
fontSize: layer2.fontSize,
|
|
3270
|
+
letterSpacing: layer2.letterSpacing ?? 0,
|
|
3271
|
+
lineHeight: layer2.lineHeight ?? 1.2,
|
|
3272
|
+
fillType: layer2.color ? "solid" : "none",
|
|
3273
|
+
fillColor: layer2.color ?? "#FFFFFF",
|
|
3274
|
+
strokeEnabled: !!layer2.stroke,
|
|
3275
|
+
strokeColor: layer2.stroke?.color ?? "#000000",
|
|
3276
|
+
strokeWidth: layer2.stroke?.width ?? 0,
|
|
3277
|
+
strokePosition: "center",
|
|
3278
|
+
strokeOpacity: 100,
|
|
3279
|
+
strokeLineJoin: "round",
|
|
3280
|
+
shadowEnabled: !!layer2.shadow,
|
|
3281
|
+
shadowColor: layer2.shadow?.color ?? "#000000",
|
|
3282
|
+
shadowBlur: layer2.shadow?.blur ?? 0,
|
|
3283
|
+
shadowOffsetX: layer2.shadow?.offsetX ?? 0,
|
|
3284
|
+
shadowOffsetY: layer2.shadow?.offsetY ?? 0,
|
|
3285
|
+
shadowOpacity: 100,
|
|
3286
|
+
shadowType: "drop",
|
|
3287
|
+
panelEnabled: !!layer2.background,
|
|
3288
|
+
panelColor: layer2.background?.color ?? "#1E1E26",
|
|
3289
|
+
panelOpacity: 80,
|
|
3290
|
+
panelRadius: layer2.background?.borderRadius ?? 6,
|
|
3291
|
+
panelPaddingX: layer2.background?.padding ?? 12,
|
|
3292
|
+
panelPaddingY: layer2.background?.padding ?? 12,
|
|
3293
|
+
textPosX: layer2.textAlign || "center",
|
|
3294
|
+
textPosY: layer2.verticalAlign === "middle" ? "middle" : layer2.verticalAlign || "middle"
|
|
3295
|
+
};
|
|
3296
|
+
return config;
|
|
3297
|
+
}
|
|
2904
3298
|
|
|
2905
3299
|
// src/engine/animation.ts
|
|
2906
3300
|
function ease(t, kind = "linear") {
|
|
@@ -3210,47 +3604,23 @@ function evaluateScene(doc, time, ctx, options = {}) {
|
|
|
3210
3604
|
finishFrame();
|
|
3211
3605
|
return;
|
|
3212
3606
|
}
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
return;
|
|
3220
|
-
}
|
|
3221
|
-
renderTextEffectCore(offCtx, cfg);
|
|
3222
|
-
applyMaskReveal(offCtx, animated, w, h);
|
|
3607
|
+
const temp = CanvasDevice.acquire(w, h);
|
|
3608
|
+
const tctx = temp.getContext("2d");
|
|
3609
|
+
if (tctx) {
|
|
3610
|
+
tctx.clearRect(0, 0, w, h);
|
|
3611
|
+
renderTextEffectCore(tctx, cfg);
|
|
3612
|
+
applyMaskReveal(tctx, animated, w, h);
|
|
3223
3613
|
const compositor = options.compositor ?? getCompositor();
|
|
3224
3614
|
if (compositor?.isSupported) {
|
|
3225
|
-
compositor.renderToContext(ctx,
|
|
3226
|
-
|
|
3227
|
-
}
|
|
3228
|
-
ctx.clearRect(0, 0, w, h);
|
|
3229
|
-
ctx.drawImage(off, 0, 0);
|
|
3230
|
-
return;
|
|
3231
|
-
}
|
|
3232
|
-
if (typeof document !== "undefined") {
|
|
3233
|
-
const temp = document.createElement("canvas");
|
|
3234
|
-
temp.width = w;
|
|
3235
|
-
temp.height = h;
|
|
3236
|
-
const tctx = temp.getContext("2d");
|
|
3237
|
-
if (tctx) {
|
|
3238
|
-
renderTextEffectCore(tctx, cfg);
|
|
3239
|
-
applyMaskReveal(tctx, animated, w, h);
|
|
3240
|
-
const compositor = options.compositor ?? getCompositor();
|
|
3241
|
-
if (compositor?.isSupported) {
|
|
3242
|
-
compositor.renderToContext(ctx, temp, comp);
|
|
3243
|
-
temp.width = 0;
|
|
3244
|
-
temp.height = 0;
|
|
3245
|
-
return;
|
|
3246
|
-
}
|
|
3615
|
+
compositor.renderToContext(ctx, temp, comp);
|
|
3616
|
+
} else {
|
|
3247
3617
|
ctx.clearRect(0, 0, w, h);
|
|
3248
3618
|
ctx.drawImage(temp, 0, 0);
|
|
3249
|
-
temp.width = 0;
|
|
3250
|
-
temp.height = 0;
|
|
3251
|
-
return;
|
|
3252
3619
|
}
|
|
3620
|
+
CanvasDevice.release(temp);
|
|
3621
|
+
return;
|
|
3253
3622
|
}
|
|
3623
|
+
CanvasDevice.release(temp);
|
|
3254
3624
|
renderTextEffectCore(ctx, cfg);
|
|
3255
3625
|
finishFrame();
|
|
3256
3626
|
}
|
|
@@ -6218,6 +6588,7 @@ function duplicateTrackAtPlayhead(doc, trackIndex, previewTime) {
|
|
|
6218
6588
|
0 && (module.exports = {
|
|
6219
6589
|
COMPOSITION_PRESETS,
|
|
6220
6590
|
CUSTOM_ENGINE_IDS,
|
|
6591
|
+
CanvasDevice,
|
|
6221
6592
|
DEFAULT_CANVAS_HEIGHT,
|
|
6222
6593
|
DEFAULT_CANVAS_WIDTH,
|
|
6223
6594
|
DEFAULT_DURATION,
|
|
@@ -6229,6 +6600,7 @@ function duplicateTrackAtPlayhead(doc, trackIndex, previewTime) {
|
|
|
6229
6600
|
ENTRANCE_PRESETS,
|
|
6230
6601
|
EXIT_PRESETS,
|
|
6231
6602
|
FONT_WEIGHT_OPTIONS,
|
|
6603
|
+
FontLoader,
|
|
6232
6604
|
InkBrushEngine,
|
|
6233
6605
|
LEGACY_RENDERER_MAP,
|
|
6234
6606
|
LOOP_PRESETS,
|
|
@@ -6240,6 +6612,7 @@ function duplicateTrackAtPlayhead(doc, trackIndex, previewTime) {
|
|
|
6240
6612
|
TextEffectRenderer,
|
|
6241
6613
|
WEBM_EXPORT_MAX_FRAMES,
|
|
6242
6614
|
WebGLCompositor,
|
|
6615
|
+
_buildConfig,
|
|
6243
6616
|
_resetPlatformCache,
|
|
6244
6617
|
addImageLayer,
|
|
6245
6618
|
addKeyframeAtTime,
|
|
@@ -6297,6 +6670,7 @@ function duplicateTrackAtPlayhead(doc, trackIndex, previewTime) {
|
|
|
6297
6670
|
encodeGif,
|
|
6298
6671
|
ensureDefaultTimeline,
|
|
6299
6672
|
ensureFontInLottie,
|
|
6673
|
+
ensureFontsLoaded,
|
|
6300
6674
|
evaluateConfig,
|
|
6301
6675
|
evaluateScene,
|
|
6302
6676
|
findTrackIndex,
|
|
@@ -6304,6 +6678,7 @@ function duplicateTrackAtPlayhead(doc, trackIndex, previewTime) {
|
|
|
6304
6678
|
getAnimatableParamDef,
|
|
6305
6679
|
getAnimatableParamsForLayer,
|
|
6306
6680
|
getDefaultText,
|
|
6681
|
+
getFontLoader,
|
|
6307
6682
|
getLayerById,
|
|
6308
6683
|
getPresetScene,
|
|
6309
6684
|
getSceneTime,
|
|
@@ -6322,6 +6697,7 @@ function duplicateTrackAtPlayhead(doc, trackIndex, previewTime) {
|
|
|
6322
6697
|
injectText,
|
|
6323
6698
|
injectTextStyle,
|
|
6324
6699
|
isWebMExportSupported,
|
|
6700
|
+
layerToTextEffectConfig,
|
|
6325
6701
|
loadLottieFonts,
|
|
6326
6702
|
lottieColorToHex,
|
|
6327
6703
|
lottieJToAlign,
|
|
@@ -6344,10 +6720,12 @@ function duplicateTrackAtPlayhead(doc, trackIndex, previewTime) {
|
|
|
6344
6720
|
renderPngSequence,
|
|
6345
6721
|
renderSceneWebM,
|
|
6346
6722
|
renderTextEffectCore,
|
|
6723
|
+
resetFontLoader,
|
|
6347
6724
|
resetSceneTime,
|
|
6348
6725
|
resizeCharFillColors,
|
|
6349
6726
|
resolveAnimatedScalar,
|
|
6350
6727
|
resolveCustomEngineId,
|
|
6728
|
+
resolveFontFamilyName,
|
|
6351
6729
|
restoreLetterSpacing,
|
|
6352
6730
|
scanLottieFonts,
|
|
6353
6731
|
scanTextLayers,
|