@versa_ai/vmml-editor 1.0.41 → 1.0.43

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @versa_ai/vmml-editor@1.0.41 build D:\code\work\vmml-player\packages\editor
2
+ > @versa_ai/vmml-editor@1.0.43 build D:\code\work\vmml-player\packages\editor
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.tsx
@@ -124,12 +124,12 @@ More info and automated migrator: https://sass-lang.com/d/slash-div [35
124
124
 
125
125
 
126
126
 
127
- CJS dist\index.js 122.59 KB
128
- CJS dist\index.js.map 234.64 KB
129
- CJS ⚡️ Build success in 868ms
130
- ESM dist\index.mjs 120.90 KB
131
- ESM dist\index.mjs.map 234.34 KB
132
- ESM ⚡️ Build success in 868ms
133
- DTS ⚡️ Build success in 1828ms
127
+ ESM dist\index.mjs 119.67 KB
128
+ ESM dist\index.mjs.map 232.93 KB
129
+ ESM ⚡️ Build success in 941ms
130
+ CJS dist\index.js 121.47 KB
131
+ CJS dist\index.js.map 233.24 KB
132
+ CJS ⚡️ Build success in 942ms
133
+ DTS ⚡️ Build success in 1928ms
134
134
  DTS dist\index.d.ts 158.00 B
135
135
  DTS dist\index.d.mts 158.00 B
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var vmmlPlayer = require('@versa_ai/vmml-player');
4
+ var cloneDeep = require('lodash.clonedeep');
4
5
  var react = require('react');
5
6
  var vmmlUtils = require('@versa_ai/vmml-utils');
6
7
  var remotion = require('remotion');
@@ -9,6 +10,10 @@ var fabric = require('fabric');
9
10
  var uuid = require('uuid');
10
11
  var domToImage = require('dom-to-image');
11
12
 
13
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
+
15
+ var cloneDeep__default = /*#__PURE__*/_interopDefault(cloneDeep);
16
+
12
17
  // src/index.tsx
13
18
 
14
19
  // src/assets/css/index.scss
@@ -750,6 +755,32 @@ var VmmlConverter = class {
750
755
  }
751
756
  }
752
757
  }
758
+ updateTextClip(fObj, duration) {
759
+ console.log("updateClip fObj", fObj, this.tracks);
760
+ const posParam = this.setPosParam(fObj);
761
+ const {
762
+ clipData: { id }
763
+ } = fObj;
764
+ const [existClip] = this.findClip(id);
765
+ if (existClip) {
766
+ const { clipData: { text, textColor, bgColor } } = fObj;
767
+ const scale = this.fontSize / 22;
768
+ existClip.duration = duration;
769
+ console.log(bgColor, "bgColor>>>");
770
+ existClip.textClip = {
771
+ ...existClip.textClip,
772
+ posParam,
773
+ backgroundColor: this.toARGB(bgColor),
774
+ textContent: text,
775
+ textColor: this.toARGB(textColor),
776
+ dimension: {
777
+ width: Math.floor(fObj.width * scale),
778
+ height: Math.floor(fObj.height * scale)
779
+ }
780
+ };
781
+ }
782
+ console.log(this.vmml, "updateText>>>");
783
+ }
753
784
  /**
754
785
  * 删除 Clip
755
786
  * @param id - 实例 id
@@ -757,13 +788,8 @@ var VmmlConverter = class {
757
788
  */
758
789
  deleteClip({ id, type, originClip }) {
759
790
  if (originClip) {
760
- for (const track of this.tracks) {
761
- const clip = (track.clips || []).find((c) => c.id === originClip.id);
762
- if (clip) {
763
- clip.duration = 0;
764
- break;
765
- }
766
- }
791
+ const [existClip] = this.findClip(id);
792
+ existClip.duration = 0;
767
793
  } else {
768
794
  const editorTrack = this.tracks.find((track) => track.editorType === type);
769
795
  const index = editorTrack.clips.findIndex((item) => item.id === id);
@@ -781,9 +807,11 @@ var VmmlConverter = class {
781
807
  }
782
808
  }
783
809
  }
810
+ console.log("\u5220\u9664\u4E4B\u540E\u7684vmml", this.vmml);
784
811
  }
785
812
  changeVmml(newVmml) {
786
813
  this.vmml = newVmml;
814
+ this.tracks = this.vmml.template.tracks;
787
815
  }
788
816
  //切换静音 视频/音频
789
817
  changeMute({ id, isMute }) {
@@ -1071,11 +1099,11 @@ var EditorCanvas = react.forwardRef(
1071
1099
  const ns = Math.floor((f ?? frame) / 30 * 1e6);
1072
1100
  const objects = fc.getObjects();
1073
1101
  objects.forEach((item) => {
1074
- var _a, _b, _c;
1102
+ var _a, _b, _c, _d, _e;
1075
1103
  if (((_a = item == null ? void 0 : item.clipData) == null ? void 0 : _a.type) === "\u6587\u5B57") {
1076
1104
  item.set("visible", item.clipData.duration > 0 && ns >= item.clipData.inPoint && ns < item.clipData.inPoint + (item.clipData.duration || vmml.template.duration));
1077
1105
  } else {
1078
- item.set("visible", item.clipData.duration > 0 && ns >= item.clipData.inPoint && ns < item.clipData.inPoint + ((_c = (_b = item.clipData) == null ? void 0 : _b.fileUrl) == null ? void 0 : _c.duration));
1106
+ item.set("visible", ((_c = (_b = item == null ? void 0 : item.clipData) == null ? void 0 : _b.fileUrl) == null ? void 0 : _c.duration) > 0 && ns >= item.clipData.inPoint && ns < item.clipData.inPoint + ((_e = (_d = item.clipData) == null ? void 0 : _d.fileUrl) == null ? void 0 : _e.duration));
1079
1107
  }
1080
1108
  });
1081
1109
  fc.discardActiveObject();
@@ -1238,7 +1266,6 @@ var EditorCanvas = react.forwardRef(
1238
1266
  objects.push(item.value);
1239
1267
  }
1240
1268
  });
1241
- console.log(editRenderTime.current === time, "editRenderTime.current === time");
1242
1269
  if (editRenderTime.current === time) {
1243
1270
  canvas.add(...objects).renderAll();
1244
1271
  checkObjectInPoint();
@@ -1327,6 +1354,82 @@ var EditorCanvas = react.forwardRef(
1327
1354
  });
1328
1355
  window.dispatchEvent(event);
1329
1356
  };
1357
+ const createTextObjs = async ({ strokeW, stColor, fontAssetUrl = null, letterSpace, bgColor, textContent, textBasicInfo, textColor }) => {
1358
+ let fontFamily = "sansMedium";
1359
+ if (fontAssetUrl) {
1360
+ const base64 = await loadFont(fontAssetUrl);
1361
+ if (base64) {
1362
+ fontFamily = getFontFamilyName(fontAssetUrl);
1363
+ await document.fonts.ready;
1364
+ }
1365
+ }
1366
+ const lines = textContent.split("\n").filter((item) => item);
1367
+ const lineHeight = 22 + strokeW;
1368
+ const paddingX = 7;
1369
+ const groupWidth = Math.max(...lines.map((l) => {
1370
+ let options = { fontSize: 22, fontFamily, strokeWidth: strokeW ?? 0 };
1371
+ if (letterSpace) options.charSpacing = letterSpace;
1372
+ let temp = new fabric.fabric.Text(l, options);
1373
+ return (temp == null ? void 0 : temp.width) ?? 0;
1374
+ })) + paddingX * 2;
1375
+ const groupHeight = lines.length * lineHeight;
1376
+ const textObjs = [];
1377
+ lines.forEach((line, idx) => {
1378
+ const y = -groupHeight / 2 + lineHeight / 2 + idx * lineHeight;
1379
+ let originX = textBasicInfo.textAlign;
1380
+ let left = paddingX;
1381
+ if (originX === "center") {
1382
+ left = groupWidth / 2;
1383
+ } else if (originX === "right") {
1384
+ left = groupWidth - paddingX;
1385
+ }
1386
+ const strokeText = new fabric.fabric.Text(line || " ", {
1387
+ fontFamily,
1388
+ fontSize: 22,
1389
+ fill: "transparent",
1390
+ stroke: stColor,
1391
+ strokeWidth: strokeW,
1392
+ originX,
1393
+ originY: "center",
1394
+ left,
1395
+ top: y,
1396
+ textAlign: "left",
1397
+ objectCaching: false
1398
+ });
1399
+ const fillText = new fabric.fabric.Text(line || " ", {
1400
+ fontFamily,
1401
+ fontSize: 22,
1402
+ fill: textColor,
1403
+ stroke: "transparent",
1404
+ originX,
1405
+ originY: "center",
1406
+ strokeWidth: 0,
1407
+ left,
1408
+ top: y,
1409
+ textAlign: "left",
1410
+ objectCaching: false
1411
+ });
1412
+ if (letterSpace) {
1413
+ fillText.set({ charSpacing: letterSpace });
1414
+ strokeText.set({ charSpacing: letterSpace });
1415
+ }
1416
+ textObjs.push(strokeText, fillText);
1417
+ });
1418
+ const bgRect = new fabric.fabric.Rect({
1419
+ width: groupWidth,
1420
+ height: groupHeight + 13,
1421
+ // padddingY: 6.5
1422
+ fill: bgColor,
1423
+ originX: "left",
1424
+ originY: "center",
1425
+ rx: 5,
1426
+ ry: 5
1427
+ });
1428
+ return {
1429
+ objects: [bgRect, ...textObjs],
1430
+ fontFamily
1431
+ };
1432
+ };
1330
1433
  const createTextFromClipCanvas = async (clip, fc2) => {
1331
1434
  return new Promise(async (resolve) => {
1332
1435
  const canvas = fc || fc2;
@@ -1339,79 +1442,18 @@ var EditorCanvas = react.forwardRef(
1339
1442
  const left = canvasSize.width * posParam.centerX;
1340
1443
  const top = canvasSize.height * posParam.centerY;
1341
1444
  const bgColor = backgroundColor ? vmmlUtils.argbToRgba(backgroundColor) : "transparent";
1445
+ const strokeW = strokeColor && strokeWidth ? strokeWidth * 30 * 1.5 / fontSize : 0;
1342
1446
  const stColor = strokeColor ? vmmlUtils.argbToRgba(strokeColor) : "transparent";
1447
+ const letterSpace = letterSpacing ? letterSpacing * 22 / fontSize * 45 : 0;
1343
1448
  const textFill = vmmlUtils.argbToRgba(textColor || "#ffffffff");
1344
- const strokeW = strokeColor && strokeWidth ? strokeWidth * 26 * 1.5 / fontSize : 0;
1345
- const letterSpace = letterSpacing * 22 / fontSize;
1346
- let fontFamily = "sansMedium";
1347
- if (fontAssetUrl) {
1348
- const base64 = await loadFont(fontAssetUrl);
1349
- if (base64) {
1350
- fontFamily = getFontFamilyName(fontAssetUrl);
1351
- await document.fonts.ready;
1352
- }
1353
- }
1354
- const lines = textContent.split("\n").filter((item) => item);
1355
- const lineHeight = 22 + strokeW;
1356
- const textHeight = lines.length * lineHeight;
1357
- const groupWidth = Math.max(...lines.map((l) => {
1358
- const temp = new fabric.fabric.Text(l || " ", { fontSize: 22, fontFamily, charSpacing: (letterSpace || 0) * 50, strokeWidth: strokeW ?? 0 });
1359
- return (temp == null ? void 0 : temp.width) ?? 0;
1360
- })) + 14;
1361
- const groupHeight = textHeight + 13;
1362
- const textObjs = [];
1363
- lines.forEach((line, idx) => {
1364
- const y = (groupHeight - textHeight) / 2 + idx * lineHeight + lineHeight / 2 + 1;
1365
- const strokeText = new fabric.fabric.Text(line || " ", {
1366
- fontFamily,
1367
- fontSize: 22,
1368
- fill: "transparent",
1369
- stroke: stColor,
1370
- strokeWidth: strokeW,
1371
- originX: "center",
1372
- originY: "center",
1373
- left: groupWidth / 2,
1374
- // 水平居中
1375
- top: y,
1376
- charSpacing: (letterSpace || 0) * 50,
1377
- textAlign: alignType === 1 ? "center" : alignType === 2 ? "right" : "left",
1378
- objectCaching: false
1379
- });
1380
- const fillText = new fabric.fabric.Text(line || " ", {
1381
- fontFamily,
1382
- fontSize: 22,
1383
- fill: textFill,
1384
- stroke: "transparent",
1385
- originX: "center",
1386
- originY: "center",
1387
- strokeWidth: 0,
1388
- left: groupWidth / 2,
1389
- // 水平居中
1390
- top: y,
1391
- charSpacing: (letterSpace || 0) * 50,
1392
- textAlign: alignType === 1 ? "center" : alignType === 2 ? "right" : "left",
1393
- objectCaching: false
1394
- });
1395
- textObjs.push(strokeText, fillText);
1396
- });
1397
- const bgRect = new fabric.fabric.Rect({
1398
- width: groupWidth,
1399
- height: groupHeight,
1400
- fill: bgColor,
1401
- originX: "left",
1402
- originY: "top",
1403
- rx: 5,
1404
- ry: 5,
1405
- left: 0,
1406
- top: 0
1407
- });
1408
1449
  const textBasicInfo = {
1409
1450
  isBack: backgroundColor ? true : false,
1410
1451
  colorValue: textFill,
1411
1452
  colorName: "custom",
1412
1453
  textAlign: alignType === 1 ? "center" : alignType === 2 ? "right" : "left"
1413
1454
  };
1414
- const group = new fabric.fabric.Group([bgRect, ...textObjs], {
1455
+ const { fontFamily, objects } = await createTextObjs({ strokeW, stColor, fontAssetUrl, letterSpace, bgColor, textContent, textBasicInfo, textColor: textFill });
1456
+ const group = new fabric.fabric.Group([...objects], {
1415
1457
  left,
1416
1458
  top,
1417
1459
  scaleX,
@@ -1455,91 +1497,6 @@ var EditorCanvas = react.forwardRef(
1455
1497
  resolve(group);
1456
1498
  });
1457
1499
  };
1458
- const createTextFromClip = async (clip, fc2) => {
1459
- return new Promise(async (resolve) => {
1460
- const canvas = fc || fc2;
1461
- if (!canvas) {
1462
- resolve(null);
1463
- return;
1464
- }
1465
- const { width, height } = vmml.template.dimension;
1466
- const fontSize = vmmlUtils.getFontSize(width, height);
1467
- const { textContent, backgroundColor, textColor, posParam, fontAssetUrl, alignType, strokeColor, strokeWidth, letterSpacing } = clip.textClip;
1468
- const scaleX = posParam.scaleX * fontSize / 22 / widthScaleRef.current;
1469
- const scaleY = posParam.scaleY * fontSize / 22 / heightScaleRef.current;
1470
- const strokeW = strokeWidth * 26 * 1.5 / fontSize;
1471
- const letterSpace = letterSpacing * 22 / fontSize;
1472
- const left = canvasSize.width * posParam.centerX;
1473
- const top = canvasSize.height * posParam.centerY - 2;
1474
- const bgColor = backgroundColor ? vmmlUtils.argbToRgba(backgroundColor) : "transparent";
1475
- const stColor = strokeColor ? vmmlUtils.argbToRgba(strokeColor) : "transparent";
1476
- const isAiError = textContent === "\u8BF7\u8F93\u5165\u6587\u6848" && textColor === "#00000000";
1477
- const textFill = vmmlUtils.argbToRgba(isAiError ? "#ffffffff" : textColor || "#ffffffff");
1478
- const textBasicInfo = {
1479
- isBack: backgroundColor ? true : false,
1480
- colorValue: textFill,
1481
- colorName: "custom",
1482
- textAlign: alignType === 1 ? "center" : alignType === 2 ? "right" : "left"
1483
- };
1484
- const textImgData = await createTextImg({ textContent, bgColor, stColor, strokeW, textColor: textFill, fontAssetUrl, textBasicInfo, letterSpacing: letterSpace });
1485
- const fontJSON = localStorage.getItem("VMML_PLAYER_FONTSMAP");
1486
- let fontMap = {};
1487
- try {
1488
- fontMap = fontJSON ? JSON.parse(fontJSON) : {};
1489
- } catch {
1490
- fontMap = {};
1491
- }
1492
- const fontFamily = fontMap[fontAssetUrl] || "";
1493
- fabric.fabric.Image.fromURL(textImgData.base64Image, (imgData) => {
1494
- imgData.set({
1495
- left,
1496
- top,
1497
- width: textImgData.width,
1498
- height: textImgData.height,
1499
- scaleX,
1500
- scaleY,
1501
- angle: posParam.rotationZ,
1502
- originX: "center",
1503
- originY: "center",
1504
- objectCaching: false,
1505
- clipData: {
1506
- id: clip.id,
1507
- inPoint: clip.inPoint,
1508
- inFrame: vmmlUtils.getFrames(clip.inPoint, 30),
1509
- type: "\u6587\u5B57",
1510
- textColor: textFill,
1511
- text: textContent,
1512
- bgColor,
1513
- originClip: clip,
1514
- fontAssetUrl,
1515
- fontFamily,
1516
- textBasicInfo,
1517
- isAiError,
1518
- duration: clip.duration
1519
- }
1520
- });
1521
- imgData.on("selected", (options) => {
1522
- options.target.isSelected = -1;
1523
- });
1524
- imgData.on("moving", (options) => {
1525
- options.transform.target.isSelected = 0;
1526
- });
1527
- imgData.on("modified", () => {
1528
- const fObj = convertToJSON(imgData);
1529
- if (fObj.clipData.isAiError) {
1530
- fObj.clipData.textColor = "rgba(0, 0, 0, 0)";
1531
- }
1532
- if (isBatchModify) {
1533
- onBatchModify(fObj, canvas);
1534
- } else {
1535
- vmmlConverterRef.current.updateClip(fObj);
1536
- }
1537
- });
1538
- console.log("fabricjs>>>end>>>>>>>>>>>>");
1539
- resolve(imgData);
1540
- });
1541
- });
1542
- };
1543
1500
  const getFontFamilyName = (url) => {
1544
1501
  const filename = url.split("/").pop() || "";
1545
1502
  const name = filename.replace(/\.(ttf|otf|woff2?|eot)$/i, "");
@@ -1708,13 +1665,25 @@ var EditorCanvas = react.forwardRef(
1708
1665
  });
1709
1666
  };
1710
1667
  const updateText = async ({ id, textContent, bgColor, textColor, textBasicInfo, fontAssetUrl }) => {
1711
- const textImgData = await createTextImg({ textContent, bgColor, textColor, fontAssetUrl, textBasicInfo });
1712
- const target = fc.getObjects().find((item) => item.clipData.id === id);
1713
- target.setSrc(textImgData.base64Image, (img) => {
1714
- img.set({
1668
+ var _a;
1669
+ const target = fc.getObjects().find((item) => {
1670
+ var _a2;
1671
+ return ((_a2 = item.clipData) == null ? void 0 : _a2.id) === id;
1672
+ });
1673
+ const center = target.getCenterPoint();
1674
+ const originClip = (_a = target.clipData) == null ? void 0 : _a.originClip;
1675
+ if (originClip && (target == null ? void 0 : target.type) === "group") {
1676
+ const objects = target.getObjects();
1677
+ const strokeText = objects[1];
1678
+ target._objects.length = 0;
1679
+ const { objects: textObjects } = await createTextObjs({ strokeW: strokeText.strokeWidth, stColor: "", fontAssetUrl, letterSpace: strokeText.charSpacing, bgColor, textContent, textBasicInfo, textColor });
1680
+ textObjects.forEach((obj) => {
1681
+ target.addWithUpdate(obj);
1682
+ });
1683
+ target.set({
1715
1684
  visible: true,
1716
1685
  clipData: {
1717
- ...img.clipData,
1686
+ ...target.clipData,
1718
1687
  textBasicInfo,
1719
1688
  textColor,
1720
1689
  text: textContent,
@@ -1722,10 +1691,20 @@ var EditorCanvas = react.forwardRef(
1722
1691
  isAiError: false
1723
1692
  }
1724
1693
  });
1725
- img.setCoords();
1726
- fc.renderAll();
1727
- vmmlConverterRef.current.updateClip(convertToJSON(img));
1728
- });
1694
+ target._calcBounds();
1695
+ target._updateObjectsCoords();
1696
+ target.setPositionByOrigin(center, "center", "center");
1697
+ originClip.textClip = {
1698
+ ...originClip.textClip,
1699
+ textContent,
1700
+ backgroundColor: bgColor,
1701
+ textColor,
1702
+ strokeColor: ""
1703
+ };
1704
+ target.setCoords();
1705
+ fc == null ? void 0 : fc.requestRenderAll();
1706
+ vmmlConverterRef.current.updateClip(convertToJSON(target));
1707
+ }
1729
1708
  };
1730
1709
  const changeObjectVisible = (id, visible = true) => {
1731
1710
  const target = fc.getObjects().find((item) => item.clipData.id === id);
@@ -1749,7 +1728,7 @@ var EditorCanvas = react.forwardRef(
1749
1728
  top: canvasSize.top,
1750
1729
  display: showCanvas ? "block" : "none"
1751
1730
  };
1752
- }, [showCanvas]);
1731
+ }, [showCanvas, canvasSize]);
1753
1732
  react.useEffect(() => {
1754
1733
  if (!fc && canvasSize.width) {
1755
1734
  initCanvas();
@@ -1814,7 +1793,6 @@ var EditorCanvas = react.forwardRef(
1814
1793
  getfcObject,
1815
1794
  checkObjectInPoint,
1816
1795
  createImageFromClip,
1817
- createTextFromClip,
1818
1796
  changeObjectVisible,
1819
1797
  getCanvasCtx
1820
1798
  }), [fc, frame]);
@@ -2597,7 +2575,7 @@ var EditorFn = ({
2597
2575
  pauseWhenBuffering = false,
2598
2576
  isBatchModify = false,
2599
2577
  textWarapCenter = false,
2600
- hideConfig = null
2578
+ hideConfig = { hideDelete: false, hideEdit: false, hideMute: false, hideVolume: false }
2601
2579
  // { hideDelete: false, hideEdit: false, hideMute: false, hideVolume: false }
2602
2580
  }, ref) => {
2603
2581
  var _a;
@@ -2805,6 +2783,10 @@ var EditorFn = ({
2805
2783
  const onPause = () => {
2806
2784
  setShowCanvas(true);
2807
2785
  setIsPlaying(false);
2786
+ if (canvasRef.current) {
2787
+ const { current: canvasC } = canvasRef;
2788
+ canvasC.checkObjectInPoint();
2789
+ }
2808
2790
  };
2809
2791
  const onWaiting = () => {
2810
2792
  var _a2, _b;
@@ -2842,7 +2824,6 @@ var EditorFn = ({
2842
2824
  if (fcTracks.length) {
2843
2825
  const clips = fcTracks.map((item) => item.clips).flat().filter((item) => Reflect.has(item, "fObj"));
2844
2826
  const fObjs = clips.map((item) => item.fObj);
2845
- setInitFcObjs(fObjs);
2846
2827
  fObjs.forEach((item) => {
2847
2828
  onVideoChange(item.clipData);
2848
2829
  });
@@ -2945,9 +2926,8 @@ var EditorFn = ({
2945
2926
  if (!playing) needPlay.current = false;
2946
2927
  const currentFrame = checkFrame ?? (((_c = player == null ? void 0 : player.getCurrentFrame) == null ? void 0 : _c.call(player)) ?? frame ?? pauseFrame);
2947
2928
  setFrame(currentFrame);
2948
- const convertedVmml = v;
2929
+ const convertedVmml = cloneDeep__default.default(v);
2949
2930
  const isSame = JSON.stringify(convertedVmml) == JSON.stringify(vmmlState);
2950
- console.log(isSame, "VMML\u662F\u5426\u76F8\u540C", convertedVmml, vmmlState);
2951
2931
  if (!isSame) {
2952
2932
  (_e = (_d = canvasCurrent == null ? void 0 : canvasCurrent.getCanvasCtx()) == null ? void 0 : _d.clear) == null ? void 0 : _e.call(_d);
2953
2933
  setVmmlState(convertedVmml);