@versa_ai/vmml-editor 1.0.45 → 1.0.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versa_ai/vmml-editor",
3
- "version": "1.0.45",
3
+ "version": "1.0.47",
4
4
  "module": "dist/index.mjs",
5
5
  "main": "dist/index.mjs",
6
6
  "types": "dist/index.d.mts",
@@ -17,7 +17,7 @@
17
17
  "remotion": "4.0.166",
18
18
  "uuid": "^10.0.0",
19
19
  "zod": "^3.23.8",
20
- "@versa_ai/vmml-player": "1.1.22",
20
+ "@versa_ai/vmml-player": "1.1.24",
21
21
  "@versa_ai/vmml-utils": "1.0.15"
22
22
  },
23
23
  "devDependencies": {
@@ -5,7 +5,6 @@ import { v4 as uuidv4 } from "uuid";
5
5
  import HistoryClass from "../utils/HistoryClass";
6
6
  import VmmlConverter from "../utils/VmmlConverter";
7
7
  import { usePeekControl } from "../utils/usePeekControl";
8
- import { toSvg } from 'dom-to-image'
9
8
 
10
9
  const EditorCanvas = forwardRef(
11
10
  ({ previewState, showCanvas, canvasSize, enterPreview, intoTextEdit, frame, vmml, dragState, initFcObjs, editClips = [], onVideoChange, isBatchModify, hideConfig, textWarapCenter }: any, ref: any) => {
@@ -511,26 +510,6 @@ const EditorCanvas = forwardRef(
511
510
  return null;
512
511
  };
513
512
 
514
- const embedFontInSVG = async (svgString: string, url: string, fontBase64?: any) => {
515
- if (url) {
516
- let res = fontBase64;
517
- if (!res) await urlToBlob({ url });
518
- const format = detectFontFormat(url);
519
- const fontFamilyName = getFontFamilyName(url);
520
- const srcValue = format ? `url('${res}') format('${format}')` : `url('${res}')`;
521
- const fontFace = `
522
- @font-face {
523
- font-family: '${fontFamilyName}';
524
- src: ${srcValue};
525
- }
526
- `;
527
- const styleElement = `<style type="text/css"><![CDATA[${fontFace}]]></style>`;
528
- const result = svgString.replace('</svg>', `${styleElement}</svg>`);
529
- return result;
530
- }
531
- return svgString
532
- }
533
-
534
513
  const loadFont = async (url: any) => {
535
514
  if (!url) return null
536
515
 
@@ -558,128 +537,56 @@ const EditorCanvas = forwardRef(
558
537
  fontCacheRef.current.set(url, loadPromise as any);
559
538
  return loadPromise;
560
539
  }
561
-
562
- const setTextAlign = (p: any, stroke: any, direction: 'left' | 'center' | 'right') => {
563
- if (direction === 'center') {
564
- p.style.justifyContent = 'center'
565
- stroke.style.left = "50%";
566
- stroke.style.top = "50%";
567
- stroke.style.transform = 'translate(-50%, -50%)';
568
- }
569
- if (direction === 'left') {
570
- stroke.style.left = "0";
571
- stroke.style.top = "0";
572
- stroke.style.transform = 'none';
573
- }
574
- if (direction === 'right') {
575
- p.style.justifyContent = 'flex-end'
576
- stroke.style.right = "0";
577
- stroke.style.top = "50%";
578
- stroke.style.transform = 'translateY(-50%)';
579
- }
580
- }
581
-
582
- //文字转图片
583
- const createTextImg = async ({ textContent, bgColor, textColor, stColor, strokeW, fontAssetUrl = null, textBasicInfo, letterSpacing }: any) => {
584
- const fontBase64 = await loadFont(fontAssetUrl);
585
- const container = document.createElement('div');
586
- container.style.backgroundColor = bgColor
587
- container.style.boxSizing = 'content-box'
588
- container.style.display = 'inline-block'
589
- container.style.textAlign = textBasicInfo.textAlign || 'left';
590
- const lines = textContent.split('\n');
591
- const fontFamily = fontAssetUrl ? getFontFamilyName(fontAssetUrl) : 'sansMedium';
592
- lines.forEach((line: string) => {
593
- const p = document.createElement('p');
594
- p.style.position = 'relative';
595
- p.style.display = 'flex';
596
- p.style.fontSize = '22px';
597
- p.style.lineHeight = '22px';
598
- p.style.fontFamily = fontFamily;
599
- p.style.whiteSpace = 'nowrap';
600
- p.style.margin = '0';
601
- p.style.padding = '0';
602
- if (letterSpacing) p.style.letterSpacing = `${letterSpacing}px`;
603
- p.style.zIndex = '2'
604
-
605
- const fill = document.createElement('span');
606
- fill.textContent = line || ' ';
607
- fill.style.color = textColor;
608
- fill.style.position = 'relative';
609
- fill.style.zIndex = '1'
610
-
611
- const stroke = document.createElement('span');
612
- stroke.textContent = line || ' ';
613
- stroke.style.position = 'absolute';
614
-
615
- stroke.style.color = 'transparent';
616
- stroke.style.webkitTextStrokeWidth = `${strokeW}px`;
617
- stroke.style.webkitTextStrokeColor = stColor;
618
-
619
- let dr = textBasicInfo.textAlign || 'left'
620
- if (textWarapCenter) dr = 'center'
621
- setTextAlign(p, stroke, dr)
622
-
623
- p.appendChild(fill);
624
- p.appendChild(stroke);
625
- container.appendChild(p);
626
- });
627
- container.style.padding = '6.5px 7px 6.5px 7px'
628
- // container.style.padding = '7.5px 7px 5.8px 7px'
629
- container.style.borderRadius = '5px'
630
- document.body.appendChild(container)
631
- const { width, height } = container?.getBoundingClientRect() as any;
632
- const dataurl = await toSvg(container);
633
- document.body.removeChild(container);
634
- const base64Image = await embedFontInSVG(dataurl, fontAssetUrl, fontBase64);
635
- return { base64Image, height, width };
636
- }
540
+ // 创建文字
637
541
  const createText = async ({ textContent, bgColor, textColor, position, textBasicInfo, id }: any, fc2: any) => {
638
542
  const canvas = fc || fc2;
639
543
  const { left, top, angle, scaleX, scaleY, zoomX, zoomY } = position;
640
- const textImgData = await createTextImg({ textContent, bgColor, textColor, textBasicInfo });
544
+ const { objects } = await createTextObjs({ strokeW: 0, stColor: '', fontAssetUrl: null, letterSpace: 0, bgColor, textContent, textBasicInfo, textColor});
545
+
641
546
  return new Promise((resolve, reject) => {
642
- fabric.Image.fromURL(textImgData.base64Image, (imgData: any) => {
643
- imgData.set({
644
- left,
645
- top,
646
- angle,
647
- width: textImgData.width,
648
- height: textImgData.height,
649
- scaleX,
650
- scaleY,
651
- clipData: {
652
- id: uuidv4(),
653
- inPoint: Math.floor((frame / 30) * 1000000),
654
- inFrame: frame,
655
- type: "文字",
656
- textBasicInfo,
657
- textColor: textColor,
658
- text: textContent,
659
- bgColor: bgColor
660
- },
661
- })
662
- imgData.on("selected", (options: any) => {
663
- options.target.isSelected = -1;
664
- });
665
- imgData.on("moving", (options: any) => {
666
- options.transform.target.isSelected = 0;
667
- });
668
- imgData.on('modified', () => {
669
- const fObj = convertToJSON(imgData)
670
- vmmlConverterRef.current.updateClip(fObj);
671
- });
672
- canvas.centerObject(imgData);
673
- canvas.add(imgData)
674
- setTimeout(() => {
675
- canvas.renderAll();
676
- })
677
- onVideoChange(imgData.clipData);
678
- vmmlConverterRef.current.addTextClip(convertToJSON(imgData));
679
- resolve(true);
547
+ const group = new fabric.Group([...objects], {
548
+ left,
549
+ top,
550
+ scaleX,
551
+ scaleY,
552
+ angle,
553
+ originX: 'center',
554
+ originY: 'center',
555
+ clipData: {
556
+ duration: vmmlConverterRef.current.vmml.template.duration,
557
+ id: uuidv4(),
558
+ inPoint: Math.floor((frame / 30) * 1000000),
559
+ inFrame: frame,
560
+ type: "文字",
561
+ textBasicInfo,
562
+ textColor: textColor,
563
+ text: textContent,
564
+ bgColor: bgColor,
565
+ visible: true
566
+ },
567
+ });
568
+ group.on("selected", (options: any) => {
569
+ options.target.isSelected = -1;
570
+ });
571
+ group.on("moving", (options: any) => {
572
+ options.transform.target.isSelected = 0;
573
+ });
574
+ group.on('modified', () => {
575
+ const fObj = convertToJSON(group)
576
+ vmmlConverterRef.current.updateClip(fObj);
577
+ });
578
+ canvas.centerObject(group);
579
+ canvas.add(group)
580
+ setTimeout(() => {
581
+ canvas.renderAll();
680
582
  })
583
+ onVideoChange(group?.clipData??null);
584
+ vmmlConverterRef.current.addTextClip(convertToJSON(group));
585
+ resolve(true);
681
586
  })
682
- };
587
+
588
+ }
589
+ // 修改文字
683
590
  const updateText = async ({ id, textContent, bgColor, textColor, textBasicInfo, fontAssetUrl }: any) => {
684
591
  // 1. 找到目标对象
685
592
  const target = fc.getObjects().find((item: any) => item.clipData?.id === id);
package/src/index.tsx CHANGED
@@ -376,7 +376,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
376
376
  if (editableArray.length && vmmlState?.template) {
377
377
  initCanEditClips(vmmlState.template.tracks);
378
378
  }
379
- }, [editableArray, refreshEdit, vmmlState]);
379
+ }, [editableArray, vmmlState]);
380
380
 
381
381
  useEffect(() => {
382
382
  if (vmmlState) {