@twick/video-editor 0.15.26 → 0.15.28
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/components/timeline/timeline-view.d.ts +6 -1
- package/dist/components/track/track-base.d.ts +5 -1
- package/dist/components/track/track-element-context-menu.d.ts +16 -0
- package/dist/components/track/track-element.d.ts +6 -0
- package/dist/helpers/types.d.ts +1 -0
- package/dist/index.js +680 -125
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +681 -126
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
7
7
|
const livePlayer = require("@twick/live-player");
|
|
8
8
|
const timeline = require("@twick/timeline");
|
|
9
9
|
const React = require("react");
|
|
10
|
+
const reactDom = require("react-dom");
|
|
10
11
|
function t(t2, e3, s2) {
|
|
11
12
|
return (e3 = function(t3) {
|
|
12
13
|
var e4 = function(t4, e5) {
|
|
@@ -5945,6 +5946,9 @@ function ea() {
|
|
|
5945
5946
|
function sa() {
|
|
5946
5947
|
return !ta && (!(arguments.length > 0 && void 0 !== arguments[0]) || arguments[0]) && (ta = ea()), ta;
|
|
5947
5948
|
}
|
|
5949
|
+
function ia(t2) {
|
|
5950
|
+
ta = t2;
|
|
5951
|
+
}
|
|
5948
5952
|
const ra = ["filters", "resizeFilter", "src", "crossOrigin", "type"], na = ["cropX", "cropY"];
|
|
5949
5953
|
class oa extends Li {
|
|
5950
5954
|
static getDefaults() {
|
|
@@ -6472,13 +6476,7 @@ function Za(e3, s2) {
|
|
|
6472
6476
|
return tt.setClass(r2, e3), r2;
|
|
6473
6477
|
}
|
|
6474
6478
|
t(Qa, "type", "ColorMatrix"), t(Qa, "defaults", Ja), t(Qa, "uniformLocations", ["uColorMatrix", "uConstants"]), tt.setClass(Qa);
|
|
6475
|
-
Za("Brownie", [0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449, 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0]);
|
|
6476
|
-
Za("Vintage", [0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0, 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0]);
|
|
6477
|
-
Za("Kodachrome", [1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0, 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0]);
|
|
6478
|
-
Za("Technicolor", [1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0, -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0]);
|
|
6479
|
-
Za("Polaroid", [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0]);
|
|
6480
|
-
Za("Sepia", [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0]);
|
|
6481
|
-
Za("BlackWhite", [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0]);
|
|
6479
|
+
const $a = Za("Brownie", [0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449, 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0]), th = Za("Vintage", [0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0, 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0]), eh = Za("Kodachrome", [1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0, 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0]), sh = Za("Technicolor", [1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0, -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0]), ih = Za("Polaroid", [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0]), rh = Za("Sepia", [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0]), nh = Za("BlackWhite", [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0]);
|
|
6482
6480
|
class oh extends Va {
|
|
6483
6481
|
constructor() {
|
|
6484
6482
|
let t2 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
|
|
@@ -6841,6 +6839,7 @@ class bh extends Va {
|
|
|
6841
6839
|
}
|
|
6842
6840
|
}
|
|
6843
6841
|
t(bh, "type", "Vibrance"), t(bh, "defaults", { vibrance: 0 }), t(bh, "uniformLocations", ["uVibrance"]), tt.setClass(bh);
|
|
6842
|
+
var Sh = Object.freeze({ __proto__: null, BaseFilter: Va, BlackWhite: nh, BlendColor: Ga, BlendImage: Ua, Blur: qa, Brightness: Ka, Brownie: $a, ColorMatrix: Qa, Composed: oh, Contrast: ah, Convolute: ch, Gamma: uh, Grayscale: gh, HueRotation: ph, Invert: mh, Kodachrome: eh, Noise: vh$1, Pixelate: yh, Polaroid: ih, RemoveColor: _h, Resize: xh, Saturation: Ch, Sepia: rh, Technicolor: sh, Vibrance: bh, Vintage: th });
|
|
6844
6843
|
var __defProp2 = Object.defineProperty;
|
|
6845
6844
|
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6846
6845
|
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, key + "", value);
|
|
@@ -6901,6 +6900,8 @@ const ELEMENT_TYPES = {
|
|
|
6901
6900
|
RECT: "rect",
|
|
6902
6901
|
/** Circle element type */
|
|
6903
6902
|
CIRCLE: "circle",
|
|
6903
|
+
/** Emoji sticker element type */
|
|
6904
|
+
EMOJI: "emoji",
|
|
6904
6905
|
/** Arrow annotation element type */
|
|
6905
6906
|
ARROW: "arrow",
|
|
6906
6907
|
/** Line annotation / shape element type */
|
|
@@ -7149,6 +7150,24 @@ const rotateControl = new ai({
|
|
|
7149
7150
|
/** Whether to show connection line */
|
|
7150
7151
|
withConnection: true
|
|
7151
7152
|
});
|
|
7153
|
+
const COLOR_FILTERS = {
|
|
7154
|
+
SATURATED: "saturated",
|
|
7155
|
+
BRIGHT: "bright",
|
|
7156
|
+
VIBRANT: "vibrant",
|
|
7157
|
+
RETRO: "retro",
|
|
7158
|
+
BLACK_WHITE: "blackWhite",
|
|
7159
|
+
SEPIA: "sepia",
|
|
7160
|
+
COOL: "cool",
|
|
7161
|
+
WARM: "warm",
|
|
7162
|
+
CINEMATIC: "cinematic",
|
|
7163
|
+
SOFT_GLOW: "softGlow",
|
|
7164
|
+
MOODY: "moody",
|
|
7165
|
+
DREAMY: "dreamy",
|
|
7166
|
+
INVERTED: "inverted",
|
|
7167
|
+
VINTAGE: "vintage",
|
|
7168
|
+
DRAMATIC: "dramatic",
|
|
7169
|
+
FADED: "faded"
|
|
7170
|
+
};
|
|
7152
7171
|
class LRUCache {
|
|
7153
7172
|
constructor(maxSize = 100) {
|
|
7154
7173
|
if (maxSize <= 0) {
|
|
@@ -7532,6 +7551,275 @@ const getObjectFitSize = (objectFit, elementSize, containerSize) => {
|
|
|
7532
7551
|
};
|
|
7533
7552
|
}
|
|
7534
7553
|
};
|
|
7554
|
+
const {
|
|
7555
|
+
Blur,
|
|
7556
|
+
Brightness,
|
|
7557
|
+
ColorMatrix,
|
|
7558
|
+
Contrast,
|
|
7559
|
+
Grayscale,
|
|
7560
|
+
HueRotation,
|
|
7561
|
+
Invert,
|
|
7562
|
+
Saturation,
|
|
7563
|
+
Sepia
|
|
7564
|
+
} = Sh;
|
|
7565
|
+
let canvas2dFilterBackendInstalled = false;
|
|
7566
|
+
function ensureCanvas2dImageFilterBackend() {
|
|
7567
|
+
if (canvas2dFilterBackendInstalled) return;
|
|
7568
|
+
canvas2dFilterBackendInstalled = true;
|
|
7569
|
+
ia(new Zo());
|
|
7570
|
+
}
|
|
7571
|
+
function getSourceBitmapSize(img) {
|
|
7572
|
+
const el = img.getElement();
|
|
7573
|
+
if (!el) return null;
|
|
7574
|
+
const w2 = "naturalWidth" in el && el.naturalWidth > 0 ? el.naturalWidth : el.width;
|
|
7575
|
+
const h2 = "naturalHeight" in el && el.naturalHeight > 0 ? el.naturalHeight : el.height;
|
|
7576
|
+
if (!w2 || !h2) return null;
|
|
7577
|
+
return { w: w2, h: h2 };
|
|
7578
|
+
}
|
|
7579
|
+
function applyFiltersSafe(img) {
|
|
7580
|
+
ensureCanvas2dImageFilterBackend();
|
|
7581
|
+
img.applyFilters();
|
|
7582
|
+
}
|
|
7583
|
+
const bright = (m2) => Math.min(1, Math.max(-1, (m2 - 1) * 0.48));
|
|
7584
|
+
const contr = (m2) => Math.min(1, Math.max(-1, (m2 - 1) * 0.55));
|
|
7585
|
+
const sat = (m2) => Math.min(1, Math.max(-1, (m2 - 1) * 0.72));
|
|
7586
|
+
const IDENTITY = [
|
|
7587
|
+
1,
|
|
7588
|
+
0,
|
|
7589
|
+
0,
|
|
7590
|
+
0,
|
|
7591
|
+
0,
|
|
7592
|
+
0,
|
|
7593
|
+
1,
|
|
7594
|
+
0,
|
|
7595
|
+
0,
|
|
7596
|
+
0,
|
|
7597
|
+
0,
|
|
7598
|
+
0,
|
|
7599
|
+
1,
|
|
7600
|
+
0,
|
|
7601
|
+
0,
|
|
7602
|
+
0,
|
|
7603
|
+
0,
|
|
7604
|
+
0,
|
|
7605
|
+
1,
|
|
7606
|
+
0
|
|
7607
|
+
];
|
|
7608
|
+
const SEPIA_MATRIX = [
|
|
7609
|
+
0.393,
|
|
7610
|
+
0.769,
|
|
7611
|
+
0.189,
|
|
7612
|
+
0,
|
|
7613
|
+
0,
|
|
7614
|
+
0.349,
|
|
7615
|
+
0.686,
|
|
7616
|
+
0.168,
|
|
7617
|
+
0,
|
|
7618
|
+
0,
|
|
7619
|
+
0.272,
|
|
7620
|
+
0.534,
|
|
7621
|
+
0.131,
|
|
7622
|
+
0,
|
|
7623
|
+
0,
|
|
7624
|
+
0,
|
|
7625
|
+
0,
|
|
7626
|
+
0,
|
|
7627
|
+
1,
|
|
7628
|
+
0
|
|
7629
|
+
];
|
|
7630
|
+
function sepiaMix(strength) {
|
|
7631
|
+
const t2 = Math.min(1, Math.max(0, strength));
|
|
7632
|
+
const m2 = IDENTITY.map((v2, i2) => v2 + (SEPIA_MATRIX[i2] - v2) * t2);
|
|
7633
|
+
return new ColorMatrix({ matrix: m2, colorsOnly: true });
|
|
7634
|
+
}
|
|
7635
|
+
const twickBlurToFabric = (v2) => Math.min(0.22, Math.max(0, v2 * 0.045));
|
|
7636
|
+
function buildFilters(filterType) {
|
|
7637
|
+
switch (filterType) {
|
|
7638
|
+
case COLOR_FILTERS.SATURATED:
|
|
7639
|
+
return {
|
|
7640
|
+
filters: [
|
|
7641
|
+
new Saturation({ saturation: sat(1.4) }),
|
|
7642
|
+
new Contrast({ contrast: contr(1.1) })
|
|
7643
|
+
],
|
|
7644
|
+
opacityFactor: 1
|
|
7645
|
+
};
|
|
7646
|
+
case COLOR_FILTERS.BRIGHT:
|
|
7647
|
+
return {
|
|
7648
|
+
filters: [
|
|
7649
|
+
new Brightness({ brightness: bright(1.3) }),
|
|
7650
|
+
new Contrast({ contrast: contr(1.05) })
|
|
7651
|
+
],
|
|
7652
|
+
opacityFactor: 1
|
|
7653
|
+
};
|
|
7654
|
+
case COLOR_FILTERS.VIBRANT:
|
|
7655
|
+
return {
|
|
7656
|
+
filters: [
|
|
7657
|
+
new Saturation({ saturation: sat(1.6) }),
|
|
7658
|
+
new Brightness({ brightness: bright(1.15) }),
|
|
7659
|
+
new Contrast({ contrast: contr(1.1) })
|
|
7660
|
+
],
|
|
7661
|
+
opacityFactor: 1
|
|
7662
|
+
};
|
|
7663
|
+
case COLOR_FILTERS.RETRO:
|
|
7664
|
+
return {
|
|
7665
|
+
filters: [
|
|
7666
|
+
sepiaMix(0.8),
|
|
7667
|
+
new Contrast({ contrast: contr(1.3) }),
|
|
7668
|
+
new Brightness({ brightness: bright(0.85) }),
|
|
7669
|
+
new Saturation({ saturation: sat(0.8) })
|
|
7670
|
+
],
|
|
7671
|
+
opacityFactor: 1
|
|
7672
|
+
};
|
|
7673
|
+
case COLOR_FILTERS.BLACK_WHITE:
|
|
7674
|
+
return {
|
|
7675
|
+
filters: [
|
|
7676
|
+
new Grayscale(),
|
|
7677
|
+
new Contrast({ contrast: contr(1.25) }),
|
|
7678
|
+
new Brightness({ brightness: bright(1.05) })
|
|
7679
|
+
],
|
|
7680
|
+
opacityFactor: 1
|
|
7681
|
+
};
|
|
7682
|
+
case COLOR_FILTERS.SEPIA:
|
|
7683
|
+
return {
|
|
7684
|
+
filters: [
|
|
7685
|
+
new Sepia(),
|
|
7686
|
+
new Contrast({ contrast: contr(1.08) })
|
|
7687
|
+
],
|
|
7688
|
+
opacityFactor: 1
|
|
7689
|
+
};
|
|
7690
|
+
case COLOR_FILTERS.COOL:
|
|
7691
|
+
return {
|
|
7692
|
+
filters: [
|
|
7693
|
+
new HueRotation({ rotation: 15 / 180 }),
|
|
7694
|
+
new Brightness({ brightness: bright(1.1) }),
|
|
7695
|
+
new Saturation({ saturation: sat(1.3) }),
|
|
7696
|
+
new Contrast({ contrast: contr(1.05) })
|
|
7697
|
+
],
|
|
7698
|
+
opacityFactor: 1
|
|
7699
|
+
};
|
|
7700
|
+
case COLOR_FILTERS.WARM:
|
|
7701
|
+
return {
|
|
7702
|
+
filters: [
|
|
7703
|
+
new HueRotation({ rotation: -15 / 180 }),
|
|
7704
|
+
new Brightness({ brightness: bright(1.15) }),
|
|
7705
|
+
new Saturation({ saturation: sat(1.3) }),
|
|
7706
|
+
new Contrast({ contrast: contr(1.05) })
|
|
7707
|
+
],
|
|
7708
|
+
opacityFactor: 1
|
|
7709
|
+
};
|
|
7710
|
+
case COLOR_FILTERS.CINEMATIC:
|
|
7711
|
+
return {
|
|
7712
|
+
filters: [
|
|
7713
|
+
new Contrast({ contrast: contr(1.4) }),
|
|
7714
|
+
new Brightness({ brightness: bright(0.95) }),
|
|
7715
|
+
new Saturation({ saturation: sat(0.85) }),
|
|
7716
|
+
sepiaMix(0.2)
|
|
7717
|
+
],
|
|
7718
|
+
opacityFactor: 1
|
|
7719
|
+
};
|
|
7720
|
+
case COLOR_FILTERS.SOFT_GLOW:
|
|
7721
|
+
return {
|
|
7722
|
+
filters: [
|
|
7723
|
+
new Brightness({ brightness: bright(1.2) }),
|
|
7724
|
+
new Contrast({ contrast: contr(0.95) }),
|
|
7725
|
+
new Blur({ blur: twickBlurToFabric(1.2) }),
|
|
7726
|
+
new Saturation({ saturation: sat(1.1) })
|
|
7727
|
+
],
|
|
7728
|
+
opacityFactor: 1
|
|
7729
|
+
};
|
|
7730
|
+
case COLOR_FILTERS.MOODY:
|
|
7731
|
+
return {
|
|
7732
|
+
filters: [
|
|
7733
|
+
new Brightness({ brightness: bright(1.05) }),
|
|
7734
|
+
new Contrast({ contrast: contr(1.4) }),
|
|
7735
|
+
new Saturation({ saturation: sat(0.65) }),
|
|
7736
|
+
sepiaMix(0.2)
|
|
7737
|
+
],
|
|
7738
|
+
opacityFactor: 1
|
|
7739
|
+
};
|
|
7740
|
+
case COLOR_FILTERS.DREAMY:
|
|
7741
|
+
return {
|
|
7742
|
+
filters: [
|
|
7743
|
+
new Brightness({ brightness: bright(1.3) }),
|
|
7744
|
+
new Blur({ blur: twickBlurToFabric(2) }),
|
|
7745
|
+
new Saturation({ saturation: sat(1.4) }),
|
|
7746
|
+
new Contrast({ contrast: contr(0.95) })
|
|
7747
|
+
],
|
|
7748
|
+
opacityFactor: 1
|
|
7749
|
+
};
|
|
7750
|
+
case COLOR_FILTERS.INVERTED:
|
|
7751
|
+
return {
|
|
7752
|
+
filters: [
|
|
7753
|
+
new Invert({ invert: true, alpha: false }),
|
|
7754
|
+
new HueRotation({ rotation: 1 })
|
|
7755
|
+
],
|
|
7756
|
+
opacityFactor: 1
|
|
7757
|
+
};
|
|
7758
|
+
case COLOR_FILTERS.VINTAGE:
|
|
7759
|
+
return {
|
|
7760
|
+
filters: [
|
|
7761
|
+
sepiaMix(0.4),
|
|
7762
|
+
new Saturation({ saturation: sat(1.4) }),
|
|
7763
|
+
new Contrast({ contrast: contr(1.2) }),
|
|
7764
|
+
new Brightness({ brightness: bright(1.1) })
|
|
7765
|
+
],
|
|
7766
|
+
opacityFactor: 1
|
|
7767
|
+
};
|
|
7768
|
+
case COLOR_FILTERS.DRAMATIC:
|
|
7769
|
+
return {
|
|
7770
|
+
filters: [
|
|
7771
|
+
new Contrast({ contrast: contr(1.5) }),
|
|
7772
|
+
new Brightness({ brightness: bright(0.9) }),
|
|
7773
|
+
new Saturation({ saturation: sat(1.2) })
|
|
7774
|
+
],
|
|
7775
|
+
opacityFactor: 1
|
|
7776
|
+
};
|
|
7777
|
+
case COLOR_FILTERS.FADED:
|
|
7778
|
+
return {
|
|
7779
|
+
filters: [
|
|
7780
|
+
new Brightness({ brightness: bright(1.2) }),
|
|
7781
|
+
new Saturation({ saturation: sat(0.8) }),
|
|
7782
|
+
new Contrast({ contrast: contr(0.9) })
|
|
7783
|
+
],
|
|
7784
|
+
opacityFactor: 0.9
|
|
7785
|
+
};
|
|
7786
|
+
default:
|
|
7787
|
+
return { filters: [], opacityFactor: 1 };
|
|
7788
|
+
}
|
|
7789
|
+
}
|
|
7790
|
+
function applyFabricMediaColorFilters(img, mediaFilter, elementOpacity) {
|
|
7791
|
+
const key = (mediaFilter == null ? void 0 : mediaFilter.trim()) || "none";
|
|
7792
|
+
if (key === "none") {
|
|
7793
|
+
img.filters = [];
|
|
7794
|
+
img.set("opacity", elementOpacity);
|
|
7795
|
+
applyFiltersSafe(img);
|
|
7796
|
+
return;
|
|
7797
|
+
}
|
|
7798
|
+
const { filters: filterList, opacityFactor } = buildFilters(key);
|
|
7799
|
+
if (filterList.length === 0) {
|
|
7800
|
+
img.filters = [];
|
|
7801
|
+
img.set("opacity", elementOpacity);
|
|
7802
|
+
applyFiltersSafe(img);
|
|
7803
|
+
return;
|
|
7804
|
+
}
|
|
7805
|
+
if (!getSourceBitmapSize(img)) {
|
|
7806
|
+
img.filters = [];
|
|
7807
|
+
img.set("opacity", elementOpacity);
|
|
7808
|
+
return;
|
|
7809
|
+
}
|
|
7810
|
+
img.filters = filterList;
|
|
7811
|
+
img.set("opacity", elementOpacity * opacityFactor);
|
|
7812
|
+
try {
|
|
7813
|
+
applyFiltersSafe(img);
|
|
7814
|
+
} catch {
|
|
7815
|
+
img.filters = [];
|
|
7816
|
+
img.set("opacity", elementOpacity);
|
|
7817
|
+
try {
|
|
7818
|
+
applyFiltersSafe(img);
|
|
7819
|
+
} catch {
|
|
7820
|
+
}
|
|
7821
|
+
}
|
|
7822
|
+
}
|
|
7535
7823
|
const MARGIN = 10;
|
|
7536
7824
|
const addTextElement = ({
|
|
7537
7825
|
element,
|
|
@@ -7622,7 +7910,7 @@ const setImageProps = ({
|
|
|
7622
7910
|
canvasMetadata,
|
|
7623
7911
|
lockAspectRatio = true
|
|
7624
7912
|
}) => {
|
|
7625
|
-
var _a, _b, _c, _d, _e2;
|
|
7913
|
+
var _a, _b, _c, _d, _e2, _f;
|
|
7626
7914
|
const width = (((_a = element.props) == null ? void 0 : _a.width) || 0) * canvasMetadata.scaleX || canvasMetadata.width;
|
|
7627
7915
|
const height = (((_b = element.props) == null ? void 0 : _b.height) || 0) * canvasMetadata.scaleY || canvasMetadata.height;
|
|
7628
7916
|
const { x: x2, y: y2 } = convertToCanvasPosition(
|
|
@@ -7636,11 +7924,15 @@ const setImageProps = ({
|
|
|
7636
7924
|
img.set("height", height);
|
|
7637
7925
|
img.set("left", x2);
|
|
7638
7926
|
img.set("top", y2);
|
|
7639
|
-
img.set("opacity", ((_e2 = element.props) == null ? void 0 : _e2.opacity) ?? 1);
|
|
7640
7927
|
img.set("selectable", true);
|
|
7641
7928
|
img.set("hasControls", true);
|
|
7642
7929
|
img.set("touchAction", "all");
|
|
7643
7930
|
img.set("lockUniScaling", lockAspectRatio);
|
|
7931
|
+
applyFabricMediaColorFilters(
|
|
7932
|
+
img,
|
|
7933
|
+
(_e2 = element.props) == null ? void 0 : _e2.mediaFilter,
|
|
7934
|
+
((_f = element.props) == null ? void 0 : _f.opacity) ?? 1
|
|
7935
|
+
);
|
|
7644
7936
|
};
|
|
7645
7937
|
const addCaptionElement = ({
|
|
7646
7938
|
element,
|
|
@@ -7650,48 +7942,52 @@ const addCaptionElement = ({
|
|
|
7650
7942
|
canvasMetadata,
|
|
7651
7943
|
lockAspectRatio = false
|
|
7652
7944
|
}) => {
|
|
7653
|
-
var _a, _b, _c, _d, _e2, _f, _g, _h2, _i2, _j, _k, _l, _m, _n2, _o2, _p, _q, _r2, _s2, _t2, _u, _v, _w, _x, _y
|
|
7654
|
-
const
|
|
7655
|
-
const
|
|
7945
|
+
var _a, _b, _c, _d, _e2, _f, _g, _h2, _i2, _j, _k, _l, _m, _n2, _o2, _p, _q, _r2, _s2, _t2, _u, _v, _w, _x, _y;
|
|
7946
|
+
const useTrackDefaults = ((_a = element.props) == null ? void 0 : _a.useTrackDefaults) ?? true;
|
|
7947
|
+
const trackColors = captionProps == null ? void 0 : captionProps.colors;
|
|
7948
|
+
const elementColors = (_b = element.props) == null ? void 0 : _b.colors;
|
|
7949
|
+
const resolvedColors = useTrackDefaults ? trackColors : { ...trackColors ?? {}, ...elementColors ?? {} };
|
|
7950
|
+
const captionTextColor = (resolvedColors == null ? void 0 : resolvedColors.text) ?? ((_c = captionProps == null ? void 0 : captionProps.color) == null ? void 0 : _c.text);
|
|
7656
7951
|
const { x: x2, y: y2 } = convertToCanvasPosition(
|
|
7657
|
-
(
|
|
7658
|
-
(
|
|
7952
|
+
(useTrackDefaults ? captionProps == null ? void 0 : captionProps.x : (_d = element.props) == null ? void 0 : _d.x) ?? (captionProps == null ? void 0 : captionProps.x) ?? 0,
|
|
7953
|
+
(useTrackDefaults ? captionProps == null ? void 0 : captionProps.y : (_e2 = element.props) == null ? void 0 : _e2.y) ?? (captionProps == null ? void 0 : captionProps.y) ?? 0,
|
|
7659
7954
|
canvasMetadata
|
|
7660
7955
|
);
|
|
7661
|
-
let width = ((
|
|
7662
|
-
if ((
|
|
7956
|
+
let width = ((_f = element.props) == null ? void 0 : _f.width) ? element.props.width * canvasMetadata.scaleX : canvasMetadata.width - 2 * MARGIN;
|
|
7957
|
+
if ((_g = element.props) == null ? void 0 : _g.maxWidth) {
|
|
7663
7958
|
width = Math.min(width, element.props.maxWidth * canvasMetadata.scaleX);
|
|
7664
7959
|
}
|
|
7665
|
-
const
|
|
7666
|
-
const resolvedFill = (applyToAll ? captionTextColor : ((_h2 = element.props) == null ? void 0 : _h2.fill) ?? (elementColors == null ? void 0 : elementColors.text) ?? captionTextColor) ?? DEFAULT_CAPTION_PROPS.fill;
|
|
7667
|
-
const trackColors = captionProps == null ? void 0 : captionProps.colors;
|
|
7960
|
+
const resolvedFill = (useTrackDefaults ? void 0 : (_h2 = element.props) == null ? void 0 : _h2.fill) ?? captionTextColor ?? DEFAULT_CAPTION_PROPS.fill;
|
|
7668
7961
|
const trackStroke = trackColors == null ? void 0 : trackColors.outlineColor;
|
|
7669
7962
|
const elementStroke = (elementColors == null ? void 0 : elementColors.outlineColor) ?? ((_i2 = element.props) == null ? void 0 : _i2.stroke);
|
|
7670
|
-
const resolvedStroke = (
|
|
7671
|
-
const
|
|
7963
|
+
const resolvedStroke = (useTrackDefaults ? trackStroke : elementStroke ?? trackStroke) ?? void 0;
|
|
7964
|
+
const trackFont = (captionProps == null ? void 0 : captionProps.font) ?? {};
|
|
7965
|
+
const elementFont = ((_j = element.props) == null ? void 0 : _j.font) ?? {};
|
|
7966
|
+
const resolvedFont = useTrackDefaults ? trackFont : { ...trackFont, ...elementFont };
|
|
7967
|
+
const caption = new Uo(((_k = element.props) == null ? void 0 : _k.text) || element.t || "", {
|
|
7672
7968
|
left: x2,
|
|
7673
7969
|
top: y2,
|
|
7674
7970
|
originX: "center",
|
|
7675
7971
|
originY: "center",
|
|
7676
|
-
angle: ((
|
|
7972
|
+
angle: ((_l = element.props) == null ? void 0 : _l.rotation) || 0,
|
|
7677
7973
|
fontSize: Math.round(
|
|
7678
|
-
((
|
|
7974
|
+
((resolvedFont == null ? void 0 : resolvedFont.size) ?? DEFAULT_CAPTION_PROPS.size) * canvasMetadata.scaleX
|
|
7679
7975
|
),
|
|
7680
|
-
fontFamily: (
|
|
7976
|
+
fontFamily: (resolvedFont == null ? void 0 : resolvedFont.family) ?? DEFAULT_CAPTION_PROPS.family,
|
|
7681
7977
|
fill: resolvedFill,
|
|
7682
|
-
fontWeight: (
|
|
7978
|
+
fontWeight: (resolvedFont == null ? void 0 : resolvedFont.weight) ?? DEFAULT_CAPTION_PROPS.fontWeight,
|
|
7683
7979
|
...resolvedStroke ? { stroke: resolvedStroke } : {},
|
|
7684
|
-
opacity: (
|
|
7980
|
+
opacity: (useTrackDefaults ? void 0 : (_m = element.props) == null ? void 0 : _m.opacity) ?? (captionProps == null ? void 0 : captionProps.opacity) ?? 1,
|
|
7685
7981
|
width,
|
|
7686
7982
|
splitByGrapheme: false,
|
|
7687
|
-
textAlign: ((
|
|
7983
|
+
textAlign: ((_n2 = element.props) == null ? void 0 : _n2.textAlign) ?? "center",
|
|
7688
7984
|
shadow: new Ds({
|
|
7689
|
-
offsetX: (
|
|
7690
|
-
offsetY: (
|
|
7691
|
-
blur: (
|
|
7692
|
-
color: (
|
|
7985
|
+
offsetX: (useTrackDefaults ? void 0 : (_p = (_o2 = element.props) == null ? void 0 : _o2.shadowOffset) == null ? void 0 : _p[0]) ?? ((_q = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _q[0]) ?? ((_r2 = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _r2[0]),
|
|
7986
|
+
offsetY: (useTrackDefaults ? void 0 : (_t2 = (_s2 = element.props) == null ? void 0 : _s2.shadowOffset) == null ? void 0 : _t2[1]) ?? ((_u = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _u[1]) ?? ((_v = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _v[1]),
|
|
7987
|
+
blur: (useTrackDefaults ? void 0 : (_w = element.props) == null ? void 0 : _w.shadowBlur) ?? (captionProps == null ? void 0 : captionProps.shadowBlur) ?? DEFAULT_CAPTION_PROPS.shadowBlur,
|
|
7988
|
+
color: (useTrackDefaults ? void 0 : (_x = element.props) == null ? void 0 : _x.shadowColor) ?? (captionProps == null ? void 0 : captionProps.shadowColor) ?? DEFAULT_CAPTION_PROPS.shadowColor
|
|
7693
7989
|
}),
|
|
7694
|
-
strokeWidth: ((
|
|
7990
|
+
strokeWidth: ((useTrackDefaults ? void 0 : (_y = element.props) == null ? void 0 : _y.lineWidth) ?? (captionProps == null ? void 0 : captionProps.lineWidth) ?? DEFAULT_CAPTION_PROPS.lineWidth) * 0.025
|
|
7695
7991
|
});
|
|
7696
7992
|
caption.set("id", element.id);
|
|
7697
7993
|
caption.set("zIndex", index);
|
|
@@ -7746,8 +8042,13 @@ const addImageElement = async ({
|
|
|
7746
8042
|
currentFrameEffect,
|
|
7747
8043
|
lockAspectRatio = true
|
|
7748
8044
|
}) => {
|
|
8045
|
+
var _a, _b;
|
|
7749
8046
|
try {
|
|
7750
|
-
const
|
|
8047
|
+
const rawSrc = imageUrl || element.props.src || "";
|
|
8048
|
+
const mediaFilter = (_b = (_a = element.props) == null ? void 0 : _a.mediaFilter) == null ? void 0 : _b.trim();
|
|
8049
|
+
const useFilter = !!mediaFilter && mediaFilter !== "none";
|
|
8050
|
+
const fromUrlOpts = useFilter && /^https?:\/\//i.test(rawSrc) ? { crossOrigin: "anonymous" } : {};
|
|
8051
|
+
const img = await oa.fromURL(rawSrc, fromUrlOpts);
|
|
7751
8052
|
img.set({
|
|
7752
8053
|
originX: "center",
|
|
7753
8054
|
originY: "center",
|
|
@@ -7784,7 +8085,7 @@ const addMediaGroup = ({
|
|
|
7784
8085
|
currentFrameEffect,
|
|
7785
8086
|
lockAspectRatio = true
|
|
7786
8087
|
}) => {
|
|
7787
|
-
var _a, _b, _c, _d, _e2, _f, _g, _h2, _i2, _j, _k, _l, _m, _n2;
|
|
8088
|
+
var _a, _b, _c, _d, _e2, _f, _g, _h2, _i2, _j, _k, _l, _m, _n2, _o2;
|
|
7788
8089
|
let frameSize;
|
|
7789
8090
|
let angle;
|
|
7790
8091
|
let framePosition;
|
|
@@ -7839,9 +8140,13 @@ const addMediaGroup = ({
|
|
|
7839
8140
|
originX: "center",
|
|
7840
8141
|
originY: "center",
|
|
7841
8142
|
scaleX: newSize.width / img.width,
|
|
7842
|
-
scaleY: newSize.height / img.height
|
|
7843
|
-
opacity: ((_n2 = element.props) == null ? void 0 : _n2.opacity) ?? 1
|
|
8143
|
+
scaleY: newSize.height / img.height
|
|
7844
8144
|
});
|
|
8145
|
+
applyFabricMediaColorFilters(
|
|
8146
|
+
img,
|
|
8147
|
+
(_n2 = element.props) == null ? void 0 : _n2.mediaFilter,
|
|
8148
|
+
((_o2 = element.props) == null ? void 0 : _o2.opacity) ?? 1
|
|
8149
|
+
);
|
|
7845
8150
|
const { x: x2, y: y2 } = convertToCanvasPosition(
|
|
7846
8151
|
(framePosition == null ? void 0 : framePosition.x) || 0,
|
|
7847
8152
|
(framePosition == null ? void 0 : framePosition.y) || 0,
|
|
@@ -8327,7 +8632,8 @@ const CaptionElement = {
|
|
|
8327
8632
|
context.canvasMetadata,
|
|
8328
8633
|
context.videoSize
|
|
8329
8634
|
);
|
|
8330
|
-
|
|
8635
|
+
const useTrackDefaults = ((_a = element.props) == null ? void 0 : _a.useTrackDefaults) ?? true;
|
|
8636
|
+
if (useTrackDefaults) {
|
|
8331
8637
|
return {
|
|
8332
8638
|
element,
|
|
8333
8639
|
operation: CANVAS_OPERATIONS.CAPTION_PROPS_UPDATED,
|
|
@@ -8544,6 +8850,72 @@ const EffectElement = {
|
|
|
8544
8850
|
return;
|
|
8545
8851
|
}
|
|
8546
8852
|
};
|
|
8853
|
+
const EmojiElement = {
|
|
8854
|
+
name: ELEMENT_TYPES.EMOJI,
|
|
8855
|
+
async add(params) {
|
|
8856
|
+
var _a;
|
|
8857
|
+
const { element, index, canvas, canvasMetadata, lockAspectRatio } = params;
|
|
8858
|
+
await addImageElement({
|
|
8859
|
+
element,
|
|
8860
|
+
index,
|
|
8861
|
+
canvas,
|
|
8862
|
+
canvasMetadata,
|
|
8863
|
+
lockAspectRatio: lockAspectRatio ?? ((_a = element.props) == null ? void 0 : _a.lockAspectRatio) ?? true
|
|
8864
|
+
});
|
|
8865
|
+
},
|
|
8866
|
+
updateFromFabricObject(object, element, context) {
|
|
8867
|
+
const canvasCenter = getObjectCanvasCenter(object);
|
|
8868
|
+
const { x: x2, y: y2 } = convertToVideoPosition(
|
|
8869
|
+
canvasCenter.x,
|
|
8870
|
+
canvasCenter.y,
|
|
8871
|
+
context.canvasMetadata,
|
|
8872
|
+
context.videoSize
|
|
8873
|
+
);
|
|
8874
|
+
if (object.type === "group") {
|
|
8875
|
+
const scaledW2 = (object.width ?? 0) * (object.scaleX ?? 1);
|
|
8876
|
+
const scaledH2 = (object.height ?? 0) * (object.scaleY ?? 1);
|
|
8877
|
+
const { width: fw, height: fh2 } = convertToVideoDimensions(
|
|
8878
|
+
scaledW2,
|
|
8879
|
+
scaledH2,
|
|
8880
|
+
context.canvasMetadata
|
|
8881
|
+
);
|
|
8882
|
+
const updatedFrameSize = [fw, fh2];
|
|
8883
|
+
const frame2 = element.frame;
|
|
8884
|
+
return {
|
|
8885
|
+
element: {
|
|
8886
|
+
...element,
|
|
8887
|
+
frame: {
|
|
8888
|
+
...frame2,
|
|
8889
|
+
rotation: getObjectCanvasAngle(object),
|
|
8890
|
+
size: updatedFrameSize,
|
|
8891
|
+
x: x2,
|
|
8892
|
+
y: y2
|
|
8893
|
+
}
|
|
8894
|
+
}
|
|
8895
|
+
};
|
|
8896
|
+
}
|
|
8897
|
+
const scaledW = (object.width ?? 0) * (object.scaleX ?? 1);
|
|
8898
|
+
const scaledH = (object.height ?? 0) * (object.scaleY ?? 1);
|
|
8899
|
+
const { width, height } = convertToVideoDimensions(
|
|
8900
|
+
scaledW,
|
|
8901
|
+
scaledH,
|
|
8902
|
+
context.canvasMetadata
|
|
8903
|
+
);
|
|
8904
|
+
return {
|
|
8905
|
+
element: {
|
|
8906
|
+
...element,
|
|
8907
|
+
props: {
|
|
8908
|
+
...element.props,
|
|
8909
|
+
rotation: getObjectCanvasAngle(object),
|
|
8910
|
+
width,
|
|
8911
|
+
height,
|
|
8912
|
+
x: x2,
|
|
8913
|
+
y: y2
|
|
8914
|
+
}
|
|
8915
|
+
}
|
|
8916
|
+
};
|
|
8917
|
+
}
|
|
8918
|
+
};
|
|
8547
8919
|
class ElementController {
|
|
8548
8920
|
constructor() {
|
|
8549
8921
|
__publicField2(this, "elements", /* @__PURE__ */ new Map());
|
|
@@ -8565,6 +8937,7 @@ function registerElements() {
|
|
|
8565
8937
|
elementController.register(RectElement);
|
|
8566
8938
|
elementController.register(CircleElement);
|
|
8567
8939
|
elementController.register(TextElement);
|
|
8940
|
+
elementController.register(EmojiElement);
|
|
8568
8941
|
elementController.register(CaptionElement);
|
|
8569
8942
|
elementController.register(WatermarkElement);
|
|
8570
8943
|
elementController.register(ArrowElement);
|
|
@@ -9149,6 +9522,8 @@ const DEFAULT_ELEMENT_COLORS = {
|
|
|
9149
9522
|
animation: "#4B9B78",
|
|
9150
9523
|
/** Icon element color - bright orchid */
|
|
9151
9524
|
icon: "#A76CD4",
|
|
9525
|
+
/** Emoji element color - warm amber */
|
|
9526
|
+
emoji: "#F59E0B",
|
|
9152
9527
|
/** Circle element color - deep byzantium */
|
|
9153
9528
|
circle: "#703D8B",
|
|
9154
9529
|
/** Effect element color - cyan accent for global effects */
|
|
@@ -19037,6 +19412,102 @@ const setElementColors = (colors) => {
|
|
|
19037
19412
|
...colors
|
|
19038
19413
|
};
|
|
19039
19414
|
};
|
|
19415
|
+
const VIEWPORT_MARGIN = 8;
|
|
19416
|
+
function clampMenuPosition(clientX, clientY, width, height) {
|
|
19417
|
+
const vw2 = window.innerWidth;
|
|
19418
|
+
const vh3 = window.innerHeight;
|
|
19419
|
+
const maxLeft = Math.max(VIEWPORT_MARGIN, vw2 - width - VIEWPORT_MARGIN);
|
|
19420
|
+
const maxTop = Math.max(VIEWPORT_MARGIN, vh3 - height - VIEWPORT_MARGIN);
|
|
19421
|
+
return {
|
|
19422
|
+
left: Math.min(Math.max(VIEWPORT_MARGIN, clientX), maxLeft),
|
|
19423
|
+
top: Math.min(Math.max(VIEWPORT_MARGIN, clientY), maxTop)
|
|
19424
|
+
};
|
|
19425
|
+
}
|
|
19426
|
+
const TrackElementContextMenu = ({
|
|
19427
|
+
x: x2,
|
|
19428
|
+
y: y2,
|
|
19429
|
+
canSplit,
|
|
19430
|
+
onSplit,
|
|
19431
|
+
onDelete,
|
|
19432
|
+
onClose
|
|
19433
|
+
}) => {
|
|
19434
|
+
const menuRef = React.useRef(null);
|
|
19435
|
+
const [position, setPosition] = React.useState(() => ({
|
|
19436
|
+
left: x2,
|
|
19437
|
+
top: y2
|
|
19438
|
+
}));
|
|
19439
|
+
const reposition = React.useCallback(() => {
|
|
19440
|
+
const el = menuRef.current;
|
|
19441
|
+
if (!el) return;
|
|
19442
|
+
const { width, height } = el.getBoundingClientRect();
|
|
19443
|
+
setPosition(clampMenuPosition(x2, y2, width, height));
|
|
19444
|
+
}, [x2, y2]);
|
|
19445
|
+
React.useLayoutEffect(() => {
|
|
19446
|
+
reposition();
|
|
19447
|
+
}, [reposition]);
|
|
19448
|
+
React.useEffect(() => {
|
|
19449
|
+
window.addEventListener("resize", reposition);
|
|
19450
|
+
return () => window.removeEventListener("resize", reposition);
|
|
19451
|
+
}, [reposition]);
|
|
19452
|
+
React.useEffect(() => {
|
|
19453
|
+
const handleClickOutside = (e3) => {
|
|
19454
|
+
if (menuRef.current && !menuRef.current.contains(e3.target)) {
|
|
19455
|
+
onClose();
|
|
19456
|
+
}
|
|
19457
|
+
};
|
|
19458
|
+
const handleEscape = (e3) => {
|
|
19459
|
+
if (e3.key === "Escape") onClose();
|
|
19460
|
+
};
|
|
19461
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
19462
|
+
document.addEventListener("keydown", handleEscape);
|
|
19463
|
+
return () => {
|
|
19464
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
19465
|
+
document.removeEventListener("keydown", handleEscape);
|
|
19466
|
+
};
|
|
19467
|
+
}, [onClose]);
|
|
19468
|
+
const wrap = (fn2) => {
|
|
19469
|
+
fn2();
|
|
19470
|
+
onClose();
|
|
19471
|
+
};
|
|
19472
|
+
const menu = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
19473
|
+
"div",
|
|
19474
|
+
{
|
|
19475
|
+
ref: menuRef,
|
|
19476
|
+
className: "twick-canvas-context-menu",
|
|
19477
|
+
style: { left: position.left, top: position.top },
|
|
19478
|
+
role: "menu",
|
|
19479
|
+
children: [
|
|
19480
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19481
|
+
"button",
|
|
19482
|
+
{
|
|
19483
|
+
type: "button",
|
|
19484
|
+
className: "twick-canvas-context-menu-item",
|
|
19485
|
+
onClick: () => wrap(onSplit),
|
|
19486
|
+
disabled: !canSplit,
|
|
19487
|
+
role: "menuitem",
|
|
19488
|
+
style: !canSplit ? { opacity: 0.45, cursor: "not-allowed" } : void 0,
|
|
19489
|
+
children: "Split at playhead"
|
|
19490
|
+
}
|
|
19491
|
+
),
|
|
19492
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-canvas-context-menu-separator", role: "separator" }),
|
|
19493
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
19494
|
+
"button",
|
|
19495
|
+
{
|
|
19496
|
+
type: "button",
|
|
19497
|
+
className: "twick-canvas-context-menu-item twick-canvas-context-menu-item-danger",
|
|
19498
|
+
onClick: () => wrap(onDelete),
|
|
19499
|
+
role: "menuitem",
|
|
19500
|
+
children: "Delete"
|
|
19501
|
+
}
|
|
19502
|
+
)
|
|
19503
|
+
]
|
|
19504
|
+
}
|
|
19505
|
+
);
|
|
19506
|
+
if (typeof document === "undefined") {
|
|
19507
|
+
return null;
|
|
19508
|
+
}
|
|
19509
|
+
return reactDom.createPortal(menu, document.body);
|
|
19510
|
+
};
|
|
19040
19511
|
const TrackElementView = ({
|
|
19041
19512
|
element,
|
|
19042
19513
|
parentWidth,
|
|
@@ -19049,13 +19520,20 @@ const TrackElementView = ({
|
|
|
19049
19520
|
onDrag,
|
|
19050
19521
|
allowOverlap = false,
|
|
19051
19522
|
onDragStateChange,
|
|
19052
|
-
elementColors
|
|
19523
|
+
elementColors,
|
|
19524
|
+
currentTime = 0,
|
|
19525
|
+
onContextMenuTarget,
|
|
19526
|
+
onDeleteElement,
|
|
19527
|
+
onSplitElement
|
|
19053
19528
|
}) => {
|
|
19054
19529
|
var _a, _b;
|
|
19055
19530
|
const ref = React.useRef(null);
|
|
19056
19531
|
const dragType = React.useRef(null);
|
|
19057
19532
|
const lastPosRef = React.useRef(null);
|
|
19058
19533
|
const [isDragging2, setIsDragging] = React.useState(false);
|
|
19534
|
+
const [clipMenu, setClipMenu] = React.useState(
|
|
19535
|
+
null
|
|
19536
|
+
);
|
|
19059
19537
|
const [position, setPosition] = React.useState({
|
|
19060
19538
|
start: 0,
|
|
19061
19539
|
end: 0
|
|
@@ -19085,6 +19563,7 @@ const TrackElementView = ({
|
|
|
19085
19563
|
newStart = nextStart - span;
|
|
19086
19564
|
}
|
|
19087
19565
|
}
|
|
19566
|
+
newStart = Math.max(0, Math.min(newStart, duration - span));
|
|
19088
19567
|
return {
|
|
19089
19568
|
start: newStart,
|
|
19090
19569
|
end: newStart + span
|
|
@@ -19107,6 +19586,7 @@ const TrackElementView = ({
|
|
|
19107
19586
|
if (prevEnd !== null && !allowOverlap && newStart < prevEnd) {
|
|
19108
19587
|
newStart = prevEnd;
|
|
19109
19588
|
}
|
|
19589
|
+
newStart = Math.max(0, Math.min(newStart, prev.end - MIN_DURATION));
|
|
19110
19590
|
return {
|
|
19111
19591
|
start: newStart,
|
|
19112
19592
|
end: prev.end
|
|
@@ -19131,6 +19611,7 @@ const TrackElementView = ({
|
|
|
19131
19611
|
newEnd = nextStart;
|
|
19132
19612
|
}
|
|
19133
19613
|
}
|
|
19614
|
+
newEnd = Math.max(prev.start + MIN_DURATION, Math.min(newEnd, duration));
|
|
19134
19615
|
return {
|
|
19135
19616
|
start: prev.start,
|
|
19136
19617
|
end: newEnd
|
|
@@ -19168,7 +19649,7 @@ const TrackElementView = ({
|
|
|
19168
19649
|
};
|
|
19169
19650
|
const getElementColor = (elementType) => {
|
|
19170
19651
|
const colors = elementColors || ELEMENT_COLORS;
|
|
19171
|
-
const key = elementType === timeline.TIMELINE_ELEMENT_TYPE.VIDEO ? "video" : elementType === timeline.TIMELINE_ELEMENT_TYPE.AUDIO ? "audio" : elementType === timeline.TIMELINE_ELEMENT_TYPE.IMAGE ? "image" : elementType === timeline.TIMELINE_ELEMENT_TYPE.TEXT ? "text" : elementType === timeline.TIMELINE_ELEMENT_TYPE.CAPTION ? "caption" : elementType === timeline.TIMELINE_ELEMENT_TYPE.RECT ? "rect" : elementType === timeline.TIMELINE_ELEMENT_TYPE.CIRCLE ? "circle" : elementType === timeline.TIMELINE_ELEMENT_TYPE.ICON ? "icon" : elementType === timeline.TIMELINE_ELEMENT_TYPE.EFFECT ? "effect" : "element";
|
|
19652
|
+
const key = elementType === timeline.TIMELINE_ELEMENT_TYPE.VIDEO ? "video" : elementType === timeline.TIMELINE_ELEMENT_TYPE.AUDIO ? "audio" : elementType === timeline.TIMELINE_ELEMENT_TYPE.IMAGE ? "image" : elementType === timeline.TIMELINE_ELEMENT_TYPE.TEXT ? "text" : elementType === timeline.TIMELINE_ELEMENT_TYPE.CAPTION ? "caption" : elementType === timeline.TIMELINE_ELEMENT_TYPE.RECT ? "rect" : elementType === timeline.TIMELINE_ELEMENT_TYPE.CIRCLE ? "circle" : elementType === timeline.TIMELINE_ELEMENT_TYPE.ICON ? "icon" : elementType === timeline.TIMELINE_ELEMENT_TYPE.EMOJI ? "emoji" : elementType === timeline.TIMELINE_ELEMENT_TYPE.EFFECT ? "effect" : "element";
|
|
19172
19653
|
if (key in colors) {
|
|
19173
19654
|
return colors[key];
|
|
19174
19655
|
}
|
|
@@ -19178,6 +19659,16 @@ const TrackElementView = ({
|
|
|
19178
19659
|
return selectedIds.has(element.getId());
|
|
19179
19660
|
}, [selectedIds, element]);
|
|
19180
19661
|
const hasHandles = (selectedItem == null ? void 0 : selectedItem.getId()) === element.getId();
|
|
19662
|
+
const contextActionsEnabled = Boolean(
|
|
19663
|
+
onDeleteElement && onSplitElement && onContextMenuTarget
|
|
19664
|
+
);
|
|
19665
|
+
const handleContextMenu = (e3) => {
|
|
19666
|
+
if (!contextActionsEnabled) return;
|
|
19667
|
+
e3.preventDefault();
|
|
19668
|
+
e3.stopPropagation();
|
|
19669
|
+
onContextMenuTarget == null ? void 0 : onContextMenuTarget(element);
|
|
19670
|
+
setClipMenu({ x: e3.clientX, y: e3.clientY });
|
|
19671
|
+
};
|
|
19181
19672
|
const motionProps = {
|
|
19182
19673
|
ref,
|
|
19183
19674
|
className: `twick-track-element ${isSelected ? "twick-track-element-selected" : "twick-track-element-default"} ${isDragging2 ? "twick-track-element-dragging" : ""}`,
|
|
@@ -19198,6 +19689,7 @@ const TrackElementView = ({
|
|
|
19198
19689
|
onSelection(element, e3);
|
|
19199
19690
|
}
|
|
19200
19691
|
},
|
|
19692
|
+
onContextMenu: handleContextMenu,
|
|
19201
19693
|
style: {
|
|
19202
19694
|
backgroundColor: getElementColor(element.getType()),
|
|
19203
19695
|
width: `${(position.end - position.start) / duration * 100}%`,
|
|
@@ -19205,39 +19697,52 @@ const TrackElementView = ({
|
|
|
19205
19697
|
touchAction: "none"
|
|
19206
19698
|
}
|
|
19207
19699
|
};
|
|
19208
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
19209
|
-
|
|
19210
|
-
|
|
19700
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(motion.div, { ...motionProps, children: [
|
|
19701
|
+
clipMenu && contextActionsEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
19702
|
+
TrackElementContextMenu,
|
|
19211
19703
|
{
|
|
19212
|
-
|
|
19213
|
-
|
|
19214
|
-
|
|
19704
|
+
x: clipMenu.x,
|
|
19705
|
+
y: clipMenu.y,
|
|
19706
|
+
canSplit: timeline.canSplitElement(element, currentTime),
|
|
19707
|
+
onSplit: () => onSplitElement == null ? void 0 : onSplitElement(element, currentTime),
|
|
19708
|
+
onDelete: () => onDeleteElement == null ? void 0 : onDeleteElement(element),
|
|
19709
|
+
onClose: () => setClipMenu(null)
|
|
19215
19710
|
}
|
|
19216
19711
|
) : null,
|
|
19217
|
-
/* @__PURE__ */ jsxRuntime.
|
|
19218
|
-
|
|
19219
|
-
"div",
|
|
19220
|
-
{
|
|
19221
|
-
style: { touchAction: "none", zIndex: isSelected ? 100 : 1 },
|
|
19222
|
-
...bindEndHandle(),
|
|
19223
|
-
className: "twick-track-element-handle twick-track-element-handle-end"
|
|
19224
|
-
}
|
|
19225
|
-
) : null,
|
|
19226
|
-
element.getFrameEffects ? element.getFrameEffects().map((frameEffect) => {
|
|
19227
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19712
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { touchAction: "none", height: "100%" }, ...bind(), children: [
|
|
19713
|
+
hasHandles ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
19228
19714
|
"div",
|
|
19229
19715
|
{
|
|
19230
|
-
|
|
19231
|
-
|
|
19232
|
-
|
|
19233
|
-
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
|
|
19237
|
-
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
|
|
19716
|
+
style: { touchAction: "none", zIndex: isSelected ? 100 : 1 },
|
|
19717
|
+
...bindStartHandle(),
|
|
19718
|
+
className: "twick-track-element-handle twick-track-element-handle-start"
|
|
19719
|
+
}
|
|
19720
|
+
) : null,
|
|
19721
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-track-element-content", children: element.getType() === timeline.TIMELINE_ELEMENT_TYPE.EFFECT ? ((_b = (_a = element.getProps) == null ? void 0 : _a.call(element)) == null ? void 0 : _b.effectKey) ?? "Effect" : element.getText ? element.getText() : element.getName() || element.getType() }),
|
|
19722
|
+
hasHandles ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
19723
|
+
"div",
|
|
19724
|
+
{
|
|
19725
|
+
style: { touchAction: "none", zIndex: isSelected ? 100 : 1 },
|
|
19726
|
+
...bindEndHandle(),
|
|
19727
|
+
className: "twick-track-element-handle twick-track-element-handle-end"
|
|
19728
|
+
}
|
|
19729
|
+
) : null,
|
|
19730
|
+
element.getFrameEffects ? element.getFrameEffects().map((frameEffect) => {
|
|
19731
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19732
|
+
"div",
|
|
19733
|
+
{
|
|
19734
|
+
className: "twick-track-element-frame-effect",
|
|
19735
|
+
style: {
|
|
19736
|
+
backgroundColor: getElementColor("frameEffect"),
|
|
19737
|
+
width: `${(frameEffect.e - frameEffect.s) / element.getDuration() * 100}%`,
|
|
19738
|
+
left: `${frameEffect.s / element.getDuration() * 100}%`
|
|
19739
|
+
}
|
|
19740
|
+
},
|
|
19741
|
+
frameEffect.s + frameEffect.e
|
|
19742
|
+
);
|
|
19743
|
+
}) : null
|
|
19744
|
+
] })
|
|
19745
|
+
] });
|
|
19241
19746
|
};
|
|
19242
19747
|
const TrackBase = ({
|
|
19243
19748
|
duration,
|
|
@@ -19250,11 +19755,21 @@ const TrackBase = ({
|
|
|
19250
19755
|
onDrag,
|
|
19251
19756
|
allowOverlap = false,
|
|
19252
19757
|
onDragStateChange,
|
|
19253
|
-
elementColors
|
|
19758
|
+
elementColors,
|
|
19759
|
+
currentTime,
|
|
19760
|
+
onContextMenuTarget,
|
|
19761
|
+
onDeleteElement,
|
|
19762
|
+
onSplitElement
|
|
19254
19763
|
}) => {
|
|
19255
19764
|
const trackRef = React.useRef(null);
|
|
19256
19765
|
const trackWidthStyle = `${Math.max(100, duration * zoom * 100)}px`;
|
|
19257
|
-
const elements = track.getElements()
|
|
19766
|
+
const elements = [...track.getElements()].sort((a2, b2) => {
|
|
19767
|
+
const byStart = a2.getStart() - b2.getStart();
|
|
19768
|
+
if (byStart !== 0) return byStart;
|
|
19769
|
+
const byEnd = a2.getEnd() - b2.getEnd();
|
|
19770
|
+
if (byEnd !== 0) return byEnd;
|
|
19771
|
+
return a2.getId().localeCompare(b2.getId());
|
|
19772
|
+
});
|
|
19258
19773
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19259
19774
|
"div",
|
|
19260
19775
|
{
|
|
@@ -19276,6 +19791,10 @@ const TrackBase = ({
|
|
|
19276
19791
|
onDrag,
|
|
19277
19792
|
onDragStateChange,
|
|
19278
19793
|
elementColors,
|
|
19794
|
+
currentTime,
|
|
19795
|
+
onContextMenuTarget,
|
|
19796
|
+
onDeleteElement,
|
|
19797
|
+
onSplitElement,
|
|
19279
19798
|
nextStart: index < elements.length - 1 ? elements[index + 1].getStart() : null,
|
|
19280
19799
|
prevEnd: index > 0 ? elements[index - 1].getEnd() : 0
|
|
19281
19800
|
},
|
|
@@ -19580,7 +20099,11 @@ function TimelineView({
|
|
|
19580
20099
|
onDropOnTimeline,
|
|
19581
20100
|
videoResolution,
|
|
19582
20101
|
enableDropOnTimeline = true,
|
|
19583
|
-
chapters = []
|
|
20102
|
+
chapters = [],
|
|
20103
|
+
currentTime = 0,
|
|
20104
|
+
onContextMenuTarget,
|
|
20105
|
+
onDeleteElement,
|
|
20106
|
+
onSplitElement
|
|
19584
20107
|
}) {
|
|
19585
20108
|
const containerRef = React.useRef(null);
|
|
19586
20109
|
const seekContainerRef = React.useRef(null);
|
|
@@ -19599,15 +20122,28 @@ function TimelineView({
|
|
|
19599
20122
|
const handleDragWithDrop = React.useCallback(
|
|
19600
20123
|
(payload, dropPointer) => {
|
|
19601
20124
|
var _a;
|
|
19602
|
-
if (dropPointer
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
20125
|
+
if (!dropPointer || !onElementDrop) {
|
|
20126
|
+
onElementDrag(payload);
|
|
20127
|
+
return;
|
|
20128
|
+
}
|
|
20129
|
+
const rect = (_a = timelineContentRef.current) == null ? void 0 : _a.getBoundingClientRect();
|
|
20130
|
+
const dropTarget = rect ? getTrackOrSeparatorAt(dropPointer.clientY, rect.top, TRACK_HEIGHT) : null;
|
|
20131
|
+
if ((dropTarget == null ? void 0 : dropTarget.type) === "track") {
|
|
20132
|
+
const elementTrackId = payload.element.getTrackId();
|
|
20133
|
+
const elementTrackIndex = (tracks || []).findIndex(
|
|
20134
|
+
(t2) => t2.getId() === elementTrackId
|
|
20135
|
+
);
|
|
20136
|
+
if (elementTrackIndex === dropTarget.trackIndex) {
|
|
20137
|
+
onElementDrag(payload);
|
|
20138
|
+
return;
|
|
20139
|
+
}
|
|
20140
|
+
} else if (!dropTarget) {
|
|
19607
20141
|
onElementDrag(payload);
|
|
20142
|
+
return;
|
|
19608
20143
|
}
|
|
20144
|
+
onElementDrop({ ...payload, dropTarget });
|
|
19609
20145
|
},
|
|
19610
|
-
[onElementDrag, onElementDrop]
|
|
20146
|
+
[onElementDrag, onElementDrop, tracks]
|
|
19611
20147
|
);
|
|
19612
20148
|
useEdgeAutoScroll({
|
|
19613
20149
|
isActive: !!draggingElementId,
|
|
@@ -19836,7 +20372,11 @@ function TimelineView({
|
|
|
19836
20372
|
onDragStateChange: (isDragging2, el) => {
|
|
19837
20373
|
setDraggingElementId(isDragging2 && el ? el.getId() : null);
|
|
19838
20374
|
},
|
|
19839
|
-
elementColors
|
|
20375
|
+
elementColors,
|
|
20376
|
+
currentTime,
|
|
20377
|
+
onContextMenuTarget,
|
|
20378
|
+
onDeleteElement,
|
|
20379
|
+
onSplitElement
|
|
19840
20380
|
}
|
|
19841
20381
|
)
|
|
19842
20382
|
] }),
|
|
@@ -19879,13 +20419,14 @@ const useTimelineManager = () => {
|
|
|
19879
20419
|
const deltaMin = -minStart;
|
|
19880
20420
|
const deltaMax = duration - maxEnd;
|
|
19881
20421
|
const clampedDelta = Math.max(deltaMin, Math.min(deltaMax, delta));
|
|
19882
|
-
|
|
19883
|
-
|
|
19884
|
-
|
|
19885
|
-
|
|
19886
|
-
|
|
19887
|
-
|
|
19888
|
-
}
|
|
20422
|
+
const batchUpdates = elements.map((el) => ({
|
|
20423
|
+
elementId: el.getId(),
|
|
20424
|
+
updates: {
|
|
20425
|
+
s: el.getStart() + clampedDelta,
|
|
20426
|
+
e: el.getEnd() + clampedDelta
|
|
20427
|
+
}
|
|
20428
|
+
}));
|
|
20429
|
+
editor.updateElements(batchUpdates);
|
|
19889
20430
|
setSelectedItem(element);
|
|
19890
20431
|
editor.refresh();
|
|
19891
20432
|
return;
|
|
@@ -19894,7 +20435,8 @@ const useTimelineManager = () => {
|
|
|
19894
20435
|
if (dragType === DRAG_TYPE.START) {
|
|
19895
20436
|
if (element instanceof timeline.VideoElement || element instanceof timeline.AudioElement) {
|
|
19896
20437
|
const elementProps = element.getProps();
|
|
19897
|
-
const
|
|
20438
|
+
const playbackRate = (elementProps == null ? void 0 : elementProps.playbackRate) || 1;
|
|
20439
|
+
const delta = (updates.start - element.getStart()) * playbackRate;
|
|
19898
20440
|
if (element instanceof timeline.AudioElement) {
|
|
19899
20441
|
element.setStartAt(element.getStartAt() + delta);
|
|
19900
20442
|
} else {
|
|
@@ -19902,10 +20444,10 @@ const useTimelineManager = () => {
|
|
|
19902
20444
|
}
|
|
19903
20445
|
}
|
|
19904
20446
|
}
|
|
19905
|
-
|
|
19906
|
-
|
|
19907
|
-
|
|
19908
|
-
setSelectedItem(
|
|
20447
|
+
editor.updateElements([
|
|
20448
|
+
{ elementId: element.getId(), updates: { s: updates.start, e: updates.end } }
|
|
20449
|
+
]);
|
|
20450
|
+
setSelectedItem(element);
|
|
19909
20451
|
editor.refresh();
|
|
19910
20452
|
};
|
|
19911
20453
|
const isElementTrackType = (track) => track.getType() === timeline.TRACK_TYPES.ELEMENT;
|
|
@@ -20007,6 +20549,38 @@ const useTimelineManager = () => {
|
|
|
20007
20549
|
totalDuration
|
|
20008
20550
|
};
|
|
20009
20551
|
};
|
|
20552
|
+
const useTimelineControl = () => {
|
|
20553
|
+
const { editor, setSelectedItem, selectedIds } = timeline.useTimelineContext();
|
|
20554
|
+
const deleteItem = (item) => {
|
|
20555
|
+
var _a;
|
|
20556
|
+
const tracks = ((_a = editor.getTimelineData()) == null ? void 0 : _a.tracks) ?? [];
|
|
20557
|
+
const toDelete = item !== void 0 ? [item] : timeline.resolveIds(selectedIds, tracks);
|
|
20558
|
+
for (const el of toDelete) {
|
|
20559
|
+
if (el instanceof timeline.Track) {
|
|
20560
|
+
editor.removeTrack(el);
|
|
20561
|
+
} else if (el instanceof timeline.TrackElement) {
|
|
20562
|
+
editor.removeElement(el);
|
|
20563
|
+
}
|
|
20564
|
+
}
|
|
20565
|
+
setSelectedItem(null);
|
|
20566
|
+
};
|
|
20567
|
+
const splitElement = (element, currentTime) => {
|
|
20568
|
+
if (!timeline.canSplitElement(element, currentTime)) return;
|
|
20569
|
+
void editor.splitElement(element, currentTime);
|
|
20570
|
+
};
|
|
20571
|
+
const handleUndo = () => {
|
|
20572
|
+
editor.undo();
|
|
20573
|
+
};
|
|
20574
|
+
const handleRedo = () => {
|
|
20575
|
+
editor.redo();
|
|
20576
|
+
};
|
|
20577
|
+
return {
|
|
20578
|
+
splitElement,
|
|
20579
|
+
deleteItem,
|
|
20580
|
+
handleUndo,
|
|
20581
|
+
handleRedo
|
|
20582
|
+
};
|
|
20583
|
+
};
|
|
20010
20584
|
function useTimelineSelection() {
|
|
20011
20585
|
const { editor, selectedIds, setSelection, setSelectedItem } = timeline.useTimelineContext();
|
|
20012
20586
|
const handleItemSelect = React.useCallback(
|
|
@@ -20087,8 +20661,9 @@ const TimelineManager = ({
|
|
|
20087
20661
|
elementColors
|
|
20088
20662
|
}) => {
|
|
20089
20663
|
var _a, _b;
|
|
20090
|
-
const { playerState } = livePlayer.useLivePlayerContext();
|
|
20664
|
+
const { playerState, currentTime } = livePlayer.useLivePlayerContext();
|
|
20091
20665
|
const { followPlayheadEnabled, editor, videoResolution, setSelectedItem } = timeline.useTimelineContext();
|
|
20666
|
+
const { deleteItem, splitElement } = useTimelineControl();
|
|
20092
20667
|
const {
|
|
20093
20668
|
timelineData,
|
|
20094
20669
|
totalDuration,
|
|
@@ -20109,6 +20684,12 @@ const TimelineManager = ({
|
|
|
20109
20684
|
setPlayheadState(state);
|
|
20110
20685
|
}, []);
|
|
20111
20686
|
const isPlayheadActive = followPlayheadEnabled && playerState === livePlayer.PLAYER_STATE.PLAYING || playheadState.isDragging;
|
|
20687
|
+
const handleContextMenuTarget = React.useCallback(
|
|
20688
|
+
(element) => {
|
|
20689
|
+
setSelectedItem(element);
|
|
20690
|
+
},
|
|
20691
|
+
[setSelectedItem]
|
|
20692
|
+
);
|
|
20112
20693
|
const handleDropOnTimeline = React.useCallback(
|
|
20113
20694
|
async (params) => {
|
|
20114
20695
|
const { track, timeSec, type, url } = params;
|
|
@@ -20156,6 +20737,10 @@ const TimelineManager = ({
|
|
|
20156
20737
|
onEmptyClick: handleEmptyClick,
|
|
20157
20738
|
onMarqueeSelect: handleMarqueeSelect,
|
|
20158
20739
|
elementColors,
|
|
20740
|
+
currentTime,
|
|
20741
|
+
onContextMenuTarget: handleContextMenuTarget,
|
|
20742
|
+
onDeleteElement: (el) => deleteItem(el),
|
|
20743
|
+
onSplitElement: (el, t2) => splitElement(el, t2),
|
|
20159
20744
|
playheadPositionPx: playheadState.positionPx,
|
|
20160
20745
|
isPlayheadActive,
|
|
20161
20746
|
chapters: ((_a = timelineData == null ? void 0 : timelineData.metadata) == null ? void 0 : _a.chapters) ?? [],
|
|
@@ -20239,11 +20824,12 @@ const PlayerControls = ({
|
|
|
20239
20824
|
}
|
|
20240
20825
|
}, [selectedIds.size, onDelete]);
|
|
20241
20826
|
const hasSelection = selectedIds.size > 0;
|
|
20827
|
+
const canSplitSelected = selectedItem instanceof timeline.TrackElement ? timeline.canSplitElement(selectedItem, currentTime) : false;
|
|
20242
20828
|
const handleSplit = React.useCallback(() => {
|
|
20243
|
-
if (selectedItem instanceof timeline.TrackElement && onSplit) {
|
|
20829
|
+
if (selectedItem instanceof timeline.TrackElement && onSplit && canSplitSelected) {
|
|
20244
20830
|
onSplit(selectedItem, currentTime);
|
|
20245
20831
|
}
|
|
20246
|
-
}, [selectedItem, onSplit, currentTime]);
|
|
20832
|
+
}, [selectedItem, onSplit, currentTime, canSplitSelected]);
|
|
20247
20833
|
const handleZoomIn = React.useCallback(() => {
|
|
20248
20834
|
if (setZoomLevel && zoomLevel < MAX_ZOOM) {
|
|
20249
20835
|
setZoomLevel(zoomLevel + ZOOM_STEP);
|
|
@@ -20270,9 +20856,9 @@ const PlayerControls = ({
|
|
|
20270
20856
|
"button",
|
|
20271
20857
|
{
|
|
20272
20858
|
onClick: handleSplit,
|
|
20273
|
-
disabled: !
|
|
20859
|
+
disabled: !canSplitSelected,
|
|
20274
20860
|
title: "Split",
|
|
20275
|
-
className: `control-btn split-btn ${!
|
|
20861
|
+
className: `control-btn split-btn ${!canSplitSelected ? "btn-disabled" : ""}`,
|
|
20276
20862
|
children: /* @__PURE__ */ jsxRuntime.jsx(Scissors, { className: "icon-md" })
|
|
20277
20863
|
}
|
|
20278
20864
|
),
|
|
@@ -20386,37 +20972,6 @@ const usePlayerControl = () => {
|
|
|
20386
20972
|
togglePlayback
|
|
20387
20973
|
};
|
|
20388
20974
|
};
|
|
20389
|
-
const useTimelineControl = () => {
|
|
20390
|
-
const { editor, setSelectedItem, selectedIds } = timeline.useTimelineContext();
|
|
20391
|
-
const deleteItem = (item) => {
|
|
20392
|
-
var _a;
|
|
20393
|
-
const tracks = ((_a = editor.getTimelineData()) == null ? void 0 : _a.tracks) ?? [];
|
|
20394
|
-
const toDelete = item !== void 0 ? [item] : timeline.resolveIds(selectedIds, tracks);
|
|
20395
|
-
for (const el of toDelete) {
|
|
20396
|
-
if (el instanceof timeline.Track) {
|
|
20397
|
-
editor.removeTrack(el);
|
|
20398
|
-
} else if (el instanceof timeline.TrackElement) {
|
|
20399
|
-
editor.removeElement(el);
|
|
20400
|
-
}
|
|
20401
|
-
}
|
|
20402
|
-
setSelectedItem(null);
|
|
20403
|
-
};
|
|
20404
|
-
const splitElement = (element, currentTime) => {
|
|
20405
|
-
editor.splitElement(element, currentTime);
|
|
20406
|
-
};
|
|
20407
|
-
const handleUndo = () => {
|
|
20408
|
-
editor.undo();
|
|
20409
|
-
};
|
|
20410
|
-
const handleRedo = () => {
|
|
20411
|
-
editor.redo();
|
|
20412
|
-
};
|
|
20413
|
-
return {
|
|
20414
|
-
splitElement,
|
|
20415
|
-
deleteItem,
|
|
20416
|
-
handleUndo,
|
|
20417
|
-
handleRedo
|
|
20418
|
-
};
|
|
20419
|
-
};
|
|
20420
20975
|
function shouldIgnoreKeydown() {
|
|
20421
20976
|
const active = document.activeElement;
|
|
20422
20977
|
if (!active) return false;
|