@twick/studio 0.15.24 → 0.15.25
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/dist/helpers/constant.d.ts +15 -0
- package/dist/index.js +351 -160
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +352 -161
- package/dist/index.mjs.map +1 -1
- package/dist/studio.css +119 -1
- package/dist/types/index.d.ts +5 -0
- package/package.json +15 -15
package/dist/index.js
CHANGED
|
@@ -4671,6 +4671,16 @@ function EffectStylePanelContainer({
|
|
|
4671
4671
|
}
|
|
4672
4672
|
);
|
|
4673
4673
|
}
|
|
4674
|
+
const formatTime = (seconds) => {
|
|
4675
|
+
if (!Number.isFinite(seconds) || seconds < 0) return "0:00.00";
|
|
4676
|
+
const totalMs = Math.round(seconds * 1e3);
|
|
4677
|
+
const totalSeconds = Math.floor(totalMs / 1e3);
|
|
4678
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
4679
|
+
const secs = totalSeconds % 60;
|
|
4680
|
+
const ms = Math.floor(totalMs % 1e3 / 10);
|
|
4681
|
+
const pad = (n, l = 2) => String(n).padStart(l, "0");
|
|
4682
|
+
return `${minutes}:${pad(secs)}.${pad(ms)}`;
|
|
4683
|
+
};
|
|
4674
4684
|
function CaptionsPanel({
|
|
4675
4685
|
captions,
|
|
4676
4686
|
addCaption,
|
|
@@ -4678,54 +4688,102 @@ function CaptionsPanel({
|
|
|
4678
4688
|
deleteCaption,
|
|
4679
4689
|
updateCaption
|
|
4680
4690
|
}) {
|
|
4681
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-container", children: [
|
|
4682
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4683
|
-
|
|
4684
|
-
"div",
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4691
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-container captions-panel", children: [
|
|
4692
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "captions-panel-header", children: [
|
|
4693
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "panel-title", children: "Captions" }),
|
|
4694
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "captions-panel-header-meta", children: [
|
|
4695
|
+
captions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "captions-panel-count", children: "No captions yet" }) : null,
|
|
4696
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4697
|
+
"button",
|
|
4698
|
+
{
|
|
4699
|
+
onClick: addCaption,
|
|
4700
|
+
className: "btn-primary captions-panel-add-button",
|
|
4701
|
+
title: "Add caption",
|
|
4702
|
+
children: "Add caption"
|
|
4703
|
+
}
|
|
4704
|
+
)
|
|
4705
|
+
] })
|
|
4706
|
+
] }),
|
|
4707
|
+
captions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-section captions-panel-empty", children: [
|
|
4708
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "captions-panel-empty-title", children: "Start your first caption" }),
|
|
4709
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "captions-panel-empty-subtitle", children: "Use the button above to add the first caption block for the active track." }),
|
|
4710
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4711
|
+
"button",
|
|
4712
|
+
{
|
|
4713
|
+
onClick: addCaption,
|
|
4714
|
+
className: "btn-primary captions-panel-empty-button",
|
|
4715
|
+
title: "Add first caption",
|
|
4716
|
+
children: "Add caption"
|
|
4717
|
+
}
|
|
4718
|
+
)
|
|
4719
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-section captions-panel-list", children: captions.map((caption, i) => {
|
|
4720
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4721
|
+
"div",
|
|
4722
|
+
{
|
|
4723
|
+
className: "captions-panel-item",
|
|
4724
|
+
children: [
|
|
4725
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "captions-panel-item-header", children: [
|
|
4726
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "captions-panel-time captions-panel-time-start", children: formatTime(caption.s) }),
|
|
4727
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "captions-panel-time captions-panel-time-end", children: formatTime(caption.e) })
|
|
4728
|
+
] }),
|
|
4729
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "captions-panel-item-body", children: [
|
|
4730
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4731
|
+
"textarea",
|
|
4732
|
+
{
|
|
4733
|
+
placeholder: "Enter caption text",
|
|
4734
|
+
value: caption.t,
|
|
4735
|
+
onChange: (e) => updateCaption(i, { ...caption, t: e.target.value }),
|
|
4736
|
+
className: "input-dark captions-panel-textarea"
|
|
4737
|
+
}
|
|
4738
|
+
),
|
|
4739
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "captions-panel-actions", children: [
|
|
4740
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4741
|
+
"button",
|
|
4742
|
+
{
|
|
4743
|
+
onClick: () => splitCaption(i),
|
|
4744
|
+
className: "btn-ghost captions-panel-action-button",
|
|
4745
|
+
title: "Split caption at midpoint",
|
|
4746
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Scissors, { className: "icon-sm" })
|
|
4747
|
+
}
|
|
4748
|
+
),
|
|
4749
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4750
|
+
"button",
|
|
4751
|
+
{
|
|
4752
|
+
onClick: () => deleteCaption(i),
|
|
4753
|
+
className: "btn-ghost captions-panel-action-button",
|
|
4754
|
+
title: "Delete caption",
|
|
4755
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4756
|
+
Trash2,
|
|
4757
|
+
{
|
|
4758
|
+
className: "icon-sm",
|
|
4759
|
+
color: "var(--color-red-500)"
|
|
4760
|
+
}
|
|
4761
|
+
)
|
|
4762
|
+
}
|
|
4763
|
+
)
|
|
4764
|
+
] })
|
|
4765
|
+
] })
|
|
4766
|
+
]
|
|
4767
|
+
},
|
|
4768
|
+
i
|
|
4769
|
+
);
|
|
4770
|
+
}) })
|
|
4723
4771
|
] });
|
|
4724
4772
|
}
|
|
4773
|
+
const HIGHLIGHT_BG_FONT_SIZE = 46;
|
|
4774
|
+
const WORD_BY_WORD_FONT_SIZE = 46;
|
|
4775
|
+
const WORD_BY_WORD_WITH_BG_FONT_SIZE = 46;
|
|
4776
|
+
const OUTLINE_ONLY_FONT_SIZE = 42;
|
|
4777
|
+
const SOFT_BOX_FONT_SIZE = 40;
|
|
4778
|
+
const HIGHLIGHT_BG_GEOMETRY = timeline.computeCaptionGeometry(HIGHLIGHT_BG_FONT_SIZE, timeline.CAPTION_STYLE.WORD_BG_HIGHLIGHT);
|
|
4779
|
+
const WORD_BY_WORD_GEOMETRY = timeline.computeCaptionGeometry(WORD_BY_WORD_FONT_SIZE, timeline.CAPTION_STYLE.WORD_BY_WORD);
|
|
4780
|
+
const WORD_BY_WORD_WITH_BG_GEOMETRY = timeline.computeCaptionGeometry(WORD_BY_WORD_WITH_BG_FONT_SIZE, timeline.CAPTION_STYLE.WORD_BY_WORD_WITH_BG);
|
|
4781
|
+
const OUTLINE_ONLY_GEOMETRY = timeline.computeCaptionGeometry(OUTLINE_ONLY_FONT_SIZE, timeline.CAPTION_STYLE.OUTLINE_ONLY);
|
|
4782
|
+
const SOFT_BOX_GEOMETRY = timeline.computeCaptionGeometry(SOFT_BOX_FONT_SIZE, timeline.CAPTION_STYLE.SOFT_BOX);
|
|
4725
4783
|
const CAPTION_PROPS = {
|
|
4726
4784
|
[timeline.CAPTION_STYLE.WORD_BG_HIGHLIGHT]: {
|
|
4727
4785
|
font: {
|
|
4728
|
-
size:
|
|
4786
|
+
size: HIGHLIGHT_BG_FONT_SIZE,
|
|
4729
4787
|
weight: 700,
|
|
4730
4788
|
family: "Bangers"
|
|
4731
4789
|
},
|
|
@@ -4734,15 +4792,16 @@ const CAPTION_PROPS = {
|
|
|
4734
4792
|
highlight: "#ff4081",
|
|
4735
4793
|
bgColor: "#444444"
|
|
4736
4794
|
},
|
|
4737
|
-
lineWidth:
|
|
4795
|
+
lineWidth: HIGHLIGHT_BG_GEOMETRY.lineWidth,
|
|
4796
|
+
rectProps: HIGHLIGHT_BG_GEOMETRY.rectProps,
|
|
4738
4797
|
stroke: "#000000",
|
|
4739
4798
|
fontWeight: 700,
|
|
4740
|
-
shadowOffset: [-
|
|
4799
|
+
shadowOffset: [-1, 1],
|
|
4741
4800
|
shadowColor: "#000000"
|
|
4742
4801
|
},
|
|
4743
4802
|
[timeline.CAPTION_STYLE.WORD_BY_WORD]: {
|
|
4744
4803
|
font: {
|
|
4745
|
-
size:
|
|
4804
|
+
size: WORD_BY_WORD_FONT_SIZE,
|
|
4746
4805
|
weight: 700,
|
|
4747
4806
|
family: "Bangers"
|
|
4748
4807
|
},
|
|
@@ -4751,15 +4810,16 @@ const CAPTION_PROPS = {
|
|
|
4751
4810
|
highlight: "#ff4081",
|
|
4752
4811
|
bgColor: "#444444"
|
|
4753
4812
|
},
|
|
4754
|
-
lineWidth:
|
|
4813
|
+
lineWidth: WORD_BY_WORD_GEOMETRY.lineWidth,
|
|
4814
|
+
rectProps: WORD_BY_WORD_GEOMETRY.rectProps,
|
|
4755
4815
|
stroke: "#000000",
|
|
4756
|
-
shadowOffset: [-
|
|
4816
|
+
shadowOffset: [-1, 1],
|
|
4757
4817
|
shadowColor: "#000000",
|
|
4758
4818
|
shadowBlur: 5
|
|
4759
4819
|
},
|
|
4760
4820
|
[timeline.CAPTION_STYLE.WORD_BY_WORD_WITH_BG]: {
|
|
4761
4821
|
font: {
|
|
4762
|
-
size:
|
|
4822
|
+
size: WORD_BY_WORD_WITH_BG_FONT_SIZE,
|
|
4763
4823
|
weight: 700,
|
|
4764
4824
|
family: "Bangers"
|
|
4765
4825
|
},
|
|
@@ -4768,14 +4828,15 @@ const CAPTION_PROPS = {
|
|
|
4768
4828
|
highlight: "#ff4081",
|
|
4769
4829
|
bgColor: "#444444"
|
|
4770
4830
|
},
|
|
4771
|
-
lineWidth:
|
|
4772
|
-
|
|
4831
|
+
lineWidth: WORD_BY_WORD_WITH_BG_GEOMETRY.lineWidth,
|
|
4832
|
+
rectProps: WORD_BY_WORD_WITH_BG_GEOMETRY.rectProps,
|
|
4833
|
+
shadowOffset: [-1, 1],
|
|
4773
4834
|
shadowColor: "#000000",
|
|
4774
4835
|
shadowBlur: 5
|
|
4775
4836
|
},
|
|
4776
4837
|
[timeline.CAPTION_STYLE.OUTLINE_ONLY]: {
|
|
4777
4838
|
font: {
|
|
4778
|
-
size:
|
|
4839
|
+
size: OUTLINE_ONLY_FONT_SIZE,
|
|
4779
4840
|
weight: 600,
|
|
4780
4841
|
family: "Arial"
|
|
4781
4842
|
},
|
|
@@ -4784,7 +4845,8 @@ const CAPTION_PROPS = {
|
|
|
4784
4845
|
highlight: "#ff4081",
|
|
4785
4846
|
bgColor: "#000000"
|
|
4786
4847
|
},
|
|
4787
|
-
lineWidth:
|
|
4848
|
+
lineWidth: OUTLINE_ONLY_GEOMETRY.lineWidth,
|
|
4849
|
+
rectProps: OUTLINE_ONLY_GEOMETRY.rectProps,
|
|
4788
4850
|
stroke: "#000000",
|
|
4789
4851
|
fontWeight: 600,
|
|
4790
4852
|
shadowOffset: [0, 0],
|
|
@@ -4793,7 +4855,7 @@ const CAPTION_PROPS = {
|
|
|
4793
4855
|
},
|
|
4794
4856
|
[timeline.CAPTION_STYLE.SOFT_BOX]: {
|
|
4795
4857
|
font: {
|
|
4796
|
-
size:
|
|
4858
|
+
size: SOFT_BOX_FONT_SIZE,
|
|
4797
4859
|
weight: 600,
|
|
4798
4860
|
family: "Montserrat"
|
|
4799
4861
|
},
|
|
@@ -4802,7 +4864,8 @@ const CAPTION_PROPS = {
|
|
|
4802
4864
|
highlight: "#ff4081",
|
|
4803
4865
|
bgColor: "#333333"
|
|
4804
4866
|
},
|
|
4805
|
-
lineWidth:
|
|
4867
|
+
lineWidth: SOFT_BOX_GEOMETRY.lineWidth,
|
|
4868
|
+
rectProps: SOFT_BOX_GEOMETRY.rectProps,
|
|
4806
4869
|
stroke: "#000000",
|
|
4807
4870
|
fontWeight: 600,
|
|
4808
4871
|
shadowOffset: [-1, 1],
|
|
@@ -6321,6 +6384,116 @@ const CAPTION_COLOR = {
|
|
|
6321
6384
|
bgColor: "#8C52FF",
|
|
6322
6385
|
outlineColor: "#000000"
|
|
6323
6386
|
};
|
|
6387
|
+
const CAPTION_STYLE_COLOR_META = {
|
|
6388
|
+
// Word background highlight - white text on colored pill
|
|
6389
|
+
highlight_bg: {
|
|
6390
|
+
// Text color, and background pill color used in animation.
|
|
6391
|
+
usedColors: ["text", "bgColor"],
|
|
6392
|
+
labels: {
|
|
6393
|
+
text: "Text Color",
|
|
6394
|
+
bgColor: "Highlight Background"
|
|
6395
|
+
}
|
|
6396
|
+
},
|
|
6397
|
+
// Simple word-by-word – text only
|
|
6398
|
+
word_by_word: {
|
|
6399
|
+
// Visualizer uses text as fill + outlineColor for stroke, and highlight for active word.
|
|
6400
|
+
usedColors: ["text", "highlight", "outlineColor"],
|
|
6401
|
+
labels: {
|
|
6402
|
+
text: "Text Color",
|
|
6403
|
+
highlight: "Highlight Color",
|
|
6404
|
+
outlineColor: "Outline Color"
|
|
6405
|
+
}
|
|
6406
|
+
},
|
|
6407
|
+
// Word-by-word with a phrase bar background
|
|
6408
|
+
word_by_word_with_bg: {
|
|
6409
|
+
// Text color (fill), highlight for active word, outlineColor (stroke), bgColor used by phrase rect.
|
|
6410
|
+
usedColors: ["text", "highlight", "bgColor", "outlineColor"],
|
|
6411
|
+
labels: {
|
|
6412
|
+
text: "Text Color",
|
|
6413
|
+
bgColor: "Bar Background",
|
|
6414
|
+
highlight: "Highlight Color",
|
|
6415
|
+
outlineColor: "Outline Color"
|
|
6416
|
+
}
|
|
6417
|
+
},
|
|
6418
|
+
// Classic outlined text
|
|
6419
|
+
outline_only: {
|
|
6420
|
+
// Outline-only style: fill + outline color; highlight not used in animation.
|
|
6421
|
+
usedColors: ["text", "outlineColor"],
|
|
6422
|
+
labels: {
|
|
6423
|
+
text: "Fill Color",
|
|
6424
|
+
outlineColor: "Outline Color"
|
|
6425
|
+
}
|
|
6426
|
+
},
|
|
6427
|
+
// Soft rounded box behind text
|
|
6428
|
+
soft_box: {
|
|
6429
|
+
usedColors: ["text", "bgColor", "highlight", "outlineColor"],
|
|
6430
|
+
labels: {
|
|
6431
|
+
text: "Text Color",
|
|
6432
|
+
highlight: "Highlight Color",
|
|
6433
|
+
bgColor: "Box Background",
|
|
6434
|
+
outlineColor: "Outline Color"
|
|
6435
|
+
}
|
|
6436
|
+
},
|
|
6437
|
+
// Broadcast style lower-third bar
|
|
6438
|
+
lower_third: {
|
|
6439
|
+
// Title text, bar background, highlight color and outline color.
|
|
6440
|
+
usedColors: ["text", "bgColor", "outlineColor"],
|
|
6441
|
+
labels: {
|
|
6442
|
+
text: "Title Text Color",
|
|
6443
|
+
bgColor: "Bar Background",
|
|
6444
|
+
highlight: "Highlight Color",
|
|
6445
|
+
outlineColor: "Outline Color"
|
|
6446
|
+
}
|
|
6447
|
+
},
|
|
6448
|
+
// Typewriter – text only
|
|
6449
|
+
typewriter: {
|
|
6450
|
+
// Text color and outline color (stroke) used by visualizer; highlight not animated.
|
|
6451
|
+
usedColors: ["text", "outlineColor"],
|
|
6452
|
+
labels: {
|
|
6453
|
+
text: "Text Color",
|
|
6454
|
+
outlineColor: "Outline Color"
|
|
6455
|
+
}
|
|
6456
|
+
},
|
|
6457
|
+
// Karaoke – base text plus active word highlight
|
|
6458
|
+
karaoke: {
|
|
6459
|
+
// Base text color, active word highlight color, outline color.
|
|
6460
|
+
usedColors: ["text", "highlight", "outlineColor"],
|
|
6461
|
+
labels: {
|
|
6462
|
+
text: "Text Color",
|
|
6463
|
+
highlight: "Highlight Color",
|
|
6464
|
+
outlineColor: "Outline Color"
|
|
6465
|
+
}
|
|
6466
|
+
},
|
|
6467
|
+
// Karaoke-word – single active word, previous words dimmed
|
|
6468
|
+
"karaoke-word": {
|
|
6469
|
+
// Same color needs as karaoke.
|
|
6470
|
+
usedColors: ["text", "highlight", "outlineColor"],
|
|
6471
|
+
labels: {
|
|
6472
|
+
text: "Text Color",
|
|
6473
|
+
highlight: "Highlight Color",
|
|
6474
|
+
outlineColor: "Outline Color"
|
|
6475
|
+
}
|
|
6476
|
+
},
|
|
6477
|
+
// Pop / scale – text only
|
|
6478
|
+
pop_scale: {
|
|
6479
|
+
// Text color, highlight color for active word, and outline color; no background.
|
|
6480
|
+
usedColors: ["text", "highlight", "outlineColor"],
|
|
6481
|
+
labels: {
|
|
6482
|
+
text: "Text Color",
|
|
6483
|
+
highlight: "Highlight Color",
|
|
6484
|
+
outlineColor: "Outline Color"
|
|
6485
|
+
}
|
|
6486
|
+
}
|
|
6487
|
+
};
|
|
6488
|
+
const DEFAULT_COLOR_META = {
|
|
6489
|
+
usedColors: ["text", "bgColor", "outlineColor"],
|
|
6490
|
+
labels: {
|
|
6491
|
+
text: "Text Color",
|
|
6492
|
+
bgColor: "Background Color",
|
|
6493
|
+
outlineColor: "Outline Color"
|
|
6494
|
+
}
|
|
6495
|
+
};
|
|
6496
|
+
const CAPTION_FONTS = Object.values(VideoEditor.AVAILABLE_TEXT_FONTS);
|
|
6324
6497
|
function CaptionPropPanel({
|
|
6325
6498
|
selectedElement,
|
|
6326
6499
|
updateElement
|
|
@@ -6338,24 +6511,42 @@ function CaptionPropPanel({
|
|
|
6338
6511
|
bgColor: CAPTION_COLOR.bgColor,
|
|
6339
6512
|
outlineColor: CAPTION_COLOR.outlineColor
|
|
6340
6513
|
});
|
|
6514
|
+
const [useHighlight, setUseHighlight] = react.useState(true);
|
|
6515
|
+
const [useOutline, setUseOutline] = react.useState(true);
|
|
6341
6516
|
const track = selectedElement instanceof timeline.CaptionElement ? editor.getTrackById(selectedElement.getTrackId()) : null;
|
|
6342
6517
|
const trackProps = (track == null ? void 0 : track.getProps()) ?? {};
|
|
6343
6518
|
const applyToAll = (trackProps == null ? void 0 : trackProps.applyToAll) ?? false;
|
|
6344
6519
|
const handleUpdateCaption = (updates) => {
|
|
6345
6520
|
const captionElement = selectedElement;
|
|
6346
6521
|
if (!captionElement) return;
|
|
6522
|
+
const nextFontSize = updates.fontSize ?? fontSize;
|
|
6523
|
+
const geometry = timeline.computeCaptionGeometry(nextFontSize, updates.style ?? (capStyle == null ? void 0 : capStyle.value) ?? "");
|
|
6524
|
+
const highlightEnabled = updates.useHighlightOverride ?? useHighlight;
|
|
6525
|
+
const outlineEnabled = updates.useOutlineOverride ?? useOutline;
|
|
6526
|
+
const rawNextColors = updates.colors ?? colors;
|
|
6527
|
+
let effectiveColors = { ...rawNextColors };
|
|
6528
|
+
if (!highlightEnabled) {
|
|
6529
|
+
const { highlight, ...rest } = effectiveColors;
|
|
6530
|
+
effectiveColors = rest;
|
|
6531
|
+
}
|
|
6532
|
+
if (!outlineEnabled) {
|
|
6533
|
+
const { outlineColor, ...rest } = effectiveColors;
|
|
6534
|
+
effectiveColors = rest;
|
|
6535
|
+
}
|
|
6347
6536
|
if (applyToAll && track) {
|
|
6348
6537
|
const nextFont = {
|
|
6349
|
-
size:
|
|
6538
|
+
size: nextFontSize,
|
|
6350
6539
|
family: updates.fontFamily ?? fontFamily
|
|
6351
6540
|
};
|
|
6352
|
-
const nextColors =
|
|
6541
|
+
const nextColors = effectiveColors;
|
|
6353
6542
|
const nextCapStyle = updates.style ?? (capStyle == null ? void 0 : capStyle.value);
|
|
6354
6543
|
track.setProps({
|
|
6355
6544
|
...trackProps,
|
|
6356
6545
|
capStyle: nextCapStyle,
|
|
6357
6546
|
font: { ...(trackProps == null ? void 0 : trackProps.font) ?? {}, ...nextFont },
|
|
6358
|
-
colors: nextColors
|
|
6547
|
+
colors: nextColors,
|
|
6548
|
+
lineWidth: geometry.lineWidth,
|
|
6549
|
+
rectProps: geometry.rectProps
|
|
6359
6550
|
});
|
|
6360
6551
|
editor.refresh();
|
|
6361
6552
|
} else {
|
|
@@ -6364,10 +6555,11 @@ function CaptionPropPanel({
|
|
|
6364
6555
|
...elementProps,
|
|
6365
6556
|
capStyle: updates.style ?? (capStyle == null ? void 0 : capStyle.value),
|
|
6366
6557
|
font: {
|
|
6367
|
-
size:
|
|
6558
|
+
size: nextFontSize,
|
|
6368
6559
|
family: updates.fontFamily ?? fontFamily
|
|
6369
6560
|
},
|
|
6370
|
-
colors:
|
|
6561
|
+
colors: effectiveColors,
|
|
6562
|
+
lineWidth: geometry.lineWidth
|
|
6371
6563
|
});
|
|
6372
6564
|
updateElement == null ? void 0 : updateElement(captionElement);
|
|
6373
6565
|
}
|
|
@@ -6393,11 +6585,62 @@ function CaptionPropPanel({
|
|
|
6393
6585
|
bgColor: (c == null ? void 0 : c.bgColor) ?? CAPTION_COLOR.bgColor,
|
|
6394
6586
|
outlineColor: (c == null ? void 0 : c.outlineColor) ?? CAPTION_COLOR.outlineColor
|
|
6395
6587
|
});
|
|
6588
|
+
setUseHighlight((c == null ? void 0 : c.highlight) != null);
|
|
6589
|
+
setUseOutline((c == null ? void 0 : c.outlineColor) != null);
|
|
6396
6590
|
}
|
|
6397
6591
|
}, [selectedElement, applyToAll, changeLog]);
|
|
6398
6592
|
if (!(selectedElement instanceof timeline.CaptionElement)) {
|
|
6399
6593
|
return null;
|
|
6400
6594
|
}
|
|
6595
|
+
const currentStyleKey = capStyle == null ? void 0 : capStyle.value;
|
|
6596
|
+
const currentColorMeta = currentStyleKey && CAPTION_STYLE_COLOR_META[currentStyleKey] || DEFAULT_COLOR_META;
|
|
6597
|
+
const defaultColorLabels = {
|
|
6598
|
+
text: "Text Color",
|
|
6599
|
+
bgColor: "Background Color",
|
|
6600
|
+
highlight: "Highlight Color",
|
|
6601
|
+
outlineColor: "Outline Color"
|
|
6602
|
+
};
|
|
6603
|
+
const renderColorControl = (key) => {
|
|
6604
|
+
if (key === "highlight" && !useHighlight) {
|
|
6605
|
+
return null;
|
|
6606
|
+
}
|
|
6607
|
+
if (key === "outlineColor" && !useOutline) {
|
|
6608
|
+
return null;
|
|
6609
|
+
}
|
|
6610
|
+
const label = currentColorMeta.labels[key] ?? defaultColorLabels[key];
|
|
6611
|
+
const value = colors[key];
|
|
6612
|
+
const handleChange = (next) => {
|
|
6613
|
+
const nextColors = { ...colors, [key]: next };
|
|
6614
|
+
setColors(nextColors);
|
|
6615
|
+
handleUpdateCaption({ colors: nextColors });
|
|
6616
|
+
};
|
|
6617
|
+
if (value == null) {
|
|
6618
|
+
return null;
|
|
6619
|
+
}
|
|
6620
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "color-control", children: [
|
|
6621
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-small", children: label }),
|
|
6622
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "color-inputs", children: [
|
|
6623
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6624
|
+
"input",
|
|
6625
|
+
{
|
|
6626
|
+
type: "color",
|
|
6627
|
+
value,
|
|
6628
|
+
onChange: (e) => handleChange(e.target.value),
|
|
6629
|
+
className: "color-picker"
|
|
6630
|
+
}
|
|
6631
|
+
),
|
|
6632
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6633
|
+
"input",
|
|
6634
|
+
{
|
|
6635
|
+
type: "text",
|
|
6636
|
+
value,
|
|
6637
|
+
onChange: (e) => handleChange(e.target.value),
|
|
6638
|
+
className: "color-text"
|
|
6639
|
+
}
|
|
6640
|
+
)
|
|
6641
|
+
] })
|
|
6642
|
+
] }, key);
|
|
6643
|
+
};
|
|
6401
6644
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-container", children: [
|
|
6402
6645
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-section", children: [
|
|
6403
6646
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-dark", children: "Caption Style" }),
|
|
@@ -6444,7 +6687,7 @@ function CaptionPropPanel({
|
|
|
6444
6687
|
] }),
|
|
6445
6688
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-section", children: [
|
|
6446
6689
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-dark", children: "Font" }),
|
|
6447
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6690
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6448
6691
|
"select",
|
|
6449
6692
|
{
|
|
6450
6693
|
value: fontFamily,
|
|
@@ -6454,111 +6697,59 @@ function CaptionPropPanel({
|
|
|
6454
6697
|
handleUpdateCaption({ fontFamily: value });
|
|
6455
6698
|
},
|
|
6456
6699
|
className: "select-dark w-full",
|
|
6457
|
-
children:
|
|
6458
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "Bangers", children: "Bangers" }),
|
|
6459
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "Arial", children: "Arial" }),
|
|
6460
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "Helvetica", children: "Helvetica" }),
|
|
6461
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "Times New Roman", children: "Times New Roman" })
|
|
6462
|
-
]
|
|
6700
|
+
children: CAPTION_FONTS.map((font) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: font, children: font }, font))
|
|
6463
6701
|
}
|
|
6464
6702
|
)
|
|
6465
6703
|
] }),
|
|
6466
6704
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel-section", children: [
|
|
6467
6705
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-dark", children: "Colors" }),
|
|
6468
6706
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "color-section", children: [
|
|
6469
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6470
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
"
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
),
|
|
6516
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6517
|
-
"input",
|
|
6518
|
-
{
|
|
6519
|
-
type: "text",
|
|
6520
|
-
value: colors.bgColor,
|
|
6521
|
-
onChange: (e) => {
|
|
6522
|
-
const newColors = { ...colors, bgColor: e.target.value };
|
|
6523
|
-
setColors(newColors);
|
|
6524
|
-
handleUpdateCaption({ colors: newColors });
|
|
6525
|
-
},
|
|
6526
|
-
className: "color-text"
|
|
6527
|
-
}
|
|
6528
|
-
)
|
|
6529
|
-
] })
|
|
6530
|
-
] }),
|
|
6531
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "color-control", children: [
|
|
6532
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "label-small", children: "Outline Color" }),
|
|
6533
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "color-inputs", children: [
|
|
6534
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6535
|
-
"input",
|
|
6536
|
-
{
|
|
6537
|
-
type: "color",
|
|
6538
|
-
value: colors.outlineColor,
|
|
6539
|
-
onChange: (e) => {
|
|
6540
|
-
const newColors = { ...colors, outlineColor: e.target.value };
|
|
6541
|
-
setColors(newColors);
|
|
6542
|
-
handleUpdateCaption({ colors: newColors });
|
|
6543
|
-
},
|
|
6544
|
-
className: "color-picker"
|
|
6545
|
-
}
|
|
6546
|
-
),
|
|
6547
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6548
|
-
"input",
|
|
6549
|
-
{
|
|
6550
|
-
type: "text",
|
|
6551
|
-
value: colors.outlineColor,
|
|
6552
|
-
onChange: (e) => {
|
|
6553
|
-
const newColors = { ...colors, outlineColor: e.target.value };
|
|
6554
|
-
setColors(newColors);
|
|
6555
|
-
handleUpdateCaption({ colors: newColors });
|
|
6556
|
-
},
|
|
6557
|
-
className: "color-text"
|
|
6558
|
-
}
|
|
6559
|
-
)
|
|
6560
|
-
] })
|
|
6561
|
-
] })
|
|
6707
|
+
currentColorMeta.usedColors.includes("highlight") && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "checkbox-control", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "checkbox-label", children: [
|
|
6708
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6709
|
+
"input",
|
|
6710
|
+
{
|
|
6711
|
+
type: "checkbox",
|
|
6712
|
+
checked: useHighlight,
|
|
6713
|
+
onChange: (e) => {
|
|
6714
|
+
const enabled = e.target.checked;
|
|
6715
|
+
setUseHighlight(enabled);
|
|
6716
|
+
const nextColors = enabled ? { ...colors, highlight: colors.highlight || CAPTION_COLOR.highlight } : { ...colors };
|
|
6717
|
+
setColors(nextColors);
|
|
6718
|
+
handleUpdateCaption({
|
|
6719
|
+
colors: nextColors,
|
|
6720
|
+
useHighlightOverride: enabled
|
|
6721
|
+
});
|
|
6722
|
+
},
|
|
6723
|
+
className: "checkbox-purple"
|
|
6724
|
+
}
|
|
6725
|
+
),
|
|
6726
|
+
"Use Highlight Color"
|
|
6727
|
+
] }) }),
|
|
6728
|
+
currentColorMeta.usedColors.includes("outlineColor") && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "checkbox-control", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "checkbox-label", children: [
|
|
6729
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6730
|
+
"input",
|
|
6731
|
+
{
|
|
6732
|
+
type: "checkbox",
|
|
6733
|
+
checked: useOutline,
|
|
6734
|
+
onChange: (e) => {
|
|
6735
|
+
const enabled = e.target.checked;
|
|
6736
|
+
setUseOutline(enabled);
|
|
6737
|
+
const nextColors = enabled ? {
|
|
6738
|
+
...colors,
|
|
6739
|
+
outlineColor: colors.outlineColor || CAPTION_COLOR.outlineColor
|
|
6740
|
+
} : { ...colors };
|
|
6741
|
+
setColors(nextColors);
|
|
6742
|
+
handleUpdateCaption({
|
|
6743
|
+
colors: nextColors,
|
|
6744
|
+
useOutlineOverride: enabled
|
|
6745
|
+
});
|
|
6746
|
+
},
|
|
6747
|
+
className: "checkbox-purple"
|
|
6748
|
+
}
|
|
6749
|
+
),
|
|
6750
|
+
"Use Outline Color"
|
|
6751
|
+
] }) }),
|
|
6752
|
+
currentColorMeta.usedColors.map((key) => renderColorControl(key))
|
|
6562
6753
|
] })
|
|
6563
6754
|
] })
|
|
6564
6755
|
] });
|