@versa_ai/vmml-editor 1.0.11 → 1.0.13

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.11",
3
+ "version": "1.0.13",
4
4
  "module": "dist/index.mjs",
5
5
  "main": "dist/index.mjs",
6
6
  "types": "dist/index.d.mts",
@@ -16,8 +16,8 @@
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.14",
20
- "@versa_ai/vmml-utils": "1.0.14"
19
+ "@versa_ai/vmml-utils": "1.0.15",
20
+ "@versa_ai/vmml-player": "1.1.15"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@biomejs/biome": "^1.7.1",
@@ -1,7 +1,6 @@
1
1
  .editor{
2
2
  background: #000;
3
3
  width: 100%;
4
- min-height: 100vh;
5
4
  overflow: hidden;
6
5
  display: flex;
7
6
  flex-direction: column;
@@ -59,12 +58,16 @@
59
58
  }
60
59
 
61
60
  .editor-vessel {
62
- padding-top: 3.2vw;
61
+ width: 100%;
62
+ // padding-top: 3.2vw;
63
+ height: 100%;
63
64
  }
64
65
  //player与画布
65
66
  .main{
66
- width: 81.467vw;
67
- height: 144.8vw;
67
+ // width: 81.467vw;
68
+ width: 100%;
69
+ height: 100%;
70
+ // height: 144.8vw;
68
71
  margin: auto;
69
72
  position: relative;
70
73
  display: flex;
@@ -250,3 +253,64 @@
250
253
  }
251
254
 
252
255
  }
256
+
257
+ @media screen and (min-width: 750px) {
258
+ .editor {
259
+ .controls-box {
260
+ height: 20% !important;
261
+ border-radius: 3.2vw;
262
+ }
263
+ .player-controls {
264
+ display: flex;
265
+ align-items: center;
266
+ width: 100%;
267
+ height: 100%;
268
+ padding: 0 1%;
269
+ .mr-16 {
270
+ margin-right: 2.13vw;
271
+ }
272
+ .player-controls-toggle {
273
+ >img {
274
+ display: block;
275
+ width: 40px !important;
276
+ height: 40px !important;
277
+ cursor: pointer;
278
+ }
279
+ }
280
+ .player-controls-seekbar {
281
+ flex: 1;
282
+ .seekbar-container {
283
+ height: 2px !important;
284
+ .seekbar-background {
285
+ height: 10px !important;
286
+ width: 100%;
287
+ border-radius: 1vw;
288
+ .seekbar-fill {
289
+ width: 100%;
290
+ height: 80%;
291
+ border-radius: 1vw;
292
+ }
293
+ .seekbar-line {
294
+ height: 100%;
295
+ border-radius: 1vw;
296
+ }
297
+ .seekbar-sign {
298
+ width: 10px;
299
+ top: 50%;
300
+ margin-top: -6px;
301
+ }
302
+ .seekbar-cirle {
303
+ top: -10px !important;
304
+ width: 40px !important;
305
+ height: 40px !important;
306
+ }
307
+ }
308
+ }
309
+ }
310
+ .player-controls-time {
311
+ width: 6vw !important;
312
+ }
313
+ }
314
+ }
315
+ }
316
+
@@ -347,21 +347,43 @@ const EditorCanvas = forwardRef(
347
347
  waitFcTasks.current.push(createTextFromClip.bind(this, clip));
348
348
  }
349
349
  }
350
+
351
+ // 生成简短的字体名称
352
+ const getFontFamilyName = (url: string) => {
353
+ // 从URL中提取文件名作为字体名称
354
+ const filename = url.split('/').pop() || '';
355
+ const name = filename.replace(/\.(ttf|otf|woff2?|eot)$/i, '');
356
+ return `CustomFont_${name.substring(0, 20)}`; // 限制长度
357
+ };
358
+
359
+ // 检测字体格式
360
+ const detectFontFormat = (url: string) => {
361
+ const lower = url.toLowerCase();
362
+ if (lower.includes('.woff2')) return 'woff2';
363
+ if (lower.includes('.woff')) return 'woff';
364
+ if (lower.includes('.otf')) return 'opentype';
365
+ if (lower.includes('.ttf')) return 'truetype';
366
+ return null;
367
+ };
350
368
 
351
369
  const embedFontInSVG = async (svgString: string, url: string) => {
352
- if (url) {
353
- const res = await urlToBlob({ url });
354
- const fontFace = `
355
- @font-face {
356
- font-family: 'font-${url}';
357
- src: url(${res});
358
- }
359
- `;
360
- const styleElement = `<style type="text/css"><![CDATA[${fontFace}]]></style>`;
361
- return svgString.replace('</svg>', `${styleElement}</svg>`);
362
- }
363
- return svgString
364
- }
370
+ if (url) {
371
+ const res = await urlToBlob({ url });
372
+ const format = detectFontFormat(url);
373
+ const fontFamilyName = getFontFamilyName(url);
374
+ const srcValue = format ? `url('${res}') format('${format}')` : `url('${res}')`;
375
+ const fontFace = `
376
+ @font-face {
377
+ font-family: '${fontFamilyName}';
378
+ src: ${srcValue};
379
+ }
380
+ `;
381
+ const styleElement = `<style type="text/css"><![CDATA[${fontFace}]]></style>`;
382
+ const result = svgString.replace('</svg>', `${styleElement}</svg>`);
383
+ return result;
384
+ }
385
+ return svgString
386
+ }
365
387
 
366
388
  //文字转图片
367
389
  const createTextImg = async ({ textContent, bgColor, textColor, fontAssetUrl = null, textBasicInfo }: any) => {
@@ -373,13 +395,14 @@ const EditorCanvas = forwardRef(
373
395
  container.style.display = 'inline-block'
374
396
  container.style.textAlign = textBasicInfo.textAlign || 'left';
375
397
  const lines = textContent.split('\n');
398
+ const fontFamily = fontAssetUrl ? getFontFamilyName(fontAssetUrl) : 'sansMedium';
376
399
  lines.forEach((line: string) => {
377
400
  const p = document.createElement('p');
378
401
  p.style.color = textColor;
379
402
  p.style.fontSize = '22px'
380
403
  p.style.lineHeight = '22px'
381
404
  const font = fontAssetUrl ? `font-${fontAssetUrl}` : 'sansMedium';
382
- p.style.fontFamily = font
405
+ p.style.fontFamily = fontFamily;
383
406
  p.style.whiteSpace = "nowrap"
384
407
  // p.style.backgroundColor = bgColor;
385
408
  p.style.padding = '0';
package/src/index.tsx CHANGED
@@ -26,6 +26,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
26
26
  editableArray = [],
27
27
  templateId,
28
28
  strategyId,
29
+ height = '100vh',
29
30
  pauseWhenBuffering = false,
30
31
  }: any,
31
32
  ref: any,
@@ -444,7 +445,7 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
444
445
 
445
446
  return (
446
447
  <>
447
- <div className="editor">
448
+ <div className="editor" style={{ height }}>
448
449
  <div className="editor-vessel" onClick={() => {
449
450
  setMenuState("")
450
451
  }}>
@@ -496,7 +497,8 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
496
497
  </section>
497
498
  </div>
498
499
  <div className="padding-box"></div>
499
- <section style={menuStyles} className={`footer ${menuState === 'text' ? 'text-style' : ''}`}>
500
+ {
501
+ (maxText > 0 || maxVideo > 0) && <section style={menuStyles} className={`footer ${menuState === 'text' ? 'text-style' : ''}`}>
500
502
  {
501
503
  maxText > 0 && (
502
504
  <div
@@ -524,6 +526,8 @@ const EditorFn = <Schema extends AnyZodObject, Props>(
524
526
  )
525
527
  }
526
528
  </section>
529
+ }
530
+
527
531
  {
528
532
  maxVideo > 0 && (
529
533
  <VideoMenu menuState={menuState} createImage={createImage} videoMenus={videoMenus} />