@versa_ai/vmml-editor 1.0.15 → 1.0.17
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 +118 -50
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +118 -50
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/EditorCanvas.tsx +142 -98
- package/src/index.tsx +75 -46
package/package.json
CHANGED
|
@@ -8,9 +8,11 @@ import { usePeekControl } from "../utils/usePeekControl";
|
|
|
8
8
|
import { toSvg } from 'dom-to-image'
|
|
9
9
|
|
|
10
10
|
const EditorCanvas = forwardRef(
|
|
11
|
-
({ previewState, showCanvas, canvasSize, enterPreview, intoTextEdit, frame, vmml, dragState, initFcObjs, onVideoChange, isBatchModify, hideConfig }: any, ref: any) => {
|
|
11
|
+
({ previewState, showCanvas, canvasSize, enterPreview, intoTextEdit, frame, vmml, dragState, initFcObjs, editClips = [], onVideoChange, isBatchModify, hideConfig }: any, ref: any) => {
|
|
12
12
|
const [fc, setFc] = useState<any>(null);
|
|
13
13
|
const [history, setHistory] = useState<any>(null);
|
|
14
|
+
const [canvasReady, setCanvasReady] = useState(false);
|
|
15
|
+
const editRenderTime = useRef(0);
|
|
14
16
|
const waitFcTasks = useRef<any>([]);
|
|
15
17
|
const vmmlConverterRef = useRef<any>(null);
|
|
16
18
|
const heightScaleRef = useRef<number>(1);
|
|
@@ -31,7 +33,8 @@ const EditorCanvas = forwardRef(
|
|
|
31
33
|
setFc(canvas);
|
|
32
34
|
initCanvasEvent(canvas);
|
|
33
35
|
usePeekControl(canvas, hideConfig);
|
|
34
|
-
|
|
36
|
+
setCanvasReady(true);
|
|
37
|
+
};
|
|
35
38
|
|
|
36
39
|
const createFcObjs = (canvas: any) => {
|
|
37
40
|
const ns = Math.floor((frame / 30) * 1000000);
|
|
@@ -216,10 +219,35 @@ const EditorCanvas = forwardRef(
|
|
|
216
219
|
}
|
|
217
220
|
};
|
|
218
221
|
|
|
219
|
-
|
|
220
|
-
const
|
|
222
|
+
const createEditObjes = async (canvas: any, time: number) => {
|
|
223
|
+
const promises = editClips.map((clip: any) => {
|
|
224
|
+
if (clip.videoClip) {
|
|
225
|
+
return createImageFromClip(clip);
|
|
226
|
+
}
|
|
227
|
+
if (clip.textClip && !clip.audioClip) {
|
|
228
|
+
return createTextFromClip(clip);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
const res = await Promise.allSettled(promises);
|
|
232
|
+
const objects: any = [];
|
|
233
|
+
res.forEach((item: any) => {
|
|
234
|
+
if (item.status === 'fulfilled' && item.value) {
|
|
235
|
+
objects.push(item.value);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
if (editRenderTime.current === time) {
|
|
239
|
+
canvas.add(...objects).renderAll();
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// 创建可编辑的videoClip
|
|
244
|
+
const createImageFromClip = (clip: any, fc2?: any) => {
|
|
245
|
+
return new Promise((resolve) => {
|
|
221
246
|
const canvas = fc || fc2;
|
|
222
|
-
if (canvas
|
|
247
|
+
if (!canvas || !canvasSize.width) {
|
|
248
|
+
resolve(null);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
223
251
|
const url = /video/g.test(clip.videoClip.mimeType) ? "" : clip.videoClip.sourceUrl;
|
|
224
252
|
fabric.Image.fromURL(url, (img: any) => {
|
|
225
253
|
const { dimension, posParam } = clip.videoClip;
|
|
@@ -253,27 +281,24 @@ const EditorCanvas = forwardRef(
|
|
|
253
281
|
},
|
|
254
282
|
visible: frame >= inFrame && frame < inFrame + durationFrame
|
|
255
283
|
});
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
vmmlConverterRef.current.updateClip(fObj);
|
|
261
|
-
});
|
|
284
|
+
img.on('modified', () => {
|
|
285
|
+
const fObj = convertToJSON(img);
|
|
286
|
+
fObj.src = "";
|
|
287
|
+
vmmlConverterRef.current.updateClip(fObj);
|
|
262
288
|
});
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
289
|
+
resolve(img);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
}
|
|
267
293
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
294
|
+
const handleRedo = () => {
|
|
295
|
+
history.redo();
|
|
296
|
+
};
|
|
297
|
+
const handleUndo = () => {
|
|
298
|
+
history.undo();
|
|
299
|
+
};
|
|
274
300
|
|
|
275
301
|
const onBatchModify = (fObj: any, canvas: any) => {
|
|
276
|
-
console.log('onBatchModify>>>>>>>>>>>>>>>>>>>>>>>>')
|
|
277
302
|
if (!canvas) return;
|
|
278
303
|
const textObjects = canvas.getObjects().filter((item: any) => item?.clipData?.type === "文字");
|
|
279
304
|
const { left, top, scaleX, scaleY, angle } = fObj;
|
|
@@ -291,72 +316,81 @@ const EditorCanvas = forwardRef(
|
|
|
291
316
|
const updatedFObj = convertToJSON(textObj);
|
|
292
317
|
vmmlConverterRef.current.updateClip(updatedFObj);
|
|
293
318
|
});
|
|
294
|
-
|
|
295
319
|
canvas.renderAll();
|
|
320
|
+
const event = new CustomEvent('editor-vmml-batch-change', {
|
|
321
|
+
detail: {
|
|
322
|
+
vmml: vmmlConverterRef.current?.vmml ?? null
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
window.dispatchEvent(event);
|
|
296
326
|
}
|
|
297
327
|
|
|
298
|
-
|
|
299
|
-
|
|
328
|
+
// 创建可编辑的textclip
|
|
329
|
+
const createTextFromClip = async (clip: any, fc2?: any) => {
|
|
330
|
+
return new Promise(async (resolve) => {
|
|
300
331
|
const canvas = fc || fc2;
|
|
301
|
-
if (canvas) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
332
|
+
if (!canvas) {
|
|
333
|
+
resolve(null);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const { width, height } = vmml.template.dimension;
|
|
337
|
+
const fontSize = getFontSize(width, height);
|
|
338
|
+
const { textContent, backgroundColor, textColor, posParam, fontAssetUrl, alignType } = clip.textClip;
|
|
339
|
+
const scaleX = posParam.scaleX * fontSize / 22 / widthScaleRef.current;
|
|
340
|
+
const scaleY = posParam.scaleY * fontSize / 22 / heightScaleRef.current;
|
|
341
|
+
const left = canvasSize.width * posParam.centerX;
|
|
342
|
+
const top = canvasSize.height * posParam.centerY;
|
|
343
|
+
const bgColor = backgroundColor ? argbToRgba(backgroundColor) : 'transparent';
|
|
344
|
+
const isAiError = textContent === '请输入文案' && textColor === '#00000000';
|
|
345
|
+
const textFill = argbToRgba(isAiError ? '#ffffffff' : (textColor || '#ffffffff'));
|
|
346
|
+
const textBasicInfo = {
|
|
347
|
+
isBack: backgroundColor ? true : false,
|
|
348
|
+
colorValue: textFill,
|
|
349
|
+
colorName: 'custom',
|
|
350
|
+
textAlign: alignType === 1 ? 'center' : (alignType === 2 ? 'right' : 'left')
|
|
351
|
+
}
|
|
352
|
+
const textImgData = await createTextImg({ textContent, bgColor, textColor: textFill, fontAssetUrl, textBasicInfo });
|
|
353
|
+
const fontJSON = localStorage.getItem("VMML_PLAYER_FONTSMAP");
|
|
354
|
+
let fontMap: any = {};
|
|
355
|
+
try {
|
|
356
|
+
fontMap = fontJSON ? JSON.parse(fontJSON) : {};
|
|
357
|
+
} catch {
|
|
358
|
+
fontMap = {};
|
|
359
|
+
}
|
|
360
|
+
const fontFamily = fontMap[fontAssetUrl] || '';
|
|
361
|
+
fabric.Image.fromURL(textImgData.base64Image, (imgData: any) => {
|
|
362
|
+
imgData.set({
|
|
363
|
+
left,
|
|
364
|
+
top,
|
|
365
|
+
width: textImgData.width,
|
|
366
|
+
height: textImgData.height,
|
|
367
|
+
scaleX,
|
|
368
|
+
scaleY,
|
|
369
|
+
angle: posParam.rotationZ,
|
|
370
|
+
originX: 'center',
|
|
371
|
+
originY: 'center',
|
|
372
|
+
clipData: {
|
|
373
|
+
id: clip.id,
|
|
374
|
+
inPoint: clip.inPoint,
|
|
375
|
+
inFrame: getFrames(clip.inPoint, 30),
|
|
376
|
+
type: "文字",
|
|
377
|
+
textColor: textFill,
|
|
378
|
+
text: textContent,
|
|
379
|
+
bgColor,
|
|
380
|
+
originClip: clip,
|
|
381
|
+
fontAssetUrl,
|
|
382
|
+
fontFamily,
|
|
383
|
+
textBasicInfo,
|
|
384
|
+
isAiError,
|
|
385
|
+
duration: clip.duration
|
|
386
|
+
},
|
|
387
|
+
})
|
|
388
|
+
imgData.on("selected", (options: any) => {
|
|
389
|
+
options.target.isSelected = -1;
|
|
390
|
+
});
|
|
391
|
+
imgData.on("moving", (options: any) => {
|
|
392
|
+
options.transform.target.isSelected = 0;
|
|
393
|
+
});
|
|
360
394
|
imgData.on('modified', () => {
|
|
361
395
|
const fObj = convertToJSON(imgData);
|
|
362
396
|
if (fObj.clipData.isAiError) {
|
|
@@ -368,12 +402,10 @@ const EditorCanvas = forwardRef(
|
|
|
368
402
|
vmmlConverterRef.current.updateClip(fObj);
|
|
369
403
|
}
|
|
370
404
|
});
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
}
|
|
405
|
+
resolve(imgData);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
}
|
|
377
409
|
|
|
378
410
|
// 生成简短的字体名称
|
|
379
411
|
const getFontFamilyName = (url: string) => {
|
|
@@ -529,7 +561,6 @@ const EditorCanvas = forwardRef(
|
|
|
529
561
|
return fc.getObjects();
|
|
530
562
|
}
|
|
531
563
|
}
|
|
532
|
-
|
|
533
564
|
const styles: any = useMemo(() => {
|
|
534
565
|
return {
|
|
535
566
|
position: "absolute",
|
|
@@ -565,11 +596,19 @@ const EditorCanvas = forwardRef(
|
|
|
565
596
|
}
|
|
566
597
|
}, [fc, dragState])
|
|
567
598
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
599
|
+
useEffect(() => {
|
|
600
|
+
if (canvasSize.width && canvasSize.height && !vmmlConverterRef.current) {
|
|
601
|
+
vmmlConverterRef.current = new VmmlConverter({ vmml, canvasSize });
|
|
602
|
+
}
|
|
603
|
+
}, [canvasSize, vmml]);
|
|
604
|
+
|
|
605
|
+
// 监听 editClips 变化,自动重新渲染(参考 timeline)
|
|
606
|
+
useEffect(() => {
|
|
607
|
+
if (editClips.length && canvasReady && fc) {
|
|
608
|
+
editRenderTime.current = Date.now();
|
|
609
|
+
createEditObjes(fc, editRenderTime.current);
|
|
610
|
+
}
|
|
611
|
+
}, [editClips, canvasReady]);
|
|
573
612
|
|
|
574
613
|
useEffect(() => {
|
|
575
614
|
if (fc) {
|
|
@@ -582,6 +621,10 @@ const EditorCanvas = forwardRef(
|
|
|
582
621
|
}
|
|
583
622
|
}, [fc]);
|
|
584
623
|
|
|
624
|
+
const getCanvasCtx = () => {
|
|
625
|
+
return fc
|
|
626
|
+
}
|
|
627
|
+
|
|
585
628
|
useImperativeHandle(ref, () => ({
|
|
586
629
|
createImage,
|
|
587
630
|
createText,
|
|
@@ -595,8 +638,9 @@ const EditorCanvas = forwardRef(
|
|
|
595
638
|
checkObjectInPoint,
|
|
596
639
|
createImageFromClip,
|
|
597
640
|
createTextFromClip,
|
|
598
|
-
changeObjectVisible
|
|
599
|
-
|
|
641
|
+
changeObjectVisible,
|
|
642
|
+
getCanvasCtx
|
|
643
|
+
}), [fc]);
|
|
600
644
|
|
|
601
645
|
const getActions = () => {
|
|
602
646
|
if (history) {
|
package/src/index.tsx
CHANGED
|
@@ -16,7 +16,7 @@ import { emotionIcon, wordIcon } from "./utils/const";
|
|
|
16
16
|
const historyClass = new HistoryClass();
|
|
17
17
|
const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
18
18
|
{
|
|
19
|
-
vmml,
|
|
19
|
+
vmml: propVmml,
|
|
20
20
|
pauseFrame = 0,
|
|
21
21
|
maxText = 10,
|
|
22
22
|
maxVideo = 5,
|
|
@@ -33,7 +33,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
33
33
|
}: any,
|
|
34
34
|
ref: any,
|
|
35
35
|
) => {
|
|
36
|
-
|
|
36
|
+
const [vmmlState, setVmmlState] = useState<any>(() => convertVmmlTextScaleByForbidden(propVmml));
|
|
37
37
|
const textMenuRef = useRef<any>(null);
|
|
38
38
|
const vmmlPlayerRef = useRef();
|
|
39
39
|
const canvasRef = useRef();
|
|
@@ -45,7 +45,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
45
45
|
const [isPlaying, setIsPlaying] = useState<boolean>(false);
|
|
46
46
|
const [showCanvas, setShowCanvas] = useState(false);
|
|
47
47
|
const [filterIds, setFilterIds] = useState<string[]>([]);
|
|
48
|
-
const [durationInFrames, setDurationInFrames] = useState(getFrames(
|
|
48
|
+
const [durationInFrames, setDurationInFrames] = useState(getFrames(vmmlState?.template?.duration || 1, fps));
|
|
49
49
|
const [previewState, setPreviewState] = useState<boolean>(true); // true预览态 false编辑态
|
|
50
50
|
const [menuState, setMenuState] = useState<string>(""); // text 文字菜单 video 表情包菜单 空不显示
|
|
51
51
|
const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0, top: 0 }); // 画布尺寸
|
|
@@ -58,6 +58,8 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
58
58
|
const [dragState, setDragState] = useState(0);
|
|
59
59
|
const vmmlConverterRef = useRef<any>(null);
|
|
60
60
|
const [initFcObjs, setInitFcObjs] = useState([]);
|
|
61
|
+
const [editClips, setEditClips] = useState<any[]>([]); // 可编辑的 clips
|
|
62
|
+
const [refreshEdit, setRefreshEdit] = useState(0); // 触发画布刷新
|
|
61
63
|
const vmmlFlag = useRef(false);
|
|
62
64
|
const needPlay = useRef(true);
|
|
63
65
|
|
|
@@ -65,9 +67,9 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
65
67
|
const { current }: any = vmmlPlayerRef;
|
|
66
68
|
if (!current) return;
|
|
67
69
|
if (!once.current) {
|
|
68
|
-
current.setVmml(
|
|
70
|
+
current.setVmml(vmmlState, pauseFrame);
|
|
69
71
|
} else {
|
|
70
|
-
current.setVmml(
|
|
72
|
+
current.setVmml(vmmlState, frame);
|
|
71
73
|
}
|
|
72
74
|
};
|
|
73
75
|
|
|
@@ -279,18 +281,9 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
279
281
|
|
|
280
282
|
// 初始化可编辑的clip
|
|
281
283
|
const initCanEditClips = (tracks: any = []) => {
|
|
282
|
-
if (editableArray.length) {
|
|
284
|
+
if (editableArray.length && tracks.length) {
|
|
283
285
|
const list = findEditClips(tracks);
|
|
284
|
-
|
|
285
|
-
const { current }: any = canvasRef;
|
|
286
|
-
list.forEach((clip: any) => {
|
|
287
|
-
if (clip.videoClip) {
|
|
288
|
-
current.createImageFromClip(clip);
|
|
289
|
-
} else {
|
|
290
|
-
if (!clip.audioClip) current.createTextFromClip(clip);
|
|
291
|
-
}
|
|
292
|
-
})
|
|
293
|
-
}
|
|
286
|
+
setEditClips(list); // 直接更新 state,让 Canvas 组件自动处理
|
|
294
287
|
}
|
|
295
288
|
};
|
|
296
289
|
|
|
@@ -324,7 +317,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
324
317
|
// 获取更新后的vmml
|
|
325
318
|
const getVmml = () => {
|
|
326
319
|
try {
|
|
327
|
-
const tracks =
|
|
320
|
+
const tracks = vmmlState.template.tracks.filter((item: any) => item.editorType === "文字");
|
|
328
321
|
tracks.forEach((track: any) => {
|
|
329
322
|
track.clips.forEach((clip: any) => {
|
|
330
323
|
clip.fObj.src = '';
|
|
@@ -333,7 +326,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
333
326
|
} catch {
|
|
334
327
|
console.log("出错了")
|
|
335
328
|
}
|
|
336
|
-
return
|
|
329
|
+
return vmmlState
|
|
337
330
|
};
|
|
338
331
|
|
|
339
332
|
const getPlayer = () => {
|
|
@@ -354,19 +347,35 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
354
347
|
}, [previewState]);
|
|
355
348
|
|
|
356
349
|
useEffect(() => {
|
|
357
|
-
if (canvasSize.width && canvasSize.height &&
|
|
358
|
-
vmmlConverterRef.current
|
|
350
|
+
if (canvasSize.width && canvasSize.height && vmmlState) {
|
|
351
|
+
if (!vmmlConverterRef.current) {
|
|
352
|
+
vmmlConverterRef.current = new VmmlConverter({ vmml: vmmlState, canvasSize });
|
|
353
|
+
} else {
|
|
354
|
+
vmmlConverterRef.current.vmml = vmmlState;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}, [canvasSize, vmmlState]);
|
|
358
|
+
|
|
359
|
+
useEffect(() => {
|
|
360
|
+
if (editableArray.length && vmmlState?.template) {
|
|
361
|
+
initCanEditClips(vmmlState.template.tracks);
|
|
359
362
|
}
|
|
360
|
-
|
|
361
|
-
|
|
363
|
+
}, [editableArray, refreshEdit]);
|
|
364
|
+
|
|
365
|
+
useEffect(() => {
|
|
366
|
+
if (propVmml) {
|
|
367
|
+
const convertedVmml = convertVmmlTextScaleByForbidden(propVmml);
|
|
368
|
+
setVmmlState(convertedVmml);
|
|
369
|
+
setDurationInFrames(getFrames(propVmml?.template?.duration || 1, fps));
|
|
370
|
+
setRefreshEdit(Date.now());
|
|
362
371
|
}
|
|
363
|
-
}, [
|
|
372
|
+
}, [propVmml]);
|
|
364
373
|
|
|
365
374
|
useEffect(() => {
|
|
366
|
-
if (
|
|
367
|
-
initFcObjects(
|
|
375
|
+
if (vmmlState) {
|
|
376
|
+
initFcObjects(vmmlState.template.tracks);
|
|
368
377
|
}
|
|
369
|
-
}, [
|
|
378
|
+
}, [vmmlState]);
|
|
370
379
|
|
|
371
380
|
useEffect(() => {
|
|
372
381
|
if (player) {
|
|
@@ -404,7 +413,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
404
413
|
if (dragState === 2) {
|
|
405
414
|
needPlay.current = false;
|
|
406
415
|
const { current }: any = vmmlPlayerRef;
|
|
407
|
-
current.setVmml(
|
|
416
|
+
current.setVmml(vmmlState, frame, false);
|
|
408
417
|
setShowCanvas(false);
|
|
409
418
|
}
|
|
410
419
|
if (dragState === 3 || dragState === 4) {
|
|
@@ -412,6 +421,24 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
412
421
|
setPreviewState(false);
|
|
413
422
|
}
|
|
414
423
|
}, [dragState]);
|
|
424
|
+
|
|
425
|
+
const updateVmml = (v: any) => {
|
|
426
|
+
const { current: playerCurrent }: any = vmmlPlayerRef;
|
|
427
|
+
const { current: canvasCurrent }: any = canvasRef;
|
|
428
|
+
if (!playerCurrent) return;
|
|
429
|
+
canvasCurrent?.getCanvasCtx()?.clear?.()
|
|
430
|
+
|
|
431
|
+
const convertedVmml = convertVmmlTextScaleByForbidden(v);
|
|
432
|
+
setVmmlState(convertedVmml);
|
|
433
|
+
setDurationInFrames(getFrames(v?.template?.duration || 1, fps));
|
|
434
|
+
playerCurrent.setVmml(convertedVmml, pauseFrame);
|
|
435
|
+
|
|
436
|
+
setRefreshEdit(Date.now());
|
|
437
|
+
|
|
438
|
+
if (canvasCurrent) {
|
|
439
|
+
canvasCurrent.checkObjectInPoint(pauseFrame);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
415
442
|
|
|
416
443
|
useImperativeHandle(ref,
|
|
417
444
|
() => ({
|
|
@@ -420,9 +447,10 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
420
447
|
getVmml,
|
|
421
448
|
getPlayer,
|
|
422
449
|
texteditClose,
|
|
423
|
-
textFinish
|
|
450
|
+
textFinish,
|
|
451
|
+
updateVmml
|
|
424
452
|
}),
|
|
425
|
-
[
|
|
453
|
+
[vmmlState, player]
|
|
426
454
|
)
|
|
427
455
|
const texteditClose = ()=>{
|
|
428
456
|
if (textMenuRef) {
|
|
@@ -455,7 +483,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
455
483
|
<div className="vessel" onClick={onClickMain}>
|
|
456
484
|
<VmmlPlayer
|
|
457
485
|
ref={vmmlPlayerRef}
|
|
458
|
-
vmml={
|
|
486
|
+
vmml={vmmlState}
|
|
459
487
|
existenceBorderRadio
|
|
460
488
|
moveToBeginningWhenEnded
|
|
461
489
|
muted={true}
|
|
@@ -467,22 +495,23 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
|
|
|
467
495
|
filterIds={filterIds}
|
|
468
496
|
/>
|
|
469
497
|
</div>
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
498
|
+
<EditorCanvas
|
|
499
|
+
ref={canvasRef}
|
|
500
|
+
previewState={previewState}
|
|
501
|
+
showCanvas={showCanvas}
|
|
502
|
+
canvasSize={canvasSize}
|
|
503
|
+
enterPreview={enterPreview}
|
|
504
|
+
intoTextEdit={intoTextEdit}
|
|
505
|
+
frame={frame}
|
|
506
|
+
vmml={vmmlState}
|
|
507
|
+
dragState={dragState}
|
|
508
|
+
initFcObjs={initFcObjs}
|
|
509
|
+
editClips={editClips}
|
|
510
|
+
onVideoChange={onVideoChange}
|
|
511
|
+
isBatchModify={isBatchModify}
|
|
512
|
+
hideConfig={hideConfig}
|
|
513
|
+
// textInfoReset={textInfoReset}
|
|
514
|
+
/>
|
|
486
515
|
<div className="controls-box">
|
|
487
516
|
<Controls
|
|
488
517
|
player={player}
|