@versa_ai/vmml-editor 1.0.38 → 1.0.39
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/.turbo/turbo-build.log +9 -9
- package/dist/index.js +151 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +151 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/components/EditorCanvas.tsx +246 -86
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @versa_ai/vmml-editor@1.0.
|
|
2
|
+
> @versa_ai/vmml-editor@1.0.39 build D:\code\work\vmml-player\packages\editor
|
|
3
3
|
> tsup
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.tsx
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
[34mCLI[39m Target: node16
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
+
[34mDTS[39m Build start
|
|
12
13
|
|
|
13
14
|
[43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mUsing / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.
|
|
14
15
|
|
|
@@ -123,13 +124,12 @@ More info and automated migrator: https://sass-lang.com/d/slash-div[0m [1m[35
|
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
|
|
126
|
-
[
|
|
127
|
-
[
|
|
128
|
-
[
|
|
129
|
-
[32mESM[39m
|
|
130
|
-
[
|
|
131
|
-
[
|
|
132
|
-
[
|
|
133
|
-
[32mDTS[39m ⚡️ Build success in 1577ms
|
|
127
|
+
[32mCJS[39m [1mdist\index.js [22m[32m122.27 KB[39m
|
|
128
|
+
[32mCJS[39m [1mdist\index.js.map [22m[32m233.66 KB[39m
|
|
129
|
+
[32mCJS[39m ⚡️ Build success in 839ms
|
|
130
|
+
[32mESM[39m [1mdist\index.mjs [22m[32m120.58 KB[39m
|
|
131
|
+
[32mESM[39m [1mdist\index.mjs.map [22m[32m233.36 KB[39m
|
|
132
|
+
[32mESM[39m ⚡️ Build success in 839ms
|
|
133
|
+
[32mDTS[39m ⚡️ Build success in 2050ms
|
|
134
134
|
[32mDTS[39m [1mdist\index.d.ts [22m[32m158.00 B[39m
|
|
135
135
|
[32mDTS[39m [1mdist\index.d.mts [22m[32m158.00 B[39m
|
package/dist/index.js
CHANGED
|
@@ -1020,6 +1020,7 @@ var EditorCanvas = react.forwardRef(
|
|
|
1020
1020
|
const vmmlConverterRef = react.useRef(null);
|
|
1021
1021
|
const heightScaleRef = react.useRef(1);
|
|
1022
1022
|
const widthScaleRef = react.useRef(1);
|
|
1023
|
+
const fontCacheRef = react.useRef(/* @__PURE__ */ new Map());
|
|
1023
1024
|
const initCanvas = () => {
|
|
1024
1025
|
const canvas = new fabric.fabric.Canvas("canvas", {
|
|
1025
1026
|
width: canvasSize.width,
|
|
@@ -1055,6 +1056,7 @@ var EditorCanvas = react.forwardRef(
|
|
|
1055
1056
|
if (fc) {
|
|
1056
1057
|
const ns = Math.floor((f ?? frame) / 30 * 1e6);
|
|
1057
1058
|
const objects = fc.getObjects();
|
|
1059
|
+
console.log(objects, "fc>>>>>>>>>>>>>>>>", frame);
|
|
1058
1060
|
objects.forEach((item) => {
|
|
1059
1061
|
var _a, _b, _c;
|
|
1060
1062
|
if (((_a = item == null ? void 0 : item.clipData) == null ? void 0 : _a.type) === "\u6587\u5B57") {
|
|
@@ -1213,7 +1215,7 @@ var EditorCanvas = react.forwardRef(
|
|
|
1213
1215
|
return createImageFromClip(clip);
|
|
1214
1216
|
}
|
|
1215
1217
|
if (clip.textClip && !clip.audioClip) {
|
|
1216
|
-
return
|
|
1218
|
+
return createTextFromClipCanvas(clip);
|
|
1217
1219
|
}
|
|
1218
1220
|
});
|
|
1219
1221
|
const res = await Promise.allSettled(promises);
|
|
@@ -1223,6 +1225,7 @@ var EditorCanvas = react.forwardRef(
|
|
|
1223
1225
|
objects.push(item.value);
|
|
1224
1226
|
}
|
|
1225
1227
|
});
|
|
1228
|
+
console.log(editRenderTime.current === time, "editRenderTime.current === time");
|
|
1226
1229
|
if (editRenderTime.current === time) {
|
|
1227
1230
|
canvas.add(...objects).renderAll();
|
|
1228
1231
|
checkObjectInPoint();
|
|
@@ -1311,6 +1314,134 @@ var EditorCanvas = react.forwardRef(
|
|
|
1311
1314
|
});
|
|
1312
1315
|
window.dispatchEvent(event);
|
|
1313
1316
|
};
|
|
1317
|
+
const createTextFromClipCanvas = async (clip, fc2) => {
|
|
1318
|
+
return new Promise(async (resolve) => {
|
|
1319
|
+
const canvas = fc || fc2;
|
|
1320
|
+
if (!canvas) return null;
|
|
1321
|
+
const { width, height } = vmml.template.dimension;
|
|
1322
|
+
const fontSize = vmmlUtils.getFontSize(width, height);
|
|
1323
|
+
const { textContent, backgroundColor, textColor, posParam, fontAssetUrl, alignType, strokeColor, strokeWidth, letterSpacing } = clip.textClip;
|
|
1324
|
+
const scaleX = posParam.scaleX * fontSize / 22 / widthScaleRef.current;
|
|
1325
|
+
const scaleY = posParam.scaleY * fontSize / 22 / heightScaleRef.current;
|
|
1326
|
+
const left = canvasSize.width * posParam.centerX;
|
|
1327
|
+
const top = canvasSize.height * posParam.centerY;
|
|
1328
|
+
const bgColor = backgroundColor ? vmmlUtils.argbToRgba(backgroundColor) : "transparent";
|
|
1329
|
+
const stColor = strokeColor ? vmmlUtils.argbToRgba(strokeColor) : "transparent";
|
|
1330
|
+
const textFill = vmmlUtils.argbToRgba(textColor || "#ffffffff");
|
|
1331
|
+
const strokeW = strokeColor && strokeWidth ? strokeWidth * 26 * 1.5 / fontSize : 0;
|
|
1332
|
+
const letterSpace = letterSpacing * 22 / fontSize;
|
|
1333
|
+
let fontFamily = "sansMedium";
|
|
1334
|
+
if (fontAssetUrl) {
|
|
1335
|
+
const base64 = await loadFont(fontAssetUrl);
|
|
1336
|
+
if (base64) {
|
|
1337
|
+
fontFamily = getFontFamilyName(fontAssetUrl);
|
|
1338
|
+
await document.fonts.ready;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
const lines = textContent.split("\n");
|
|
1342
|
+
const lineHeight = 22 + strokeW;
|
|
1343
|
+
const textHeight = lines.length * lineHeight;
|
|
1344
|
+
const groupWidth = Math.max(...lines.map((l) => {
|
|
1345
|
+
const temp = new fabric.fabric.Text(l || " ", { fontSize: 22, fontFamily, charSpacing: (letterSpace || 0) * 50, strokeWidth: strokeW ?? 0 });
|
|
1346
|
+
return (temp == null ? void 0 : temp.width) ?? 0;
|
|
1347
|
+
})) + 14;
|
|
1348
|
+
const groupHeight = textHeight + 13;
|
|
1349
|
+
const textObjs = [];
|
|
1350
|
+
lines.forEach((line, idx) => {
|
|
1351
|
+
const y = (groupHeight - textHeight) / 2 + idx * lineHeight + lineHeight / 2 + 1;
|
|
1352
|
+
const strokeText = new fabric.fabric.Text(line || " ", {
|
|
1353
|
+
fontFamily,
|
|
1354
|
+
fontSize: 22,
|
|
1355
|
+
fill: "transparent",
|
|
1356
|
+
stroke: stColor,
|
|
1357
|
+
strokeWidth: strokeW,
|
|
1358
|
+
originX: "center",
|
|
1359
|
+
originY: "center",
|
|
1360
|
+
left: groupWidth / 2,
|
|
1361
|
+
// 水平居中
|
|
1362
|
+
top: y,
|
|
1363
|
+
charSpacing: (letterSpace || 0) * 50,
|
|
1364
|
+
textAlign: alignType === 1 ? "center" : alignType === 2 ? "right" : "left",
|
|
1365
|
+
objectCaching: false
|
|
1366
|
+
});
|
|
1367
|
+
const fillText = new fabric.fabric.Text(line || " ", {
|
|
1368
|
+
fontFamily,
|
|
1369
|
+
fontSize: 22,
|
|
1370
|
+
fill: textFill,
|
|
1371
|
+
stroke: "transparent",
|
|
1372
|
+
originX: "center",
|
|
1373
|
+
originY: "center",
|
|
1374
|
+
strokeWidth: 0,
|
|
1375
|
+
left: groupWidth / 2,
|
|
1376
|
+
// 水平居中
|
|
1377
|
+
top: y,
|
|
1378
|
+
charSpacing: (letterSpace || 0) * 50,
|
|
1379
|
+
textAlign: alignType === 1 ? "center" : alignType === 2 ? "right" : "left",
|
|
1380
|
+
objectCaching: false
|
|
1381
|
+
});
|
|
1382
|
+
textObjs.push(strokeText, fillText);
|
|
1383
|
+
});
|
|
1384
|
+
const bgRect = new fabric.fabric.Rect({
|
|
1385
|
+
width: groupWidth,
|
|
1386
|
+
height: groupHeight,
|
|
1387
|
+
fill: bgColor,
|
|
1388
|
+
originX: "left",
|
|
1389
|
+
originY: "top",
|
|
1390
|
+
rx: 5,
|
|
1391
|
+
ry: 5,
|
|
1392
|
+
left: 0,
|
|
1393
|
+
top: 0
|
|
1394
|
+
});
|
|
1395
|
+
const textBasicInfo = {
|
|
1396
|
+
isBack: backgroundColor ? true : false,
|
|
1397
|
+
colorValue: textFill,
|
|
1398
|
+
colorName: "custom",
|
|
1399
|
+
textAlign: alignType === 1 ? "center" : alignType === 2 ? "right" : "left"
|
|
1400
|
+
};
|
|
1401
|
+
const group = new fabric.fabric.Group([bgRect, ...textObjs], {
|
|
1402
|
+
left,
|
|
1403
|
+
top,
|
|
1404
|
+
scaleX,
|
|
1405
|
+
scaleY,
|
|
1406
|
+
angle: posParam.rotationZ,
|
|
1407
|
+
originX: "center",
|
|
1408
|
+
originY: "center",
|
|
1409
|
+
clipData: {
|
|
1410
|
+
id: clip.id,
|
|
1411
|
+
inPoint: clip.inPoint,
|
|
1412
|
+
inFrame: vmmlUtils.getFrames(clip.inPoint, 30),
|
|
1413
|
+
type: "\u6587\u5B57",
|
|
1414
|
+
textColor: textFill,
|
|
1415
|
+
text: textContent,
|
|
1416
|
+
bgColor,
|
|
1417
|
+
originClip: clip,
|
|
1418
|
+
fontAssetUrl,
|
|
1419
|
+
fontFamily,
|
|
1420
|
+
textBasicInfo,
|
|
1421
|
+
duration: clip.duration
|
|
1422
|
+
},
|
|
1423
|
+
objectCaching: false
|
|
1424
|
+
});
|
|
1425
|
+
group.on("selected", (options) => {
|
|
1426
|
+
options.target.isSelected = -1;
|
|
1427
|
+
});
|
|
1428
|
+
group.on("moving", (options) => {
|
|
1429
|
+
options.transform.target.isSelected = 0;
|
|
1430
|
+
});
|
|
1431
|
+
group.on("modified", () => {
|
|
1432
|
+
const fObj = convertToJSON(group);
|
|
1433
|
+
if (fObj.clipData.isAiError) {
|
|
1434
|
+
fObj.clipData.textColor = "rgba(0, 0, 0, 0)";
|
|
1435
|
+
}
|
|
1436
|
+
if (isBatchModify) {
|
|
1437
|
+
onBatchModify(fObj, canvas);
|
|
1438
|
+
} else {
|
|
1439
|
+
vmmlConverterRef.current.updateClip(fObj);
|
|
1440
|
+
}
|
|
1441
|
+
});
|
|
1442
|
+
resolve(group);
|
|
1443
|
+
});
|
|
1444
|
+
};
|
|
1314
1445
|
const createTextFromClip = async (clip, fc2) => {
|
|
1315
1446
|
return new Promise(async (resolve) => {
|
|
1316
1447
|
const canvas = fc || fc2;
|
|
@@ -1391,6 +1522,7 @@ var EditorCanvas = react.forwardRef(
|
|
|
1391
1522
|
vmmlConverterRef.current.updateClip(fObj);
|
|
1392
1523
|
}
|
|
1393
1524
|
});
|
|
1525
|
+
console.log("fabricjs>>>end>>>>>>>>>>>>");
|
|
1394
1526
|
resolve(imgData);
|
|
1395
1527
|
});
|
|
1396
1528
|
});
|
|
@@ -1429,17 +1561,25 @@ var EditorCanvas = react.forwardRef(
|
|
|
1429
1561
|
};
|
|
1430
1562
|
const loadFont = async (url) => {
|
|
1431
1563
|
if (!url) return null;
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
const fontFamilyName = getFontFamilyName(url);
|
|
1435
|
-
const format = detectFontFormat(url);
|
|
1436
|
-
const fontFace = new FontFace(fontFamilyName, `url(${base64})${format ? ` format('${format}')` : ""}`);
|
|
1437
|
-
await fontFace.load();
|
|
1438
|
-
document.fonts.add(fontFace);
|
|
1439
|
-
return base64;
|
|
1440
|
-
} catch (e) {
|
|
1441
|
-
return null;
|
|
1564
|
+
if (fontCacheRef.current.has(url)) {
|
|
1565
|
+
return fontCacheRef.current.get(url);
|
|
1442
1566
|
}
|
|
1567
|
+
const loadPromise = (async () => {
|
|
1568
|
+
try {
|
|
1569
|
+
const base64 = await vmmlUtils.urlToBlob({ url });
|
|
1570
|
+
const fontFamilyName = getFontFamilyName(url);
|
|
1571
|
+
const format = detectFontFormat(url);
|
|
1572
|
+
const fontFace = new FontFace(fontFamilyName, `url(${base64})${format ? ` format('${format}')` : ""}`);
|
|
1573
|
+
await fontFace.load();
|
|
1574
|
+
document.fonts.add(fontFace);
|
|
1575
|
+
return base64;
|
|
1576
|
+
} catch (e) {
|
|
1577
|
+
console.error("Font load failed:", url, e);
|
|
1578
|
+
return null;
|
|
1579
|
+
}
|
|
1580
|
+
})();
|
|
1581
|
+
fontCacheRef.current.set(url, loadPromise);
|
|
1582
|
+
return loadPromise;
|
|
1443
1583
|
};
|
|
1444
1584
|
const setTextAlign = (p, stroke, direction) => {
|
|
1445
1585
|
if (direction === "center") {
|