@versa_ai/vmml-editor 1.0.17 → 1.0.19

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.17",
3
+ "version": "1.0.19",
4
4
  "module": "dist/index.mjs",
5
5
  "main": "dist/index.mjs",
6
6
  "types": "dist/index.d.mts",
@@ -16,7 +16,7 @@
16
16
  "remotion": "4.0.166",
17
17
  "uuid": "^10.0.0",
18
18
  "zod": "^3.23.8",
19
- "@versa_ai/vmml-player": "1.1.15",
19
+ "@versa_ai/vmml-player": "1.1.17",
20
20
  "@versa_ai/vmml-utils": "1.0.15"
21
21
  },
22
22
  "devDependencies": {
@@ -335,12 +335,14 @@ const EditorCanvas = forwardRef(
335
335
  }
336
336
  const { width, height } = vmml.template.dimension;
337
337
  const fontSize = getFontSize(width, height);
338
- const { textContent, backgroundColor, textColor, posParam, fontAssetUrl, alignType } = clip.textClip;
338
+ const { textContent, backgroundColor, textColor, posParam, fontAssetUrl, alignType, strokeColor, strokeWidth } = clip.textClip;
339
339
  const scaleX = posParam.scaleX * fontSize / 22 / widthScaleRef.current;
340
340
  const scaleY = posParam.scaleY * fontSize / 22 / heightScaleRef.current;
341
+ const strokeW = strokeWidth ? (strokeWidth * 22 / fontSize) : 0;
341
342
  const left = canvasSize.width * posParam.centerX;
342
343
  const top = canvasSize.height * posParam.centerY;
343
344
  const bgColor = backgroundColor ? argbToRgba(backgroundColor) : 'transparent';
345
+ const stColor = strokeColor ? argbToRgba(strokeColor) : 'transparent';
344
346
  const isAiError = textContent === '请输入文案' && textColor === '#00000000';
345
347
  const textFill = argbToRgba(isAiError ? '#ffffffff' : (textColor || '#ffffffff'));
346
348
  const textBasicInfo = {
@@ -349,7 +351,7 @@ const EditorCanvas = forwardRef(
349
351
  colorName: 'custom',
350
352
  textAlign: alignType === 1 ? 'center' : (alignType === 2 ? 'right' : 'left')
351
353
  }
352
- const textImgData = await createTextImg({ textContent, bgColor, textColor: textFill, fontAssetUrl, textBasicInfo });
354
+ const textImgData = await createTextImg({ textContent, bgColor, stColor, strokeW, textColor: textFill, fontAssetUrl, textBasicInfo });
353
355
  const fontJSON = localStorage.getItem("VMML_PLAYER_FONTSMAP");
354
356
  let fontMap: any = {};
355
357
  try {
@@ -407,23 +409,22 @@ const EditorCanvas = forwardRef(
407
409
  });
408
410
  }
409
411
 
410
- // 生成简短的字体名称
411
- const getFontFamilyName = (url: string) => {
412
- // 从URL中提取文件名作为字体名称
413
- const filename = url.split('/').pop() || '';
414
- const name = filename.replace(/\.(ttf|otf|woff2?|eot)$/i, '');
415
- return `CustomFont_${name.substring(0, 20)}`; // 限制长度
416
- };
412
+ // 生成简短的字体名称
413
+ const getFontFamilyName = (url: string) => {
414
+ const filename = url.split('/').pop() || '';
415
+ const name = filename.replace(/\.(ttf|otf|woff2?|eot)$/i, '');
416
+ return `CustomFont_${name.substring(0, 20)}`; // 限制长度
417
+ };
417
418
 
418
- // 检测字体格式
419
- const detectFontFormat = (url: string) => {
420
- const lower = url.toLowerCase();
421
- if (lower.includes('.woff2')) return 'woff2';
422
- if (lower.includes('.woff')) return 'woff';
423
- if (lower.includes('.otf')) return 'opentype';
424
- if (lower.includes('.ttf')) return 'truetype';
425
- return null;
426
- };
419
+ // 检测字体格式
420
+ const detectFontFormat = (url: string) => {
421
+ const lower = url.toLowerCase();
422
+ if (lower.includes('.woff2')) return 'woff2';
423
+ if (lower.includes('.woff')) return 'woff';
424
+ if (lower.includes('.otf')) return 'opentype';
425
+ if (lower.includes('.ttf')) return 'truetype';
426
+ return null;
427
+ };
427
428
 
428
429
  const embedFontInSVG = async (svgString: string, url: string) => {
429
430
  if (url) {
@@ -445,7 +446,7 @@ const EditorCanvas = forwardRef(
445
446
  }
446
447
 
447
448
  //文字转图片
448
- const createTextImg = async ({ textContent, bgColor, textColor, fontAssetUrl = null, textBasicInfo }: any) => {
449
+ const createTextImg = async ({ textContent, bgColor, textColor, stColor, strokeW, fontAssetUrl = null, textBasicInfo }: any) => {
449
450
  const container = document.createElement('div');
450
451
  container.style.backgroundColor = bgColor
451
452
  // container.style.width = `fit-content`
@@ -462,8 +463,12 @@ const EditorCanvas = forwardRef(
462
463
  p.style.lineHeight = '22px'
463
464
  p.style.fontFamily = fontFamily;
464
465
  p.style.whiteSpace = "nowrap"
465
- // p.style.backgroundColor = bgColor;
466
466
  p.style.padding = '0';
467
+ p.style.margin = '0';
468
+
469
+ p.style.webkitTextStrokeWidth = `${strokeW ?? 0}px`;
470
+ p.style.webkitTextStrokeColor = stColor;
471
+
467
472
  p.textContent = line || " "
468
473
  container.appendChild(p);
469
474
  })
package/src/index.tsx CHANGED
@@ -55,7 +55,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
55
55
  const videoList = useRef<any>([]);
56
56
  const [signList, setSignList] = useState<any>([]);
57
57
  const [tips, setTips] = useState("");
58
- const [dragState, setDragState] = useState(0);
58
+ const [dragState, setDragState] = useState(0); // 1: onPointerDown 2: onPointerMove 3: onPointerUp 4: onClickSign
59
59
  const vmmlConverterRef = useRef<any>(null);
60
60
  const [initFcObjs, setInitFcObjs] = useState([]);
61
61
  const [editClips, setEditClips] = useState<any[]>([]); // 可编辑的 clips
@@ -76,10 +76,12 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
76
76
  const onPlayerReady = () => {
77
77
  const { current }: any = vmmlPlayerRef;
78
78
  vmmlFlag.current = false;
79
+ let show = false
79
80
  if (current && current.playerRef) {
80
81
  setPlayer(current.playerRef);
81
82
  current.unmute();
82
83
  if (!once.current) {
84
+ show = true
83
85
  once.current = true;
84
86
  } else {
85
87
  if (needPlay.current) {
@@ -89,7 +91,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
89
91
  }
90
92
  }
91
93
  }
92
- setShowCanvas(false);
94
+ setShowCanvas(show);
93
95
  setLoading(false);
94
96
  };
95
97
 
@@ -264,9 +266,11 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
264
266
  setFrame(e.detail.frame)
265
267
  };
266
268
  const onPlay = () => {
269
+ setShowCanvas(false)
267
270
  setIsPlaying(true);
268
271
  };
269
272
  const onPause = () => {
273
+ setShowCanvas(true)
270
274
  setIsPlaying(false);
271
275
  };
272
276
  const onWaiting = () => {
@@ -28,7 +28,7 @@ class VmmlConverter {
28
28
  //更新位置
29
29
  private setPosParam(fObj: any): object {
30
30
  const {
31
- clipData: { type },
31
+ clipData: { type, originClip },
32
32
  centerPoint,
33
33
  scaleX,
34
34
  scaleY,
@@ -36,28 +36,41 @@ class VmmlConverter {
36
36
  width,
37
37
  height,
38
38
  } = fObj;
39
- let _scaleX, _scaleY, _centerX, _centerY;
40
-
39
+ let _scaleX, _scaleY, _centerX, _centerY, _scaleZ, _centerZ, _rotationX, _rotationY;
40
+ let key = '';
41
41
  if (type === "文字") {
42
42
  // const [rect, textbox] = fObj.objects;
43
43
  _scaleX = (22 * scaleX * this.widthScale) / this.fontSize;
44
44
  _scaleY = (22 * scaleY * this.heightScale) / this.fontSize;
45
45
  _centerX = centerPoint.x / this.canvasSize.width;
46
46
  _centerY = centerPoint.y / this.canvasSize.height;
47
+
48
+ key = 'textClip'
47
49
  // fObj.clipData.lineSpacing = 22 * textbox.lineHeight * scaleY * this.heightScale;
48
50
  } else if (type === "表情包") {
49
51
  _scaleX = (width * scaleX * this.widthScale) / width;
50
52
  _scaleY = (height * scaleY * this.heightScale) / height;
51
53
  _centerX = centerPoint.x / this.canvasSize.width;
52
54
  _centerY = centerPoint.y / this.canvasSize.height;
55
+
56
+ key = 'videoClip'
53
57
  }
54
58
 
59
+ _scaleZ = originClip?.[key]?.posParam?.scaleZ ?? 1;
60
+ _centerZ = originClip?.[key]?.posParam?.centerZ ?? 0.5;
61
+ _rotationX = originClip?.[key]?.posParam?.rotationX ?? 0;
62
+ _rotationY = originClip?.[key]?.posParam?.rotationY ?? 0;
63
+
55
64
  return {
56
65
  scaleX: _scaleX,
57
66
  scaleY: _scaleY,
67
+ scaleZ: _scaleZ,
58
68
  centerX: _centerX,
59
69
  centerY: _centerY,
70
+ centerZ: _centerZ,
60
71
  rotationZ: angle,
72
+ rotationX: _rotationX,
73
+ rotationY: _rotationY,
61
74
  };
62
75
  }
63
76