@nmmty/lazycanvas 0.6.5 → 1.0.0-dev.3
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 +1 -1
- package/biome.json +41 -0
- package/dist/core/Interpolation.d.ts +30 -0
- package/dist/core/Interpolation.js +200 -0
- package/dist/core/Scene.d.ts +96 -0
- package/dist/core/Scene.js +172 -0
- package/dist/core/Signal.d.ts +133 -0
- package/dist/core/Signal.js +255 -0
- package/dist/core/SignalUtils.d.ts +133 -0
- package/dist/core/SignalUtils.js +333 -0
- package/dist/core/ThreadScheduler.d.ts +38 -0
- package/dist/core/ThreadScheduler.js +74 -0
- package/dist/helpers/Filters.js +1 -1
- package/dist/helpers/FontsList.js +18 -18
- package/dist/helpers/Utlis.d.ts +3 -3
- package/dist/helpers/Utlis.js +15 -18
- package/dist/helpers/index.d.ts +3 -3
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/jsx-runtime.d.ts +17 -0
- package/dist/jsx-runtime.js +111 -0
- package/dist/structures/LazyCanvas.d.ts +3 -45
- package/dist/structures/LazyCanvas.js +11 -74
- package/dist/structures/components/BaseLayer.d.ts +34 -12
- package/dist/structures/components/BaseLayer.js +68 -35
- package/dist/structures/components/BezierLayer.d.ts +16 -37
- package/dist/structures/components/BezierLayer.js +83 -46
- package/dist/structures/components/{Group.d.ts → Div.d.ts} +22 -16
- package/dist/structures/components/{Group.js → Div.js} +38 -39
- package/dist/structures/components/ImageLayer.d.ts +1 -1
- package/dist/structures/components/ImageLayer.js +24 -25
- package/dist/structures/components/LineLayer.d.ts +11 -37
- package/dist/structures/components/LineLayer.js +42 -42
- package/dist/structures/components/MorphLayer.d.ts +3 -32
- package/dist/structures/components/MorphLayer.js +32 -46
- package/dist/structures/components/Path2DLayer.d.ts +4 -32
- package/dist/structures/components/Path2DLayer.js +28 -33
- package/dist/structures/components/PolygonLayer.d.ts +2 -31
- package/dist/structures/components/PolygonLayer.js +35 -38
- package/dist/structures/components/QuadraticLayer.d.ts +16 -33
- package/dist/structures/components/QuadraticLayer.js +80 -42
- package/dist/structures/components/TextLayer.d.ts +4 -33
- package/dist/structures/components/TextLayer.js +60 -62
- package/dist/structures/components/index.d.ts +10 -11
- package/dist/structures/components/index.js +1 -2
- package/dist/structures/helpers/Exporter.d.ts +13 -4
- package/dist/structures/helpers/Exporter.js +79 -42
- package/dist/structures/helpers/Font.js +1 -17
- package/dist/structures/helpers/Gradient.js +32 -45
- package/dist/structures/helpers/Link.js +2 -14
- package/dist/structures/helpers/Pattern.js +9 -17
- package/dist/structures/helpers/index.d.ts +7 -7
- package/dist/structures/helpers/readers/JSONReader.d.ts +4 -4
- package/dist/structures/helpers/readers/JSONReader.js +32 -40
- package/dist/structures/helpers/readers/YAMLReader.js +5 -5
- package/dist/structures/managers/FontsManager.js +9 -18
- package/dist/structures/managers/LayersManager.d.ts +18 -28
- package/dist/structures/managers/LayersManager.js +14 -36
- package/dist/structures/managers/RenderManager.d.ts +1 -15
- package/dist/structures/managers/RenderManager.js +17 -110
- package/dist/structures/managers/index.d.ts +3 -5
- package/dist/structures/managers/index.js +0 -2
- package/dist/types/enum.d.ts +1 -2
- package/dist/types/enum.js +1 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/APNGEncoder.d.ts +67 -0
- package/dist/utils/APNGEncoder.js +205 -0
- package/dist/utils/DrawUtils.d.ts +9 -0
- package/dist/utils/DrawUtils.js +42 -0
- package/dist/utils/LazyUtil.js +1 -2
- package/dist/utils/utils.d.ts +4 -7
- package/dist/utils/utils.js +133 -76
- package/package.json +62 -59
- package/dist/structures/components/ClearLayer.d.ts +0 -147
- package/dist/structures/components/ClearLayer.js +0 -158
- package/dist/structures/managers/AnimationManager.d.ts +0 -120
- package/dist/structures/managers/AnimationManager.js +0 -99
- package/dist/structures/managers/PluginManager.d.ts +0 -230
- package/dist/structures/managers/PluginManager.js +0 -182
- package/dist/types/types.d.ts +0 -107
|
@@ -5,14 +5,11 @@ const BaseLayer_1 = require("./BaseLayer");
|
|
|
5
5
|
const types_1 = require("../../types");
|
|
6
6
|
const LazyUtil_1 = require("../../utils/LazyUtil");
|
|
7
7
|
const utils_1 = require("../../utils/utils");
|
|
8
|
+
const DrawUtils_1 = require("../../utils/DrawUtils");
|
|
8
9
|
/**
|
|
9
10
|
* Class representing a Text layer, extending the BaseLayer class.
|
|
10
11
|
*/
|
|
11
12
|
class TextLayer extends BaseLayer_1.BaseLayer {
|
|
12
|
-
/**
|
|
13
|
-
* The properties of the Text Layer.
|
|
14
|
-
*/
|
|
15
|
-
props;
|
|
16
13
|
/**
|
|
17
14
|
* Constructs a new TextLayer instance.
|
|
18
15
|
* @param {ITextLayerProps} [props] - The properties of the Text layer.
|
|
@@ -43,9 +40,9 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
43
40
|
setFont(familyOrConfig, size, weight) {
|
|
44
41
|
if (typeof familyOrConfig === "string") {
|
|
45
42
|
if (!size)
|
|
46
|
-
throw new LazyUtil_1.LazyError(
|
|
43
|
+
throw new LazyUtil_1.LazyError("The size of the font must be provided");
|
|
47
44
|
if (!weight)
|
|
48
|
-
throw new LazyUtil_1.LazyError(
|
|
45
|
+
throw new LazyUtil_1.LazyError("The weight of the font must be provided");
|
|
49
46
|
this.props.font = {
|
|
50
47
|
family: familyOrConfig,
|
|
51
48
|
size,
|
|
@@ -88,9 +85,9 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
88
85
|
*/
|
|
89
86
|
setColor(color, ...sub) {
|
|
90
87
|
if (!color)
|
|
91
|
-
throw new LazyUtil_1.LazyError(
|
|
88
|
+
throw new LazyUtil_1.LazyError("The color of the layer must be provided");
|
|
92
89
|
if (!(0, utils_1.isColor)(color))
|
|
93
|
-
throw new LazyUtil_1.LazyError(
|
|
90
|
+
throw new LazyUtil_1.LazyError("The color of the layer must be a valid color");
|
|
94
91
|
this.props.fillStyle = color;
|
|
95
92
|
if (sub && sub.length > 0) {
|
|
96
93
|
this.props.subStringColors = sub;
|
|
@@ -137,13 +134,12 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
137
134
|
setStroke(width, cap, join, dash, dashOffset, miterLimit) {
|
|
138
135
|
this.props.stroke = {
|
|
139
136
|
width,
|
|
140
|
-
cap: cap ||
|
|
141
|
-
join: join ||
|
|
137
|
+
cap: cap || "butt",
|
|
138
|
+
join: join || "miter",
|
|
142
139
|
dash: dash || [],
|
|
143
140
|
dashOffset: dashOffset || 0,
|
|
144
141
|
miterLimit: miterLimit || 10,
|
|
145
142
|
};
|
|
146
|
-
this.props.filled = false; // Ensure filled is false when stroke is set
|
|
147
143
|
return this;
|
|
148
144
|
}
|
|
149
145
|
/**
|
|
@@ -171,9 +167,9 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
171
167
|
* @returns {Object} The width and height of the text.
|
|
172
168
|
*/
|
|
173
169
|
measureText(ctx, canvas) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
170
|
+
if (this.props?.multiline?.enabled) {
|
|
171
|
+
const w = (0, utils_1.parseToNormal)(this.props.size?.width || "vw", ctx, canvas);
|
|
172
|
+
const h = (0, utils_1.parseToNormal)(this.props.size?.height || 0, ctx, canvas, { width: w, height: 0 }, { vertical: true });
|
|
177
173
|
return { width: w, height: h };
|
|
178
174
|
}
|
|
179
175
|
else {
|
|
@@ -192,19 +188,26 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
192
188
|
async draw(ctx, canvas, manager, debug) {
|
|
193
189
|
const parcer = (0, utils_1.parser)(ctx, canvas, manager);
|
|
194
190
|
const { x, y, w } = parcer.parseBatch({
|
|
195
|
-
x: { v: this.props.x },
|
|
196
|
-
y: { v: this.props.y, options: LazyUtil_1.defaultArg.vl(true) },
|
|
197
|
-
w: { v: this.props.size?.width },
|
|
191
|
+
x: { v: this.props.position.x },
|
|
192
|
+
y: { v: this.props.position.y, options: LazyUtil_1.defaultArg.vl(true) },
|
|
193
|
+
w: { v: this.props.size?.width || "vw" },
|
|
198
194
|
});
|
|
199
|
-
const h = parcer.parse(this.props.size?.height, LazyUtil_1.defaultArg.wh(w), LazyUtil_1.defaultArg.vl(true));
|
|
195
|
+
const h = parcer.parse(this.props.size?.height || 0, LazyUtil_1.defaultArg.wh(w), LazyUtil_1.defaultArg.vl(true));
|
|
200
196
|
if (debug)
|
|
201
|
-
LazyUtil_1.LazyLog.log(
|
|
197
|
+
LazyUtil_1.LazyLog.log("none", `TextLayer:`, { x, y, w, h });
|
|
202
198
|
ctx.save();
|
|
203
|
-
|
|
199
|
+
if (this.props.transform) {
|
|
200
|
+
(0, utils_1.transform)(ctx, this.props.transform, { width: w, height: h, x, y, type: this.type }, {
|
|
201
|
+
text: this.props.text,
|
|
202
|
+
textAlign: this.props.align,
|
|
203
|
+
fontSize: this.props.font.size,
|
|
204
|
+
multiline: this.props?.multiline?.enabled || false,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
204
207
|
ctx.beginPath();
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
DrawUtils_1.DrawUtils.drawShadow(ctx, this.props.shadow);
|
|
209
|
+
DrawUtils_1.DrawUtils.opacity(ctx, this.props.opacity);
|
|
210
|
+
DrawUtils_1.DrawUtils.filters(ctx, this.props.filter);
|
|
208
211
|
ctx.textAlign = this.props.align;
|
|
209
212
|
if (this.props.letterSpacing)
|
|
210
213
|
ctx.letterSpacing = `${this.props.letterSpacing}px`;
|
|
@@ -214,9 +217,13 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
214
217
|
ctx.textBaseline = this.props.baseline;
|
|
215
218
|
if (this.props.direction)
|
|
216
219
|
ctx.direction = this.props.direction;
|
|
217
|
-
let fillStyle = await (0, utils_1.parseFillStyle)(ctx, this.props.fillStyle, {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
let fillStyle = await (0, utils_1.parseFillStyle)(ctx, this.props.fillStyle, {
|
|
221
|
+
debug,
|
|
222
|
+
layer: { width: w, height: h, x, y, align: "center" },
|
|
223
|
+
manager,
|
|
224
|
+
});
|
|
225
|
+
if (this.props?.multiline?.enabled) {
|
|
226
|
+
const words = this.props.text.split(" ");
|
|
220
227
|
let lines = [];
|
|
221
228
|
for (let fontSize = 1; fontSize <= this.props.font.size; fontSize++) {
|
|
222
229
|
let lineHeight = fontSize * (this.props.multiline.spacing || 1.1);
|
|
@@ -224,14 +231,14 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
224
231
|
let xm = x;
|
|
225
232
|
let ym = y;
|
|
226
233
|
lines = [];
|
|
227
|
-
let line =
|
|
234
|
+
let line = "";
|
|
228
235
|
let charOffset = 0; // Track position in original text
|
|
229
236
|
for (let word of words) {
|
|
230
|
-
let linePlus = line + word +
|
|
237
|
+
let linePlus = line + word + " ";
|
|
231
238
|
if (ctx.measureText(linePlus).width > w) {
|
|
232
239
|
lines.push({ text: line, x: xm, y: ym, startOffset: charOffset });
|
|
233
240
|
charOffset += line.length;
|
|
234
|
-
line = word +
|
|
241
|
+
line = word + " ";
|
|
235
242
|
ym += lineHeight;
|
|
236
243
|
}
|
|
237
244
|
else {
|
|
@@ -267,19 +274,12 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
267
274
|
drawText(props, ctx, fillStyle, text, x, y, w, textOffset = 0) {
|
|
268
275
|
// If no substring colors are defined, draw normally
|
|
269
276
|
if (!props.subStringColors || props.subStringColors.length === 0) {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
ctx.
|
|
277
|
+
DrawUtils_1.DrawUtils.fillStyle(ctx, fillStyle, this.props.stroke);
|
|
278
|
+
if (props.stroke) {
|
|
279
|
+
ctx.strokeText(text, x, y, w);
|
|
273
280
|
}
|
|
274
281
|
else {
|
|
275
|
-
ctx.
|
|
276
|
-
ctx.lineWidth = props.stroke?.width || 1;
|
|
277
|
-
ctx.lineCap = props.stroke?.cap || 'butt';
|
|
278
|
-
ctx.lineJoin = props.stroke?.join || 'miter';
|
|
279
|
-
ctx.miterLimit = props.stroke?.miterLimit || 10;
|
|
280
|
-
ctx.lineDashOffset = props.stroke?.dashOffset || 0;
|
|
281
|
-
ctx.setLineDash(props.stroke?.dash || []);
|
|
282
|
-
ctx.strokeText(text, x, y, w);
|
|
282
|
+
ctx.fillText(text, x, y, w);
|
|
283
283
|
}
|
|
284
284
|
return;
|
|
285
285
|
}
|
|
@@ -288,14 +288,17 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
288
288
|
let currentX = x;
|
|
289
289
|
// Save original text alignment and set to left for manual positioning
|
|
290
290
|
const originalAlign = ctx.textAlign;
|
|
291
|
-
ctx.textAlign =
|
|
291
|
+
ctx.textAlign = "left";
|
|
292
292
|
// Adjust starting X based on text alignment
|
|
293
293
|
const alignValue = props.align;
|
|
294
|
-
if (alignValue === types_1.TextAlign.Center || alignValue ===
|
|
294
|
+
if (alignValue === types_1.TextAlign.Center || alignValue === "center") {
|
|
295
295
|
const totalWidth = ctx.measureText(text).width;
|
|
296
296
|
currentX = x - totalWidth / 2;
|
|
297
297
|
}
|
|
298
|
-
else if (alignValue === types_1.TextAlign.Right ||
|
|
298
|
+
else if (alignValue === types_1.TextAlign.Right ||
|
|
299
|
+
alignValue === "right" ||
|
|
300
|
+
alignValue === types_1.TextAlign.End ||
|
|
301
|
+
alignValue === "end") {
|
|
299
302
|
const totalWidth = ctx.measureText(text).width;
|
|
300
303
|
currentX = x - totalWidth;
|
|
301
304
|
}
|
|
@@ -323,16 +326,19 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
323
326
|
text: text.substring(currentIndex, localStart),
|
|
324
327
|
color: fillStyle,
|
|
325
328
|
start: currentIndex,
|
|
326
|
-
end: localStart
|
|
329
|
+
end: localStart,
|
|
327
330
|
});
|
|
328
331
|
}
|
|
329
332
|
// Add colored substring
|
|
330
333
|
if (localStart < localEnd) {
|
|
331
334
|
segments.push({
|
|
332
335
|
text: text.substring(localStart, localEnd),
|
|
333
|
-
color: subColor.color,
|
|
336
|
+
color: (0, utils_1.parseFillStyle)(ctx, subColor.color, {
|
|
337
|
+
debug: false,
|
|
338
|
+
layer: { width: w, height: 0, x: 0, y: 0, align: "center" },
|
|
339
|
+
}),
|
|
334
340
|
start: localStart,
|
|
335
|
-
end: localEnd
|
|
341
|
+
end: localEnd,
|
|
336
342
|
});
|
|
337
343
|
currentIndex = localEnd;
|
|
338
344
|
}
|
|
@@ -343,7 +349,7 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
343
349
|
text: text.substring(currentIndex),
|
|
344
350
|
color: fillStyle,
|
|
345
351
|
start: currentIndex,
|
|
346
|
-
end: textLength
|
|
352
|
+
end: textLength,
|
|
347
353
|
});
|
|
348
354
|
}
|
|
349
355
|
// Draw each segment
|
|
@@ -351,19 +357,12 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
351
357
|
if (segment.text.length === 0)
|
|
352
358
|
continue;
|
|
353
359
|
const segmentWidth = ctx.measureText(segment.text).width;
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
ctx.
|
|
360
|
+
DrawUtils_1.DrawUtils.fillStyle(ctx, segment.color, this.props.stroke);
|
|
361
|
+
if (props.stroke) {
|
|
362
|
+
ctx.strokeText(segment.text, currentX, y);
|
|
357
363
|
}
|
|
358
364
|
else {
|
|
359
|
-
ctx.
|
|
360
|
-
ctx.lineWidth = props.stroke?.width || 1;
|
|
361
|
-
ctx.lineCap = props.stroke?.cap || 'butt';
|
|
362
|
-
ctx.lineJoin = props.stroke?.join || 'miter';
|
|
363
|
-
ctx.miterLimit = props.stroke?.miterLimit || 10;
|
|
364
|
-
ctx.lineDashOffset = props.stroke?.dashOffset || 0;
|
|
365
|
-
ctx.setLineDash(props.stroke?.dash || []);
|
|
366
|
-
ctx.strokeText(segment.text, currentX, y);
|
|
365
|
+
ctx.fillText(segment.text, currentX, y);
|
|
367
366
|
}
|
|
368
367
|
currentX += segmentWidth;
|
|
369
368
|
}
|
|
@@ -377,8 +376,8 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
377
376
|
toJSON() {
|
|
378
377
|
let data = super.toJSON();
|
|
379
378
|
let copy = { ...this.props };
|
|
380
|
-
for (const key of [
|
|
381
|
-
if (copy[key] && typeof copy[key] ===
|
|
379
|
+
for (const key of ["x", "y", "size.width", "size.height", "fillStyle"]) {
|
|
380
|
+
if (copy[key] && typeof copy[key] === "object" && "toJSON" in copy[key]) {
|
|
382
381
|
copy[key] = copy[key].toJSON();
|
|
383
382
|
}
|
|
384
383
|
}
|
|
@@ -392,8 +391,7 @@ class TextLayer extends BaseLayer_1.BaseLayer {
|
|
|
392
391
|
validateProps(data) {
|
|
393
392
|
return {
|
|
394
393
|
...super.validateProps(data),
|
|
395
|
-
|
|
396
|
-
fillStyle: data.fillStyle || '#000000',
|
|
394
|
+
fillStyle: data.fillStyle || "#000000",
|
|
397
395
|
text: data.text || "",
|
|
398
396
|
font: {
|
|
399
397
|
family: data.font?.family || "Arial",
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from './PolygonLayer';
|
|
1
|
+
export * from "./BaseLayer";
|
|
2
|
+
export * from "./BezierLayer";
|
|
3
|
+
export * from "./ImageLayer";
|
|
4
|
+
export * from "./TextLayer";
|
|
5
|
+
export * from "./MorphLayer";
|
|
6
|
+
export * from "./Div";
|
|
7
|
+
export * from "./LineLayer";
|
|
8
|
+
export * from "./QuadraticLayer";
|
|
9
|
+
export * from "./Path2DLayer";
|
|
10
|
+
export * from "./PolygonLayer";
|
|
@@ -16,11 +16,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./BaseLayer"), exports);
|
|
18
18
|
__exportStar(require("./BezierLayer"), exports);
|
|
19
|
-
__exportStar(require("./ClearLayer"), exports);
|
|
20
19
|
__exportStar(require("./ImageLayer"), exports);
|
|
21
20
|
__exportStar(require("./TextLayer"), exports);
|
|
22
21
|
__exportStar(require("./MorphLayer"), exports);
|
|
23
|
-
__exportStar(require("./
|
|
22
|
+
__exportStar(require("./Div"), exports);
|
|
24
23
|
__exportStar(require("./LineLayer"), exports);
|
|
25
24
|
__exportStar(require("./QuadraticLayer"), exports);
|
|
26
25
|
__exportStar(require("./Path2DLayer"), exports);
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { IOLazyCanvas, LazyCanvas } from "../LazyCanvas";
|
|
2
2
|
import { AnyExport } from "../../types";
|
|
3
3
|
import { Canvas, SKRSContext2D, SvgCanvas } from "@napi-rs/canvas";
|
|
4
|
+
import { Scene } from "../../core/Scene";
|
|
4
5
|
/**
|
|
5
|
-
* Class responsible for exporting a LazyCanvas instance to various formats.
|
|
6
|
+
* Class responsible for exporting a LazyCanvas or Scene instance to various formats.
|
|
6
7
|
*/
|
|
7
8
|
export declare class Exporter {
|
|
8
9
|
/**
|
|
9
10
|
* The LazyCanvas instance to be exported.
|
|
10
11
|
*/
|
|
11
|
-
canvas
|
|
12
|
+
canvas?: LazyCanvas;
|
|
13
|
+
/**
|
|
14
|
+
* The Scene instance to be exported.
|
|
15
|
+
*/
|
|
16
|
+
scene?: Scene;
|
|
12
17
|
/**
|
|
13
18
|
* Constructs a new Exporter instance.
|
|
14
|
-
* @param
|
|
19
|
+
* @param source {LazyCanvas | Scene} - The LazyCanvas or Scene instance to be exported.
|
|
15
20
|
*/
|
|
16
|
-
constructor(
|
|
21
|
+
constructor(source: LazyCanvas | Scene);
|
|
17
22
|
/**
|
|
18
23
|
* Saves a file to the filesystem.
|
|
19
24
|
* @param {any} [buffer] - The data to be saved.
|
|
@@ -34,12 +39,16 @@ export declare class Exporter {
|
|
|
34
39
|
* @param {Object} [opts] - Optional settings.
|
|
35
40
|
* @param {string} [opts.name] - The name of the file (optional).
|
|
36
41
|
* @param {boolean} [opts.saveAsFile] - Whether to save the export as a file (optional).
|
|
42
|
+
* @param {number} [opts.duration] - Duration of the animation in seconds (Scene only).
|
|
43
|
+
* @param {number} [opts.fps] - Frames per second for animation (default: 60, Scene only).
|
|
37
44
|
* @returns {Promise<Buffer | SKRSContext2D | Canvas | SvgCanvas | string>} The exported data.
|
|
38
45
|
* @throws {LazyError} If the export type is not supported.
|
|
39
46
|
*/
|
|
40
47
|
export(exportType: AnyExport, opts?: {
|
|
41
48
|
name?: string;
|
|
42
49
|
saveAsFile?: boolean;
|
|
50
|
+
duration?: number;
|
|
51
|
+
fps?: number;
|
|
43
52
|
}): Promise<Buffer | SKRSContext2D | Canvas | SvgCanvas | string>;
|
|
44
53
|
/**
|
|
45
54
|
* Synchronously exports the canvas to the specified format.
|
|
@@ -32,6 +32,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.Exporter = void 0;
|
|
37
40
|
const types_1 = require("../../types");
|
|
@@ -39,20 +42,24 @@ const LazyUtil_1 = require("../../utils/LazyUtil");
|
|
|
39
42
|
const fs = __importStar(require("fs"));
|
|
40
43
|
const utils_1 = require("../../utils/utils");
|
|
41
44
|
const _yaml = __importStar(require("js-yaml"));
|
|
45
|
+
const APNGEncoder_1 = __importDefault(require("../../utils/APNGEncoder"));
|
|
46
|
+
const Scene_1 = require("../../core/Scene");
|
|
42
47
|
/**
|
|
43
|
-
* Class responsible for exporting a LazyCanvas instance to various formats.
|
|
48
|
+
* Class responsible for exporting a LazyCanvas or Scene instance to various formats.
|
|
44
49
|
*/
|
|
45
50
|
class Exporter {
|
|
46
|
-
/**
|
|
47
|
-
* The LazyCanvas instance to be exported.
|
|
48
|
-
*/
|
|
49
|
-
canvas;
|
|
50
51
|
/**
|
|
51
52
|
* Constructs a new Exporter instance.
|
|
52
|
-
* @param
|
|
53
|
+
* @param source {LazyCanvas | Scene} - The LazyCanvas or Scene instance to be exported.
|
|
53
54
|
*/
|
|
54
|
-
constructor(
|
|
55
|
-
|
|
55
|
+
constructor(source) {
|
|
56
|
+
if (source instanceof Scene_1.Scene) {
|
|
57
|
+
this.scene = source;
|
|
58
|
+
this.canvas = source.lazyCanvas;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.canvas = source;
|
|
62
|
+
}
|
|
56
63
|
}
|
|
57
64
|
/**
|
|
58
65
|
* Saves a file to the filesystem.
|
|
@@ -63,9 +70,9 @@ class Exporter {
|
|
|
63
70
|
*/
|
|
64
71
|
async saveFile(buffer, extension, name) {
|
|
65
72
|
if (!buffer)
|
|
66
|
-
throw new LazyUtil_1.LazyError(
|
|
73
|
+
throw new LazyUtil_1.LazyError("Buffer must be provided");
|
|
67
74
|
if (!extension)
|
|
68
|
-
throw new LazyUtil_1.LazyError(
|
|
75
|
+
throw new LazyUtil_1.LazyError("Extension must be provided");
|
|
69
76
|
fs.writeFileSync(`${name === undefined ? (0, utils_1.generateRandomName)() : name}.${extension}`, buffer);
|
|
70
77
|
}
|
|
71
78
|
/**
|
|
@@ -86,12 +93,15 @@ class Exporter {
|
|
|
86
93
|
* @param {Object} [opts] - Optional settings.
|
|
87
94
|
* @param {string} [opts.name] - The name of the file (optional).
|
|
88
95
|
* @param {boolean} [opts.saveAsFile] - Whether to save the export as a file (optional).
|
|
96
|
+
* @param {number} [opts.duration] - Duration of the animation in seconds (Scene only).
|
|
97
|
+
* @param {number} [opts.fps] - Frames per second for animation (default: 60, Scene only).
|
|
89
98
|
* @returns {Promise<Buffer | SKRSContext2D | Canvas | SvgCanvas | string>} The exported data.
|
|
90
99
|
* @throws {LazyError} If the export type is not supported.
|
|
91
100
|
*/
|
|
92
101
|
async export(exportType, opts) {
|
|
93
|
-
|
|
94
|
-
|
|
102
|
+
if (!this.canvas) {
|
|
103
|
+
throw new LazyUtil_1.LazyError("Canvas is not initialized");
|
|
104
|
+
}
|
|
95
105
|
let result;
|
|
96
106
|
switch (exportType) {
|
|
97
107
|
case types_1.Export.CTX:
|
|
@@ -100,69 +110,94 @@ class Exporter {
|
|
|
100
110
|
break;
|
|
101
111
|
case types_1.Export.SVG:
|
|
102
112
|
case "svg":
|
|
103
|
-
result = await this.canvas.manager.render.render(
|
|
113
|
+
result = await this.canvas.manager.render.render("svg");
|
|
104
114
|
if (opts?.saveAsFile) {
|
|
105
|
-
await this.saveFile(result,
|
|
115
|
+
await this.saveFile(result, "svg", opts.name);
|
|
106
116
|
}
|
|
107
117
|
break;
|
|
108
118
|
case types_1.Export.BUFFER:
|
|
109
119
|
case "buffer":
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
if (this.scene) {
|
|
121
|
+
result = await this.scene.renderFirstFrame().then((frame) => frame.toBuffer("image/png"));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
result = (await this.canvas.manager.render.render("buffer"));
|
|
113
125
|
}
|
|
114
|
-
break;
|
|
115
|
-
case types_1.Export.GIF:
|
|
116
|
-
case "gif":
|
|
117
|
-
result = await this.canvas.manager.render.render('buffer');
|
|
118
126
|
if (opts?.saveAsFile) {
|
|
119
|
-
await this.saveFile(result,
|
|
127
|
+
await this.saveFile(result, "png", opts.name);
|
|
120
128
|
}
|
|
121
129
|
break;
|
|
122
130
|
case types_1.Export.WEBP:
|
|
123
131
|
case "webp":
|
|
124
|
-
|
|
132
|
+
if (this.scene) {
|
|
133
|
+
result = await this.scene
|
|
134
|
+
.renderFirstFrame()
|
|
135
|
+
.then((frame) => frame.toBuffer("image/webp"));
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
result = await this.canvas.manager.render.render("webp");
|
|
139
|
+
}
|
|
125
140
|
if (opts?.saveAsFile) {
|
|
126
|
-
await this.saveFile(result,
|
|
141
|
+
await this.saveFile(result, "webp", opts.name);
|
|
127
142
|
}
|
|
128
143
|
break;
|
|
129
|
-
case types_1.Export.JPEG:
|
|
130
|
-
case "jpeg":
|
|
131
|
-
result = await this.canvas.manager.render.render('buffer');
|
|
132
|
-
await this.saveFile(result, 'jpeg', opts?.name);
|
|
133
|
-
break;
|
|
134
144
|
case types_1.Export.JPG:
|
|
135
145
|
case "jpg":
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
if (this.scene) {
|
|
147
|
+
result = await this.scene
|
|
148
|
+
.renderFirstFrame()
|
|
149
|
+
.then((frame) => frame.toBuffer("image/jpeg"));
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
result = await this.canvas.manager.render.render("jpg");
|
|
153
|
+
}
|
|
154
|
+
await this.saveFile(result, "jpg", opts?.name);
|
|
155
|
+
return result;
|
|
139
156
|
case types_1.Export.PNG:
|
|
140
157
|
case "png":
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
158
|
+
if (this.scene) {
|
|
159
|
+
result = await this.scene.renderFirstFrame().then((frame) => frame.toBuffer("image/png"));
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
result = await this.canvas.manager.render.render("png");
|
|
163
|
+
}
|
|
164
|
+
await this.saveFile(result, "png", opts?.name);
|
|
165
|
+
return result;
|
|
166
|
+
case types_1.Export.APNG:
|
|
167
|
+
case "apng":
|
|
168
|
+
if (!this.scene) {
|
|
169
|
+
throw new LazyUtil_1.LazyError("APNG export requires a Scene instance. Use: new Exporter(scene)");
|
|
170
|
+
}
|
|
171
|
+
const duration = opts?.duration ?? 0;
|
|
172
|
+
const timeNow = Date.now();
|
|
173
|
+
const fps = opts?.fps ?? 60;
|
|
174
|
+
const frameData = await this.scene.renderAnimationData(timeNow, timeNow + duration, fps);
|
|
175
|
+
const encoder = new APNGEncoder_1.default(this.scene.width, this.scene.height, fps).addFrames(...frameData);
|
|
176
|
+
const buffer = encoder.encode();
|
|
177
|
+
if (opts?.saveAsFile !== false) {
|
|
178
|
+
fs.writeFileSync(`${opts?.name ?? "animation"}.png`, buffer);
|
|
179
|
+
}
|
|
180
|
+
return buffer;
|
|
144
181
|
case types_1.Export.JSON:
|
|
145
182
|
case "json":
|
|
146
183
|
const json = this.syncExport(exportType);
|
|
147
184
|
if (opts?.saveAsFile) {
|
|
148
|
-
await this.saveFile(JSON.stringify(json),
|
|
185
|
+
await this.saveFile(JSON.stringify(json), "json", opts.name);
|
|
149
186
|
}
|
|
150
187
|
return JSON.stringify(json);
|
|
151
188
|
case types_1.Export.CANVAS:
|
|
152
189
|
case "canvas":
|
|
153
|
-
return await this.canvas.manager.render.render(exportType);
|
|
190
|
+
return (await this.canvas.manager.render.render(exportType));
|
|
154
191
|
case types_1.Export.YAML:
|
|
155
192
|
case "yaml":
|
|
156
193
|
const yaml = _yaml.dump(this.syncExport(types_1.Export.JSON));
|
|
157
194
|
if (opts?.saveAsFile) {
|
|
158
|
-
await this.saveFile(yaml,
|
|
195
|
+
await this.saveFile(yaml, "yaml", opts.name);
|
|
159
196
|
}
|
|
160
197
|
return yaml;
|
|
161
198
|
default:
|
|
162
199
|
throw new LazyUtil_1.LazyError(`Export type ${exportType} is not supported`);
|
|
163
200
|
}
|
|
164
|
-
// afterExport hook
|
|
165
|
-
this.canvas.manager.plugins.executeHook('afterExport', this.canvas, result);
|
|
166
201
|
return result;
|
|
167
202
|
}
|
|
168
203
|
/**
|
|
@@ -171,13 +206,15 @@ class Exporter {
|
|
|
171
206
|
* @returns {IOLazyCanvas | void} The exported data or void if the export type is unsupported.
|
|
172
207
|
*/
|
|
173
208
|
syncExport(exportType) {
|
|
209
|
+
if (!this.canvas) {
|
|
210
|
+
throw new LazyUtil_1.LazyError("Canvas is not initialized");
|
|
211
|
+
}
|
|
174
212
|
switch (exportType) {
|
|
175
213
|
case types_1.Export.JSON:
|
|
176
214
|
case "json":
|
|
177
215
|
return {
|
|
178
216
|
options: this.canvas.options,
|
|
179
|
-
|
|
180
|
-
layers: this.exportLayers(this.canvas.manager.layers)
|
|
217
|
+
layers: this.exportLayers(this.canvas.manager.layers),
|
|
181
218
|
};
|
|
182
219
|
}
|
|
183
220
|
}
|
|
@@ -6,22 +6,6 @@ const types_1 = require("../../types");
|
|
|
6
6
|
* Class representing a font with properties such as family, weight, path, and base64.
|
|
7
7
|
*/
|
|
8
8
|
class Font {
|
|
9
|
-
/**
|
|
10
|
-
* The font family.
|
|
11
|
-
*/
|
|
12
|
-
family;
|
|
13
|
-
/**
|
|
14
|
-
* The weight of the font.
|
|
15
|
-
*/
|
|
16
|
-
weight;
|
|
17
|
-
/**
|
|
18
|
-
* The file path of the font (optional).
|
|
19
|
-
*/
|
|
20
|
-
path;
|
|
21
|
-
/**
|
|
22
|
-
* The base64 representation of the font (optional).
|
|
23
|
-
*/
|
|
24
|
-
base64;
|
|
25
9
|
/**
|
|
26
10
|
* Constructs a new Font instance with default values.
|
|
27
11
|
*/
|
|
@@ -86,7 +70,7 @@ class Font {
|
|
|
86
70
|
family: this.family,
|
|
87
71
|
weight: this.weight,
|
|
88
72
|
path: this.path,
|
|
89
|
-
base64: this.base64
|
|
73
|
+
base64: this.base64,
|
|
90
74
|
};
|
|
91
75
|
}
|
|
92
76
|
}
|