@twick/video-editor 0.14.3 → 0.14.5
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/controls/player-controls.d.ts +6 -0
- package/dist/components/player/player-manager.d.ts +5 -1
- package/dist/components/timeline/timeline-manager.d.ts +1 -2
- package/dist/components/timeline/timeline-view.d.ts +2 -2
- package/dist/components/track/track-element.d.ts +1 -1
- package/dist/components/video-editor.d.ts +7 -2
- package/dist/helpers/types.d.ts +52 -183
- package/dist/hooks/use-timeline-manager.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +319 -231
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +319 -231
- package/dist/index.mjs.map +1 -1
- package/dist/video-editor.css +3 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -6936,10 +6936,19 @@ const reorderElementsByZIndex = (canvas) => {
|
|
|
6936
6936
|
objects.forEach((obj) => canvas.add(obj));
|
|
6937
6937
|
canvas.renderAll();
|
|
6938
6938
|
};
|
|
6939
|
+
const getCanvasContext = (canvas) => {
|
|
6940
|
+
var _a2, _b, _c, _d;
|
|
6941
|
+
if (!canvas || !((_b = (_a2 = canvas.elements) == null ? void 0 : _a2.lower) == null ? void 0 : _b.ctx)) return;
|
|
6942
|
+
return (_d = (_c = canvas.elements) == null ? void 0 : _c.lower) == null ? void 0 : _d.ctx;
|
|
6943
|
+
};
|
|
6939
6944
|
const clearCanvas = (canvas) => {
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6945
|
+
try {
|
|
6946
|
+
if (!canvas || !getCanvasContext(canvas)) return;
|
|
6947
|
+
canvas.clear();
|
|
6948
|
+
canvas.renderAll();
|
|
6949
|
+
} catch (error) {
|
|
6950
|
+
console.warn("Error clearing canvas:", error);
|
|
6951
|
+
}
|
|
6943
6952
|
};
|
|
6944
6953
|
const convertToCanvasPosition = (x2, y2, canvasMetadata) => {
|
|
6945
6954
|
return {
|
|
@@ -6949,8 +6958,8 @@ const convertToCanvasPosition = (x2, y2, canvasMetadata) => {
|
|
|
6949
6958
|
};
|
|
6950
6959
|
const convertToVideoPosition = (x2, y2, canvasMetadata, videoSize) => {
|
|
6951
6960
|
return {
|
|
6952
|
-
x: x2 / canvasMetadata.scaleX - videoSize.width / 2,
|
|
6953
|
-
y: y2 / canvasMetadata.scaleY - videoSize.height / 2
|
|
6961
|
+
x: Number((x2 / canvasMetadata.scaleX - videoSize.width / 2).toFixed(2)),
|
|
6962
|
+
y: Number((y2 / canvasMetadata.scaleY - videoSize.height / 2).toFixed(2))
|
|
6954
6963
|
};
|
|
6955
6964
|
};
|
|
6956
6965
|
const getCurrentFrameEffect = (item, seekTime) => {
|
|
@@ -6985,7 +6994,7 @@ const disabledControl = new Hs({
|
|
|
6985
6994
|
ctx.save();
|
|
6986
6995
|
ctx.translate(left, top);
|
|
6987
6996
|
ctx.fillStyle = "#red";
|
|
6988
|
-
ctx.fillRect(-
|
|
6997
|
+
ctx.fillRect(-size / 2, -size / 2, size, size);
|
|
6989
6998
|
ctx.restore();
|
|
6990
6999
|
}
|
|
6991
7000
|
});
|
|
@@ -7085,7 +7094,7 @@ const getThumbnail = async (videoUrl, seekTime = 0.1, playbackRate = 1) => {
|
|
|
7085
7094
|
timeoutId = window.setTimeout(() => {
|
|
7086
7095
|
cleanup();
|
|
7087
7096
|
reject(new Error("Video loading timed out"));
|
|
7088
|
-
},
|
|
7097
|
+
}, 15e3);
|
|
7089
7098
|
video.src = videoUrl;
|
|
7090
7099
|
document.body.appendChild(video);
|
|
7091
7100
|
});
|
|
@@ -7136,7 +7145,7 @@ const addTextElement = ({
|
|
|
7136
7145
|
canvas,
|
|
7137
7146
|
canvasMetadata
|
|
7138
7147
|
}) => {
|
|
7139
|
-
var _a2, _b, _c, _d, _e2, _f, _g, _h, _i2, _j, _k, _l, _m, _n2, _o2, _p, _q, _r2, _s2, _t2, _u, _v;
|
|
7148
|
+
var _a2, _b, _c, _d, _e2, _f, _g, _h, _i2, _j, _k, _l, _m, _n2, _o2, _p, _q, _r2, _s2, _t2, _u, _v, _w;
|
|
7140
7149
|
const { x: x2, y: y2 } = convertToCanvasPosition(
|
|
7141
7150
|
((_a2 = element.props) == null ? void 0 : _a2.x) || 0,
|
|
7142
7151
|
((_b = element.props) == null ? void 0 : _b.y) || 0,
|
|
@@ -7155,15 +7164,16 @@ const addTextElement = ({
|
|
|
7155
7164
|
fontStyle: ((_g = element.props) == null ? void 0 : _g.fontStyle) || "normal",
|
|
7156
7165
|
fontWeight: ((_h = element.props) == null ? void 0 : _h.fontWeight) || "normal",
|
|
7157
7166
|
fill: ((_i2 = element.props) == null ? void 0 : _i2.fill) || DEFAULT_TEXT_PROPS.fill,
|
|
7167
|
+
opacity: ((_j = element.props) == null ? void 0 : _j.opacity) ?? 1,
|
|
7158
7168
|
skipWrapping: false,
|
|
7159
|
-
textAlign: ((
|
|
7160
|
-
stroke: ((
|
|
7161
|
-
strokeWidth: ((
|
|
7162
|
-
shadow: ((
|
|
7163
|
-
offsetX: ((
|
|
7164
|
-
offsetY: ((
|
|
7165
|
-
blur: (((
|
|
7166
|
-
color: (
|
|
7169
|
+
textAlign: ((_k = element.props) == null ? void 0 : _k.textAlign) || "center",
|
|
7170
|
+
stroke: ((_l = element.props) == null ? void 0 : _l.stroke) || DEFAULT_TEXT_PROPS.stroke,
|
|
7171
|
+
strokeWidth: ((_m = element.props) == null ? void 0 : _m.lineWidth) || DEFAULT_TEXT_PROPS.lineWidth,
|
|
7172
|
+
shadow: ((_n2 = element.props) == null ? void 0 : _n2.shadowColor) ? new ds({
|
|
7173
|
+
offsetX: ((_p = (_o2 = element.props) == null ? void 0 : _o2.shadowOffset) == null ? void 0 : _p.length) && ((_r2 = (_q = element.props) == null ? void 0 : _q.shadowOffset) == null ? void 0 : _r2.length) > 1 ? element.props.shadowOffset[0] / 2 : 1,
|
|
7174
|
+
offsetY: ((_t2 = (_s2 = element.props) == null ? void 0 : _s2.shadowOffset) == null ? void 0 : _t2.length) && ((_u = element.props) == null ? void 0 : _u.shadowOffset.length) > 1 ? element.props.shadowOffset[1] / 2 : 1,
|
|
7175
|
+
blur: (((_v = element.props) == null ? void 0 : _v.shadowBlur) || 2) / 2,
|
|
7176
|
+
color: (_w = element.props) == null ? void 0 : _w.shadowColor
|
|
7167
7177
|
}) : void 0
|
|
7168
7178
|
});
|
|
7169
7179
|
text.set("id", element.id);
|
|
@@ -7186,7 +7196,7 @@ const setImageProps = ({
|
|
|
7186
7196
|
index,
|
|
7187
7197
|
canvasMetadata
|
|
7188
7198
|
}) => {
|
|
7189
|
-
var _a2, _b, _c, _d;
|
|
7199
|
+
var _a2, _b, _c, _d, _e2;
|
|
7190
7200
|
const width = (((_a2 = element.props) == null ? void 0 : _a2.width) || 0) * canvasMetadata.scaleX || canvasMetadata.width;
|
|
7191
7201
|
const height = (((_b = element.props) == null ? void 0 : _b.height) || 0) * canvasMetadata.scaleY || canvasMetadata.height;
|
|
7192
7202
|
const { x: x2, y: y2 } = convertToCanvasPosition(
|
|
@@ -7201,6 +7211,7 @@ const setImageProps = ({
|
|
|
7201
7211
|
img.set("height", height);
|
|
7202
7212
|
img.set("left", x2);
|
|
7203
7213
|
img.set("top", y2);
|
|
7214
|
+
img.set("opacity", ((_e2 = element.props) == null ? void 0 : _e2.opacity) ?? 1);
|
|
7204
7215
|
img.set("selectable", true);
|
|
7205
7216
|
img.set("hasControls", true);
|
|
7206
7217
|
img.set("touchAction", "all");
|
|
@@ -7212,7 +7223,7 @@ const addCaptionElement = ({
|
|
|
7212
7223
|
captionProps,
|
|
7213
7224
|
canvasMetadata
|
|
7214
7225
|
}) => {
|
|
7215
|
-
var _a2, _b, _c, _d, _e2, _f, _g, _h, _i2, _j, _k, _l, _m, _n2, _o2, _p, _q, _r2, _s2, _t2, _u, _v, _w, _x, _y, _z;
|
|
7226
|
+
var _a2, _b, _c, _d, _e2, _f, _g, _h, _i2, _j, _k, _l, _m, _n2, _o2, _p, _q, _r2, _s2, _t2, _u, _v, _w, _x, _y, _z, _A;
|
|
7216
7227
|
const { x: x2, y: y2 } = convertToCanvasPosition(
|
|
7217
7228
|
((_b = (_a2 = element.props) == null ? void 0 : _a2.pos) == null ? void 0 : _b.x) || ((_c = captionProps == null ? void 0 : captionProps.pos) == null ? void 0 : _c.x) || 0,
|
|
7218
7229
|
((_e2 = (_d = element.props) == null ? void 0 : _d.pos) == null ? void 0 : _e2.y) || ((_f = captionProps == null ? void 0 : captionProps.pos) == null ? void 0 : _f.y) || 0,
|
|
@@ -7231,13 +7242,14 @@ const addCaptionElement = ({
|
|
|
7231
7242
|
fill: ((_o2 = element.props) == null ? void 0 : _o2.fill) || ((_p = captionProps.color) == null ? void 0 : _p.text) || DEFAULT_CAPTION_PROPS.fill,
|
|
7232
7243
|
fontWeight: DEFAULT_CAPTION_PROPS.fontWeight,
|
|
7233
7244
|
stroke: ((_q = element.props) == null ? void 0 : _q.stroke) || DEFAULT_CAPTION_PROPS.stroke,
|
|
7245
|
+
opacity: ((_r2 = element.props) == null ? void 0 : _r2.opacity) ?? 1,
|
|
7234
7246
|
shadow: new ds({
|
|
7235
|
-
offsetX: ((
|
|
7236
|
-
offsetY: ((
|
|
7237
|
-
blur: ((
|
|
7238
|
-
color: ((
|
|
7247
|
+
offsetX: ((_t2 = (_s2 = element.props) == null ? void 0 : _s2.shadowOffset) == null ? void 0 : _t2[0]) || ((_u = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _u[0]),
|
|
7248
|
+
offsetY: ((_w = (_v = element.props) == null ? void 0 : _v.shadowOffset) == null ? void 0 : _w[1]) || ((_x = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _x[1]),
|
|
7249
|
+
blur: ((_y = element.props) == null ? void 0 : _y.shadowBlur) || DEFAULT_CAPTION_PROPS.shadowBlur,
|
|
7250
|
+
color: ((_z = element.props) == null ? void 0 : _z.shadowColor) || DEFAULT_CAPTION_PROPS.shadowColor
|
|
7239
7251
|
}),
|
|
7240
|
-
strokeWidth: ((
|
|
7252
|
+
strokeWidth: ((_A = element.props) == null ? void 0 : _A.lineWidth) || DEFAULT_CAPTION_PROPS.lineWidth
|
|
7241
7253
|
});
|
|
7242
7254
|
caption.set("id", element.id);
|
|
7243
7255
|
caption.set("zIndex", index);
|
|
@@ -7328,7 +7340,7 @@ const addMediaGroup = ({
|
|
|
7328
7340
|
canvasMetadata,
|
|
7329
7341
|
currentFrameEffect
|
|
7330
7342
|
}) => {
|
|
7331
|
-
var _a2, _b, _c, _d, _e2, _f, _g, _h, _i2, _j, _k, _l, _m;
|
|
7343
|
+
var _a2, _b, _c, _d, _e2, _f, _g, _h, _i2, _j, _k, _l, _m, _n2;
|
|
7332
7344
|
let frameSize;
|
|
7333
7345
|
let angle;
|
|
7334
7346
|
let framePosition;
|
|
@@ -7383,7 +7395,8 @@ const addMediaGroup = ({
|
|
|
7383
7395
|
originX: "center",
|
|
7384
7396
|
originY: "center",
|
|
7385
7397
|
scaleX: newSize.width / img.width,
|
|
7386
|
-
scaleY: newSize.height / img.height
|
|
7398
|
+
scaleY: newSize.height / img.height,
|
|
7399
|
+
opacity: ((_n2 = element.props) == null ? void 0 : _n2.opacity) ?? 1
|
|
7387
7400
|
});
|
|
7388
7401
|
const { x: x2, y: y2 } = convertToCanvasPosition(
|
|
7389
7402
|
(framePosition == null ? void 0 : framePosition.x) || 0,
|
|
@@ -7503,6 +7516,7 @@ const useTwickCanvas = ({
|
|
|
7503
7516
|
const elementFrameMap = useRef({});
|
|
7504
7517
|
const twickCanvasRef = useRef(null);
|
|
7505
7518
|
const videoSizeRef = useRef({ width: 1, height: 1 });
|
|
7519
|
+
const canvasResolutionRef = useRef({ width: 1, height: 1 });
|
|
7506
7520
|
const canvasMetadataRef = useRef({
|
|
7507
7521
|
width: 0,
|
|
7508
7522
|
height: 0,
|
|
@@ -7526,9 +7540,13 @@ const useTwickCanvas = ({
|
|
|
7526
7540
|
selectionLineWidth = 2,
|
|
7527
7541
|
uniScaleTransform = true,
|
|
7528
7542
|
enableRetinaScaling = true,
|
|
7529
|
-
touchZoomThreshold = 10
|
|
7543
|
+
touchZoomThreshold = 10,
|
|
7544
|
+
forceBuild = false
|
|
7530
7545
|
}) => {
|
|
7531
7546
|
if (!canvasRef) return;
|
|
7547
|
+
if (!forceBuild && canvasResolutionRef.current.width === canvasSize.width && canvasResolutionRef.current.height === canvasSize.height) {
|
|
7548
|
+
return;
|
|
7549
|
+
}
|
|
7532
7550
|
if (twickCanvasRef.current) {
|
|
7533
7551
|
console.log("Destroying twickCanvas");
|
|
7534
7552
|
twickCanvasRef.current.off("mouse:up", handleMouseUp);
|
|
@@ -7548,6 +7566,7 @@ const useTwickCanvas = ({
|
|
|
7548
7566
|
canvasMetadataRef.current = canvasMetadata;
|
|
7549
7567
|
videoSizeRef.current = videoSize;
|
|
7550
7568
|
canvas == null ? void 0 : canvas.on("mouse:up", handleMouseUp);
|
|
7569
|
+
canvasResolutionRef.current = canvasSize;
|
|
7551
7570
|
setTwickCanvas(canvas);
|
|
7552
7571
|
twickCanvasRef.current = canvas;
|
|
7553
7572
|
if (onCanvasReady) {
|
|
@@ -7688,13 +7707,18 @@ const useTwickCanvas = ({
|
|
|
7688
7707
|
captionProps,
|
|
7689
7708
|
cleanAndAdd = false
|
|
7690
7709
|
}) => {
|
|
7691
|
-
if (!twickCanvas) {
|
|
7692
|
-
console.warn("Canvas not initialized");
|
|
7710
|
+
if (!twickCanvas || !getCanvasContext(twickCanvas)) {
|
|
7711
|
+
console.warn("Canvas not properly initialized");
|
|
7693
7712
|
return;
|
|
7694
7713
|
}
|
|
7695
7714
|
try {
|
|
7696
|
-
if (cleanAndAdd) {
|
|
7715
|
+
if (cleanAndAdd && getCanvasContext(twickCanvas)) {
|
|
7716
|
+
const backgroundColor = twickCanvas.backgroundColor;
|
|
7697
7717
|
clearCanvas(twickCanvas);
|
|
7718
|
+
if (backgroundColor) {
|
|
7719
|
+
twickCanvas.backgroundColor = backgroundColor;
|
|
7720
|
+
twickCanvas.renderAll();
|
|
7721
|
+
}
|
|
7698
7722
|
}
|
|
7699
7723
|
await Promise.all(
|
|
7700
7724
|
elements.map(async (element, index) => {
|
|
@@ -7813,7 +7837,8 @@ const usePlayerManager = ({
|
|
|
7813
7837
|
videoProps
|
|
7814
7838
|
}) => {
|
|
7815
7839
|
const [projectData, setProjectData] = useState(null);
|
|
7816
|
-
const { timelineAction, setTimelineAction, setSelectedItem, editor } = useTimelineContext();
|
|
7840
|
+
const { timelineAction, setTimelineAction, setSelectedItem, editor, changeLog } = useTimelineContext();
|
|
7841
|
+
const currentChangeLog = useRef(changeLog);
|
|
7817
7842
|
const [playerUpdating, setPlayerUpdating] = useState(false);
|
|
7818
7843
|
const handleCanvasReady = (canvas) => {
|
|
7819
7844
|
console.log("canvas ready", canvas);
|
|
@@ -7826,7 +7851,9 @@ const usePlayerManager = ({
|
|
|
7826
7851
|
break;
|
|
7827
7852
|
case CANVAS_OPERATIONS.ITEM_UPDATED:
|
|
7828
7853
|
if (element) {
|
|
7829
|
-
editor.updateElement(element);
|
|
7854
|
+
const updatedElement = editor.updateElement(element);
|
|
7855
|
+
currentChangeLog.current = currentChangeLog.current + 1;
|
|
7856
|
+
setSelectedItem(updatedElement);
|
|
7830
7857
|
}
|
|
7831
7858
|
break;
|
|
7832
7859
|
}
|
|
@@ -7837,6 +7864,9 @@ const usePlayerManager = ({
|
|
|
7837
7864
|
});
|
|
7838
7865
|
const updateCanvas = (seekTime) => {
|
|
7839
7866
|
var _a2;
|
|
7867
|
+
if (changeLog === currentChangeLog.current) {
|
|
7868
|
+
return;
|
|
7869
|
+
}
|
|
7840
7870
|
const elements = getCurrentElements(
|
|
7841
7871
|
seekTime,
|
|
7842
7872
|
((_a2 = editor.getTimelineData()) == null ? void 0 : _a2.tracks) ?? []
|
|
@@ -7847,6 +7877,7 @@ const usePlayerManager = ({
|
|
|
7847
7877
|
captionProps: {},
|
|
7848
7878
|
cleanAndAdd: true
|
|
7849
7879
|
});
|
|
7880
|
+
currentChangeLog.current = changeLog;
|
|
7850
7881
|
};
|
|
7851
7882
|
const onPlayerUpdate = (event) => {
|
|
7852
7883
|
var _a2;
|
|
@@ -7888,6 +7919,7 @@ const usePlayerManager = ({
|
|
|
7888
7919
|
};
|
|
7889
7920
|
const PlayerManager = ({
|
|
7890
7921
|
videoProps,
|
|
7922
|
+
playerProps,
|
|
7891
7923
|
canvasMode
|
|
7892
7924
|
}) => {
|
|
7893
7925
|
const { changeLog } = useTimelineContext();
|
|
@@ -7909,6 +7941,7 @@ const PlayerManager = ({
|
|
|
7909
7941
|
height: container == null ? void 0 : container.clientHeight
|
|
7910
7942
|
};
|
|
7911
7943
|
buildCanvas({
|
|
7944
|
+
backgroundColor: videoProps.backgroundColor,
|
|
7912
7945
|
videoSize: {
|
|
7913
7946
|
width: videoProps.width,
|
|
7914
7947
|
height: videoProps.height
|
|
@@ -7953,6 +7986,7 @@ const PlayerManager = ({
|
|
|
7953
7986
|
{
|
|
7954
7987
|
seekTime,
|
|
7955
7988
|
projectData,
|
|
7989
|
+
quality: playerProps == null ? void 0 : playerProps.quality,
|
|
7956
7990
|
videoSize: {
|
|
7957
7991
|
width: videoProps.width,
|
|
7958
7992
|
height: videoProps.height
|
|
@@ -9568,7 +9602,7 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
9568
9602
|
* This source code is licensed under the ISC license.
|
|
9569
9603
|
* See the LICENSE file in the root directory of this source tree.
|
|
9570
9604
|
*/
|
|
9571
|
-
const __iconNode$
|
|
9605
|
+
const __iconNode$b = [
|
|
9572
9606
|
["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
|
|
9573
9607
|
["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
|
|
9574
9608
|
["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
|
|
@@ -9576,45 +9610,56 @@ const __iconNode$a = [
|
|
|
9576
9610
|
["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
|
|
9577
9611
|
["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
|
|
9578
9612
|
];
|
|
9579
|
-
const GripVertical = createLucideIcon("grip-vertical", __iconNode$
|
|
9613
|
+
const GripVertical = createLucideIcon("grip-vertical", __iconNode$b);
|
|
9580
9614
|
/**
|
|
9581
9615
|
* @license lucide-react v0.511.0 - ISC
|
|
9582
9616
|
*
|
|
9583
9617
|
* This source code is licensed under the ISC license.
|
|
9584
9618
|
* See the LICENSE file in the root directory of this source tree.
|
|
9585
9619
|
*/
|
|
9586
|
-
const __iconNode$
|
|
9587
|
-
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$
|
|
9620
|
+
const __iconNode$a = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
|
|
9621
|
+
const LoaderCircle = createLucideIcon("loader-circle", __iconNode$a);
|
|
9588
9622
|
/**
|
|
9589
9623
|
* @license lucide-react v0.511.0 - ISC
|
|
9590
9624
|
*
|
|
9591
9625
|
* This source code is licensed under the ISC license.
|
|
9592
9626
|
* See the LICENSE file in the root directory of this source tree.
|
|
9593
9627
|
*/
|
|
9594
|
-
const __iconNode$
|
|
9628
|
+
const __iconNode$9 = [
|
|
9595
9629
|
["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2", key: "1w4ew1" }],
|
|
9596
9630
|
["path", { d: "M7 11V7a5 5 0 0 1 10 0v4", key: "fwvmzm" }]
|
|
9597
9631
|
];
|
|
9598
|
-
const Lock = createLucideIcon("lock", __iconNode$
|
|
9632
|
+
const Lock = createLucideIcon("lock", __iconNode$9);
|
|
9599
9633
|
/**
|
|
9600
9634
|
* @license lucide-react v0.511.0 - ISC
|
|
9601
9635
|
*
|
|
9602
9636
|
* This source code is licensed under the ISC license.
|
|
9603
9637
|
* See the LICENSE file in the root directory of this source tree.
|
|
9604
9638
|
*/
|
|
9605
|
-
const __iconNode$
|
|
9639
|
+
const __iconNode$8 = [
|
|
9606
9640
|
["rect", { x: "14", y: "4", width: "4", height: "16", rx: "1", key: "zuxfzm" }],
|
|
9607
9641
|
["rect", { x: "6", y: "4", width: "4", height: "16", rx: "1", key: "1okwgv" }]
|
|
9608
9642
|
];
|
|
9609
|
-
const Pause = createLucideIcon("pause", __iconNode$
|
|
9643
|
+
const Pause = createLucideIcon("pause", __iconNode$8);
|
|
9610
9644
|
/**
|
|
9611
9645
|
* @license lucide-react v0.511.0 - ISC
|
|
9612
9646
|
*
|
|
9613
9647
|
* This source code is licensed under the ISC license.
|
|
9614
9648
|
* See the LICENSE file in the root directory of this source tree.
|
|
9615
9649
|
*/
|
|
9616
|
-
const __iconNode$
|
|
9617
|
-
const Play = createLucideIcon("play", __iconNode$
|
|
9650
|
+
const __iconNode$7 = [["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]];
|
|
9651
|
+
const Play = createLucideIcon("play", __iconNode$7);
|
|
9652
|
+
/**
|
|
9653
|
+
* @license lucide-react v0.511.0 - ISC
|
|
9654
|
+
*
|
|
9655
|
+
* This source code is licensed under the ISC license.
|
|
9656
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
9657
|
+
*/
|
|
9658
|
+
const __iconNode$6 = [
|
|
9659
|
+
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
9660
|
+
["path", { d: "M12 5v14", key: "s699le" }]
|
|
9661
|
+
];
|
|
9662
|
+
const Plus = createLucideIcon("plus", __iconNode$6);
|
|
9618
9663
|
/**
|
|
9619
9664
|
* @license lucide-react v0.511.0 - ISC
|
|
9620
9665
|
*
|
|
@@ -12511,7 +12556,7 @@ function findSpring({ duration = springDefaults.duration, bounce = springDefault
|
|
|
12511
12556
|
envelope = (undampedFreq2) => {
|
|
12512
12557
|
const a2 = Math.exp(-undampedFreq2 * duration);
|
|
12513
12558
|
const b2 = (undampedFreq2 - velocity) * duration + 1;
|
|
12514
|
-
return -
|
|
12559
|
+
return -safeMin + a2 * b2;
|
|
12515
12560
|
};
|
|
12516
12561
|
derivative = (undampedFreq2) => {
|
|
12517
12562
|
const a2 = Math.exp(-undampedFreq2 * duration);
|
|
@@ -16893,30 +16938,34 @@ const DRAG_TYPE = {
|
|
|
16893
16938
|
};
|
|
16894
16939
|
const DEFAULT_TIMELINE_ZOOM = 1.5;
|
|
16895
16940
|
const DEFAULT_ELEMENT_COLORS = {
|
|
16896
|
-
/** Fragment element color */
|
|
16897
|
-
fragment: "#
|
|
16898
|
-
/** Video element color -
|
|
16899
|
-
video: "#
|
|
16900
|
-
/** Caption element color -
|
|
16901
|
-
caption: "#
|
|
16902
|
-
/** Image element color -
|
|
16903
|
-
image: "#
|
|
16904
|
-
/** Audio element color -
|
|
16905
|
-
audio: "#
|
|
16906
|
-
/** Text element color -
|
|
16907
|
-
text: "#
|
|
16908
|
-
/** Generic element color - muted
|
|
16909
|
-
element: "#
|
|
16910
|
-
/** Rectangle element color -
|
|
16911
|
-
rect: "#
|
|
16912
|
-
/** Frame effect color -
|
|
16913
|
-
frameEffect: "#
|
|
16914
|
-
/** Filters color -
|
|
16915
|
-
filters: "#
|
|
16916
|
-
/** Transition color -
|
|
16917
|
-
transition: "#
|
|
16918
|
-
/** Animation color -
|
|
16919
|
-
animation: "#
|
|
16941
|
+
/** Fragment element color - deep charcoal matching UI background */
|
|
16942
|
+
fragment: "#1A1A1A",
|
|
16943
|
+
/** Video element color - vibrant royal purple */
|
|
16944
|
+
video: "#8B5FBF",
|
|
16945
|
+
/** Caption element color - soft wisteria purple */
|
|
16946
|
+
caption: "#9B8ACE",
|
|
16947
|
+
/** Image element color - warm copper accent */
|
|
16948
|
+
image: "#D4956C",
|
|
16949
|
+
/** Audio element color - deep teal */
|
|
16950
|
+
audio: "#3D8B8B",
|
|
16951
|
+
/** Text element color - medium lavender */
|
|
16952
|
+
text: "#8D74C4",
|
|
16953
|
+
/** Generic element color - muted amethyst */
|
|
16954
|
+
element: "#7B68B8",
|
|
16955
|
+
/** Rectangle element color - deep indigo */
|
|
16956
|
+
rect: "#5B4B99",
|
|
16957
|
+
/** Frame effect color - rich magenta */
|
|
16958
|
+
frameEffect: "#B55B9C",
|
|
16959
|
+
/** Filters color - periwinkle blue */
|
|
16960
|
+
filters: "#7A89D4",
|
|
16961
|
+
/** Transition color - burnished bronze */
|
|
16962
|
+
transition: "#BE8157",
|
|
16963
|
+
/** Animation color - muted emerald */
|
|
16964
|
+
animation: "#4B9B78",
|
|
16965
|
+
/** Icon element color - bright orchid */
|
|
16966
|
+
icon: "#A76CD4",
|
|
16967
|
+
/** Circle element color - deep byzantium */
|
|
16968
|
+
circle: "#703D8B"
|
|
16920
16969
|
};
|
|
16921
16970
|
const AVAILABLE_TEXT_FONTS = {
|
|
16922
16971
|
// Google Fonts
|
|
@@ -16968,6 +17017,12 @@ const AVAILABLE_TEXT_FONTS = {
|
|
|
16968
17017
|
BRITTANY_SIGNATURE: "Brittany Signature"
|
|
16969
17018
|
};
|
|
16970
17019
|
let ELEMENT_COLORS = { ...DEFAULT_ELEMENT_COLORS };
|
|
17020
|
+
const setElementColors = (colors) => {
|
|
17021
|
+
ELEMENT_COLORS = {
|
|
17022
|
+
...DEFAULT_ELEMENT_COLORS,
|
|
17023
|
+
...colors
|
|
17024
|
+
};
|
|
17025
|
+
};
|
|
16971
17026
|
const TrackElementView = ({
|
|
16972
17027
|
element,
|
|
16973
17028
|
parentWidth,
|
|
@@ -17002,10 +17057,12 @@ const TrackElementView = ({
|
|
|
17002
17057
|
const span = prev.end - prev.start;
|
|
17003
17058
|
let newStart = Math.max(0, prev.start + dx / parentWidth * duration);
|
|
17004
17059
|
newStart = Math.min(newStart, prev.end - MIN_DURATION);
|
|
17005
|
-
if (
|
|
17006
|
-
newStart
|
|
17007
|
-
|
|
17008
|
-
|
|
17060
|
+
if (!allowOverlap) {
|
|
17061
|
+
if (prevEnd !== null && newStart < prevEnd) {
|
|
17062
|
+
newStart = prevEnd;
|
|
17063
|
+
} else if (nextStart !== null && !allowOverlap && newStart + span > nextStart) {
|
|
17064
|
+
newStart = nextStart - span;
|
|
17065
|
+
}
|
|
17009
17066
|
}
|
|
17010
17067
|
return {
|
|
17011
17068
|
start: newStart,
|
|
@@ -17046,8 +17103,10 @@ const TrackElementView = ({
|
|
|
17046
17103
|
setPosition((prev) => {
|
|
17047
17104
|
let newEnd = prev.end + dx / parentWidth * duration;
|
|
17048
17105
|
newEnd = Math.max(newEnd, prev.start + MIN_DURATION);
|
|
17049
|
-
if (
|
|
17050
|
-
newEnd
|
|
17106
|
+
if (!allowOverlap) {
|
|
17107
|
+
if (nextStart !== null && newEnd > nextStart) {
|
|
17108
|
+
newEnd = nextStart;
|
|
17109
|
+
}
|
|
17051
17110
|
}
|
|
17052
17111
|
return {
|
|
17053
17112
|
start: prev.start,
|
|
@@ -17084,11 +17143,19 @@ const TrackElementView = ({
|
|
|
17084
17143
|
const motionProps = {
|
|
17085
17144
|
ref,
|
|
17086
17145
|
className: `twick-track-element ${isSelected ? "twick-track-element-selected" : "twick-track-element-default"} ${isDragging2 ? "twick-track-element-dragging" : ""}`,
|
|
17087
|
-
onMouseDown:
|
|
17088
|
-
|
|
17146
|
+
onMouseDown: (e3) => {
|
|
17147
|
+
if (e3.target === ref.current) {
|
|
17148
|
+
setLastPos();
|
|
17149
|
+
}
|
|
17150
|
+
},
|
|
17151
|
+
onTouchStart: (e3) => {
|
|
17152
|
+
if (e3.target === ref.current) {
|
|
17153
|
+
setLastPos();
|
|
17154
|
+
}
|
|
17155
|
+
},
|
|
17089
17156
|
onMouseUp: sendUpdate,
|
|
17090
17157
|
onTouchEnd: sendUpdate,
|
|
17091
|
-
|
|
17158
|
+
onClick: () => {
|
|
17092
17159
|
if (onSelection) {
|
|
17093
17160
|
onSelection(element);
|
|
17094
17161
|
}
|
|
@@ -17104,7 +17171,7 @@ const TrackElementView = ({
|
|
|
17104
17171
|
isSelected ? /* @__PURE__ */ jsx(
|
|
17105
17172
|
"div",
|
|
17106
17173
|
{
|
|
17107
|
-
style: { touchAction: "none" },
|
|
17174
|
+
style: { touchAction: "none", zIndex: isSelected ? 100 : 1 },
|
|
17108
17175
|
...bindStartHandle(),
|
|
17109
17176
|
className: "twick-track-element-handle twick-track-element-handle-start"
|
|
17110
17177
|
}
|
|
@@ -17113,7 +17180,7 @@ const TrackElementView = ({
|
|
|
17113
17180
|
isSelected ? /* @__PURE__ */ jsx(
|
|
17114
17181
|
"div",
|
|
17115
17182
|
{
|
|
17116
|
-
style: { touchAction: "none" },
|
|
17183
|
+
style: { touchAction: "none", zIndex: isSelected ? 100 : 1 },
|
|
17117
17184
|
...bindEndHandle(),
|
|
17118
17185
|
className: "twick-track-element-handle twick-track-element-handle-end"
|
|
17119
17186
|
}
|
|
@@ -17165,7 +17232,7 @@ const TrackBase = ({
|
|
|
17165
17232
|
selectedItem,
|
|
17166
17233
|
onSelection: onItemSelection,
|
|
17167
17234
|
onDrag,
|
|
17168
|
-
nextStart: index < elements.length - 1 ? elements[index + 1].getStart() :
|
|
17235
|
+
nextStart: index < elements.length - 1 ? elements[index + 1].getStart() : null,
|
|
17169
17236
|
prevEnd: index > 0 ? elements[index - 1].getEnd() : 0
|
|
17170
17237
|
},
|
|
17171
17238
|
element.getId()
|
|
@@ -17179,6 +17246,7 @@ function TimelineView({
|
|
|
17179
17246
|
duration,
|
|
17180
17247
|
tracks,
|
|
17181
17248
|
seekTrack,
|
|
17249
|
+
onAddTrack,
|
|
17182
17250
|
onReorder,
|
|
17183
17251
|
onSelectionChange,
|
|
17184
17252
|
onElementDrag
|
|
@@ -17268,7 +17336,7 @@ function TimelineView({
|
|
|
17268
17336
|
onScroll: handleScroll,
|
|
17269
17337
|
children: [
|
|
17270
17338
|
/* @__PURE__ */ jsx("div", { style: { width: timelineWidthPx }, children: seekTrack ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", position: "relative" }, children: [
|
|
17271
|
-
/* @__PURE__ */ jsx("div", { className: "twick-seek-track-empty-space" }),
|
|
17339
|
+
/* @__PURE__ */ jsx("div", { className: "twick-seek-track-empty-space", onClick: onAddTrack, children: /* @__PURE__ */ jsx(Plus, { color: "white", size: 20 }) }),
|
|
17272
17340
|
/* @__PURE__ */ jsx("div", { style: { flexGrow: 1 }, children: seekTrack })
|
|
17273
17341
|
] }) : null }),
|
|
17274
17342
|
/* @__PURE__ */ jsx("div", { ref: timelineContentRef, style: { width: timelineWidthPx }, children: (tracks || []).map((track) => /* @__PURE__ */ jsxs("div", { className: "twick-timeline-container", children: [
|
|
@@ -17302,13 +17370,7 @@ function TimelineView({
|
|
|
17302
17370
|
);
|
|
17303
17371
|
}
|
|
17304
17372
|
const useTimelineManager = () => {
|
|
17305
|
-
const {
|
|
17306
|
-
selectedItem,
|
|
17307
|
-
changeLog,
|
|
17308
|
-
setSelectedItem,
|
|
17309
|
-
totalDuration,
|
|
17310
|
-
editor
|
|
17311
|
-
} = useTimelineContext();
|
|
17373
|
+
const { selectedItem, changeLog, setSelectedItem, totalDuration, editor } = useTimelineContext();
|
|
17312
17374
|
const onElementDrag = ({
|
|
17313
17375
|
element,
|
|
17314
17376
|
dragType,
|
|
@@ -17327,7 +17389,8 @@ const useTimelineManager = () => {
|
|
|
17327
17389
|
}
|
|
17328
17390
|
element.setStart(updates.start);
|
|
17329
17391
|
element.setEnd(updates.end);
|
|
17330
|
-
editor.updateElement(element);
|
|
17392
|
+
const updatedElement = editor.updateElement(element);
|
|
17393
|
+
setSelectedItem(updatedElement);
|
|
17331
17394
|
};
|
|
17332
17395
|
const timelineData = useMemo(() => {
|
|
17333
17396
|
const timelineDataFromEditor = editor.getTimelineData();
|
|
@@ -17344,8 +17407,14 @@ const useTimelineManager = () => {
|
|
|
17344
17407
|
const onSelectionChange = (selectedItem2) => {
|
|
17345
17408
|
setSelectedItem(selectedItem2);
|
|
17346
17409
|
};
|
|
17410
|
+
const onAddTrack = () => {
|
|
17411
|
+
var _a2;
|
|
17412
|
+
const tracks = ((_a2 = editor.getTimelineData()) == null ? void 0 : _a2.tracks) || [];
|
|
17413
|
+
editor.addTrack(`Track_${tracks.length + 1}`);
|
|
17414
|
+
};
|
|
17347
17415
|
return {
|
|
17348
17416
|
timelineData,
|
|
17417
|
+
onAddTrack,
|
|
17349
17418
|
onElementDrag,
|
|
17350
17419
|
onReorder,
|
|
17351
17420
|
onSeek,
|
|
@@ -17355,21 +17424,20 @@ const useTimelineManager = () => {
|
|
|
17355
17424
|
};
|
|
17356
17425
|
};
|
|
17357
17426
|
const TimelineManager = ({
|
|
17358
|
-
timelineControls,
|
|
17359
17427
|
trackZoom
|
|
17360
17428
|
}) => {
|
|
17361
17429
|
var _a2;
|
|
17362
|
-
const { timelineData, totalDuration, selectedItem, onReorder, onElementDrag, onSeek, onSelectionChange } = useTimelineManager();
|
|
17430
|
+
const { timelineData, totalDuration, selectedItem, onAddTrack, onReorder, onElementDrag, onSeek, onSelectionChange } = useTimelineManager();
|
|
17363
17431
|
return /* @__PURE__ */ jsx(
|
|
17364
17432
|
TimelineView,
|
|
17365
17433
|
{
|
|
17366
|
-
timelineControls,
|
|
17367
17434
|
tracks: (timelineData == null ? void 0 : timelineData.tracks) ?? [],
|
|
17368
17435
|
zoomLevel: trackZoom,
|
|
17369
17436
|
duration: totalDuration,
|
|
17370
17437
|
selectedItem,
|
|
17371
17438
|
onDeletion: () => {
|
|
17372
17439
|
},
|
|
17440
|
+
onAddTrack,
|
|
17373
17441
|
onReorder,
|
|
17374
17442
|
onElementDrag,
|
|
17375
17443
|
onSeek,
|
|
@@ -17408,6 +17476,9 @@ const UndoRedoControls = ({ canUndo, canRedo, onUndo, onRedo }) => {
|
|
|
17408
17476
|
)
|
|
17409
17477
|
] });
|
|
17410
17478
|
};
|
|
17479
|
+
const MAX_ZOOM = 3;
|
|
17480
|
+
const MIN_ZOOM = 0.5;
|
|
17481
|
+
const ZOOM_STEP = 0.25;
|
|
17411
17482
|
const PlayerControls = ({
|
|
17412
17483
|
selectedItem,
|
|
17413
17484
|
duration,
|
|
@@ -17420,6 +17491,8 @@ const PlayerControls = ({
|
|
|
17420
17491
|
onRedo,
|
|
17421
17492
|
onSplit,
|
|
17422
17493
|
onDelete,
|
|
17494
|
+
zoomLevel = 1,
|
|
17495
|
+
setZoomLevel,
|
|
17423
17496
|
className = ""
|
|
17424
17497
|
}) => {
|
|
17425
17498
|
const formatTime = useCallback((time2) => {
|
|
@@ -17437,61 +17510,92 @@ const PlayerControls = ({
|
|
|
17437
17510
|
onSplit(selectedItem, currentTime);
|
|
17438
17511
|
}
|
|
17439
17512
|
}, [selectedItem, onSplit, currentTime]);
|
|
17440
|
-
|
|
17441
|
-
|
|
17442
|
-
|
|
17443
|
-
|
|
17444
|
-
|
|
17445
|
-
|
|
17446
|
-
|
|
17447
|
-
|
|
17448
|
-
|
|
17449
|
-
|
|
17450
|
-
|
|
17451
|
-
|
|
17452
|
-
|
|
17453
|
-
|
|
17454
|
-
|
|
17455
|
-
|
|
17456
|
-
|
|
17457
|
-
|
|
17458
|
-
|
|
17459
|
-
|
|
17460
|
-
|
|
17461
|
-
|
|
17462
|
-
|
|
17463
|
-
|
|
17464
|
-
|
|
17465
|
-
|
|
17466
|
-
|
|
17467
|
-
|
|
17468
|
-
|
|
17469
|
-
|
|
17470
|
-
|
|
17471
|
-
|
|
17472
|
-
|
|
17473
|
-
|
|
17474
|
-
|
|
17475
|
-
|
|
17476
|
-
|
|
17477
|
-
|
|
17478
|
-
|
|
17479
|
-
|
|
17480
|
-
|
|
17481
|
-
|
|
17482
|
-
|
|
17483
|
-
|
|
17484
|
-
|
|
17485
|
-
|
|
17486
|
-
|
|
17487
|
-
|
|
17488
|
-
|
|
17489
|
-
|
|
17490
|
-
|
|
17491
|
-
|
|
17492
|
-
|
|
17493
|
-
|
|
17494
|
-
|
|
17513
|
+
const handleZoomIn = useCallback(() => {
|
|
17514
|
+
if (setZoomLevel && zoomLevel < MAX_ZOOM) {
|
|
17515
|
+
setZoomLevel(zoomLevel + ZOOM_STEP);
|
|
17516
|
+
}
|
|
17517
|
+
}, [zoomLevel, setZoomLevel]);
|
|
17518
|
+
const handleZoomOut = useCallback(() => {
|
|
17519
|
+
if (setZoomLevel && zoomLevel > MIN_ZOOM) {
|
|
17520
|
+
setZoomLevel(zoomLevel - ZOOM_STEP);
|
|
17521
|
+
}
|
|
17522
|
+
}, [zoomLevel, setZoomLevel]);
|
|
17523
|
+
return /* @__PURE__ */ jsx("div", { className: `h-16 bg-gray-800 border-t border-gray-700 p-4 ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
17524
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
17525
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
17526
|
+
/* @__PURE__ */ jsx(
|
|
17527
|
+
"button",
|
|
17528
|
+
{
|
|
17529
|
+
onClick: handleDelete,
|
|
17530
|
+
disabled: !selectedItem,
|
|
17531
|
+
title: "Delete",
|
|
17532
|
+
className: `btn btn-ghost ${!!selectedItem ? "text-red-400 hover:text-red-300" : "text-gray-500 cursor-not-allowed"}`,
|
|
17533
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "w-5 h-5" })
|
|
17534
|
+
}
|
|
17535
|
+
),
|
|
17536
|
+
/* @__PURE__ */ jsx(
|
|
17537
|
+
"button",
|
|
17538
|
+
{
|
|
17539
|
+
onClick: handleSplit,
|
|
17540
|
+
disabled: !(selectedItem instanceof TrackElement),
|
|
17541
|
+
title: "Split",
|
|
17542
|
+
className: `btn btn-ghost ${selectedItem instanceof TrackElement ? "text-purple-400 hover:text-purple-300" : "text-gray-500 cursor-not-allowed"}`,
|
|
17543
|
+
children: /* @__PURE__ */ jsx(Scissors, { className: "w-5 h-5" })
|
|
17544
|
+
}
|
|
17545
|
+
),
|
|
17546
|
+
/* @__PURE__ */ jsx(
|
|
17547
|
+
UndoRedoControls,
|
|
17548
|
+
{
|
|
17549
|
+
canUndo,
|
|
17550
|
+
canRedo,
|
|
17551
|
+
onUndo,
|
|
17552
|
+
onRedo
|
|
17553
|
+
}
|
|
17554
|
+
)
|
|
17555
|
+
] }),
|
|
17556
|
+
/* @__PURE__ */ jsx(
|
|
17557
|
+
"button",
|
|
17558
|
+
{
|
|
17559
|
+
onClick: togglePlayback,
|
|
17560
|
+
disabled: playerState === PLAYER_STATE.REFRESH,
|
|
17561
|
+
title: playerState === PLAYER_STATE.PLAYING ? "Pause" : playerState === PLAYER_STATE.REFRESH ? "Refreshing" : "Play",
|
|
17562
|
+
className: "btn btn-ghost text-white",
|
|
17563
|
+
children: playerState === PLAYER_STATE.PLAYING ? /* @__PURE__ */ jsx(Pause, { className: "w-6 h-6" }) : playerState === PLAYER_STATE.REFRESH ? /* @__PURE__ */ jsx(LoaderCircle, { className: "w-6 h-6 animate-spin" }) : /* @__PURE__ */ jsx(Play, { className: "w-6 h-6" })
|
|
17564
|
+
}
|
|
17565
|
+
),
|
|
17566
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-gray-300", children: [
|
|
17567
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: formatTime(currentTime) }),
|
|
17568
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-500", children: "/" }),
|
|
17569
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: formatTime(duration) })
|
|
17570
|
+
] })
|
|
17571
|
+
] }),
|
|
17572
|
+
setZoomLevel && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
17573
|
+
/* @__PURE__ */ jsx(
|
|
17574
|
+
"button",
|
|
17575
|
+
{
|
|
17576
|
+
onClick: handleZoomOut,
|
|
17577
|
+
disabled: zoomLevel <= MIN_ZOOM,
|
|
17578
|
+
title: "Zoom Out",
|
|
17579
|
+
className: `btn btn-ghost ${zoomLevel > MIN_ZOOM ? "text-gray-300 hover:text-white" : "text-gray-500 cursor-not-allowed"}`,
|
|
17580
|
+
children: /* @__PURE__ */ jsx(ZoomOut, { className: "w-5 h-5" })
|
|
17581
|
+
}
|
|
17582
|
+
),
|
|
17583
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-gray-300 font-medium min-w-[3rem] text-center", children: [
|
|
17584
|
+
Math.round(zoomLevel * 100),
|
|
17585
|
+
"%"
|
|
17586
|
+
] }),
|
|
17587
|
+
/* @__PURE__ */ jsx(
|
|
17588
|
+
"button",
|
|
17589
|
+
{
|
|
17590
|
+
onClick: handleZoomIn,
|
|
17591
|
+
disabled: zoomLevel >= MAX_ZOOM,
|
|
17592
|
+
title: "Zoom In",
|
|
17593
|
+
className: `btn btn-ghost ${zoomLevel < MAX_ZOOM ? "text-gray-300 hover:text-white" : "text-gray-500 cursor-not-allowed"}`,
|
|
17594
|
+
children: /* @__PURE__ */ jsx(ZoomIn, { className: "w-5 h-5" })
|
|
17595
|
+
}
|
|
17596
|
+
)
|
|
17597
|
+
] })
|
|
17598
|
+
] }) });
|
|
17495
17599
|
};
|
|
17496
17600
|
const usePlayerControl = () => {
|
|
17497
17601
|
const { playerState, setPlayerState } = useLivePlayerContext();
|
|
@@ -17519,59 +17623,15 @@ const usePlayerControl = () => {
|
|
|
17519
17623
|
togglePlayback
|
|
17520
17624
|
};
|
|
17521
17625
|
};
|
|
17522
|
-
const MAX_ZOOM = 3;
|
|
17523
|
-
const MIN_ZOOM = 0.5;
|
|
17524
|
-
const ZOOM_STEP = 0.25;
|
|
17525
|
-
const TimelineZoom = ({
|
|
17526
|
-
zoomLevel,
|
|
17527
|
-
setZoomLevel,
|
|
17528
|
-
minZoom = MIN_ZOOM,
|
|
17529
|
-
maxZoom = MAX_ZOOM,
|
|
17530
|
-
zoomStep = ZOOM_STEP
|
|
17531
|
-
}) => {
|
|
17532
|
-
const handleZoomIn = () => {
|
|
17533
|
-
if (zoomLevel < maxZoom) {
|
|
17534
|
-
setZoomLevel(zoomLevel + zoomStep);
|
|
17535
|
-
}
|
|
17536
|
-
};
|
|
17537
|
-
const handleZoomOut = () => {
|
|
17538
|
-
if (zoomLevel > minZoom) {
|
|
17539
|
-
setZoomLevel(zoomLevel - zoomStep);
|
|
17540
|
-
}
|
|
17541
|
-
};
|
|
17542
|
-
return /* @__PURE__ */ jsxs("div", { className: "twick-track-zoom-container", children: [
|
|
17543
|
-
/* @__PURE__ */ jsx(ZoomOut, { size: 28, onClick: handleZoomOut }),
|
|
17544
|
-
/* @__PURE__ */ jsxs("div", { className: "twick-zoom-slider", children: [
|
|
17545
|
-
/* @__PURE__ */ jsx(
|
|
17546
|
-
"div",
|
|
17547
|
-
{
|
|
17548
|
-
className: "twick-zoom-slider-track",
|
|
17549
|
-
style: {
|
|
17550
|
-
width: `${(zoomLevel - minZoom) / (maxZoom - minZoom) * 100}%`
|
|
17551
|
-
}
|
|
17552
|
-
}
|
|
17553
|
-
),
|
|
17554
|
-
/* @__PURE__ */ jsx(
|
|
17555
|
-
"div",
|
|
17556
|
-
{
|
|
17557
|
-
className: "twick-zoom-slider-thumb",
|
|
17558
|
-
style: {
|
|
17559
|
-
left: `calc(${(zoomLevel - minZoom) / (maxZoom - minZoom) * 100}%)`
|
|
17560
|
-
}
|
|
17561
|
-
}
|
|
17562
|
-
)
|
|
17563
|
-
] }),
|
|
17564
|
-
/* @__PURE__ */ jsx(ZoomIn, { size: 28, onClick: handleZoomIn })
|
|
17565
|
-
] });
|
|
17566
|
-
};
|
|
17567
17626
|
const useTimelineControl = () => {
|
|
17568
|
-
const { editor } = useTimelineContext();
|
|
17627
|
+
const { editor, setSelectedItem } = useTimelineContext();
|
|
17569
17628
|
const deleteItem = (item) => {
|
|
17570
17629
|
if (item instanceof Track) {
|
|
17571
17630
|
editor.removeTrack(item);
|
|
17572
17631
|
} else if (item instanceof TrackElement) {
|
|
17573
17632
|
editor.removeElement(item);
|
|
17574
17633
|
}
|
|
17634
|
+
setSelectedItem(null);
|
|
17575
17635
|
};
|
|
17576
17636
|
const splitElement = (element, currentTime) => {
|
|
17577
17637
|
editor.splitElement(element, currentTime);
|
|
@@ -17597,56 +17657,54 @@ const ControlManager = ({
|
|
|
17597
17657
|
const { togglePlayback } = usePlayerControl();
|
|
17598
17658
|
const { canRedo, canUndo, totalDuration, selectedItem } = useTimelineContext();
|
|
17599
17659
|
const { deleteItem, splitElement, handleUndo, handleRedo } = useTimelineControl();
|
|
17600
|
-
return /* @__PURE__ */
|
|
17601
|
-
|
|
17602
|
-
|
|
17603
|
-
|
|
17604
|
-
|
|
17605
|
-
|
|
17606
|
-
|
|
17607
|
-
|
|
17608
|
-
|
|
17609
|
-
|
|
17610
|
-
|
|
17611
|
-
|
|
17612
|
-
|
|
17613
|
-
|
|
17614
|
-
|
|
17615
|
-
|
|
17616
|
-
|
|
17617
|
-
|
|
17618
|
-
] });
|
|
17660
|
+
return /* @__PURE__ */ jsx("div", { className: "twick-editor-timeline-controls", children: /* @__PURE__ */ jsx(
|
|
17661
|
+
PlayerControls,
|
|
17662
|
+
{
|
|
17663
|
+
selectedItem,
|
|
17664
|
+
duration: totalDuration,
|
|
17665
|
+
currentTime,
|
|
17666
|
+
playerState,
|
|
17667
|
+
togglePlayback,
|
|
17668
|
+
canUndo,
|
|
17669
|
+
canRedo,
|
|
17670
|
+
onDelete: deleteItem,
|
|
17671
|
+
onSplit: splitElement,
|
|
17672
|
+
onUndo: handleUndo,
|
|
17673
|
+
onRedo: handleRedo,
|
|
17674
|
+
zoomLevel: trackZoom,
|
|
17675
|
+
setZoomLevel: setTrackZoom
|
|
17676
|
+
}
|
|
17677
|
+
) });
|
|
17619
17678
|
};
|
|
17620
17679
|
const VideoEditor = ({
|
|
17621
17680
|
leftPanel,
|
|
17622
17681
|
rightPanel,
|
|
17623
17682
|
bottomPanel,
|
|
17624
17683
|
editorConfig,
|
|
17625
|
-
playControls,
|
|
17626
17684
|
defaultPlayControls = true
|
|
17627
17685
|
}) => {
|
|
17628
17686
|
const [trackZoom, setTrackZoom] = useState(DEFAULT_TIMELINE_ZOOM);
|
|
17687
|
+
const useMemoizedPlayerManager = useMemo(
|
|
17688
|
+
() => /* @__PURE__ */ jsx(
|
|
17689
|
+
PlayerManager,
|
|
17690
|
+
{
|
|
17691
|
+
videoProps: editorConfig.videoProps,
|
|
17692
|
+
playerProps: editorConfig.playerProps,
|
|
17693
|
+
canvasMode: editorConfig.canvasMode ?? true
|
|
17694
|
+
}
|
|
17695
|
+
),
|
|
17696
|
+
[editorConfig]
|
|
17697
|
+
);
|
|
17629
17698
|
return /* @__PURE__ */ jsxs("div", { className: "twick-editor-main-container", children: [
|
|
17630
17699
|
/* @__PURE__ */ jsxs("div", { className: "twick-editor-view-section", children: [
|
|
17631
17700
|
leftPanel ? leftPanel : /* @__PURE__ */ jsx("div", {}),
|
|
17632
|
-
|
|
17633
|
-
PlayerManager,
|
|
17634
|
-
{
|
|
17635
|
-
videoProps: editorConfig.videoProps,
|
|
17636
|
-
canvasMode: editorConfig.canvasMode ?? true
|
|
17637
|
-
}
|
|
17638
|
-
),
|
|
17701
|
+
useMemoizedPlayerManager,
|
|
17639
17702
|
rightPanel ? rightPanel : /* @__PURE__ */ jsx("div", {})
|
|
17640
17703
|
] }),
|
|
17641
17704
|
bottomPanel ? bottomPanel : null,
|
|
17642
17705
|
/* @__PURE__ */ jsxs("div", { className: "twick-editor-timeline-section", children: [
|
|
17643
|
-
|
|
17644
|
-
/* @__PURE__ */ jsx(
|
|
17645
|
-
TimelineManager,
|
|
17646
|
-
{
|
|
17647
|
-
trackZoom
|
|
17648
|
-
}
|
|
17649
|
-
)
|
|
17706
|
+
defaultPlayControls ? /* @__PURE__ */ jsx(ControlManager, { trackZoom, setTrackZoom }) : null,
|
|
17707
|
+
/* @__PURE__ */ jsx(TimelineManager, { trackZoom })
|
|
17650
17708
|
] })
|
|
17651
17709
|
] });
|
|
17652
17710
|
};
|
|
@@ -17817,7 +17875,7 @@ class BrowserMediaManager extends BaseMediaManager {
|
|
|
17817
17875
|
request.onsuccess = async () => {
|
|
17818
17876
|
let items = request.result;
|
|
17819
17877
|
const filteredItems = items.filter((item) => {
|
|
17820
|
-
const matchesQuery = item.url.toLowerCase().includes(options.query.toLowerCase());
|
|
17878
|
+
const matchesQuery = item.url.toLowerCase().includes((options.query || "").toLowerCase());
|
|
17821
17879
|
const matchesType = !options.type || item.type === options.type;
|
|
17822
17880
|
const matchesMetadata = !options.metadata || Object.entries(options.metadata).every(
|
|
17823
17881
|
([key, value]) => {
|
|
@@ -17871,9 +17929,14 @@ const ANIMATIONS = [
|
|
|
17871
17929
|
{
|
|
17872
17930
|
name: "fade",
|
|
17873
17931
|
interval: 1,
|
|
17932
|
+
duration: 1,
|
|
17933
|
+
intensity: 1,
|
|
17874
17934
|
animate: "enter",
|
|
17875
17935
|
options: {
|
|
17876
|
-
animate: ["enter", "exit", "both"]
|
|
17936
|
+
animate: ["enter", "exit", "both"],
|
|
17937
|
+
interval: [0.1, 5],
|
|
17938
|
+
duration: [0.1, 5],
|
|
17939
|
+
intensity: [0.1, 2]
|
|
17877
17940
|
},
|
|
17878
17941
|
getSample: () => {
|
|
17879
17942
|
return animationGifs.fade;
|
|
@@ -17882,11 +17945,16 @@ const ANIMATIONS = [
|
|
|
17882
17945
|
{
|
|
17883
17946
|
name: "rise",
|
|
17884
17947
|
interval: 1,
|
|
17948
|
+
duration: 1,
|
|
17949
|
+
intensity: 1,
|
|
17885
17950
|
animate: "enter",
|
|
17886
17951
|
direction: "up",
|
|
17887
17952
|
options: {
|
|
17888
17953
|
animate: ["enter", "exit", "both"],
|
|
17889
|
-
direction: ["up", "down"]
|
|
17954
|
+
direction: ["up", "down", "left", "right", "center"],
|
|
17955
|
+
interval: [0.1, 5],
|
|
17956
|
+
duration: [0.1, 5],
|
|
17957
|
+
intensity: [1, 300]
|
|
17890
17958
|
},
|
|
17891
17959
|
getSample: (animation) => {
|
|
17892
17960
|
return (animation == null ? void 0 : animation.direction) === "down" ? animationGifs["rise-down"] : animationGifs["rise-up"];
|
|
@@ -17895,9 +17963,14 @@ const ANIMATIONS = [
|
|
|
17895
17963
|
{
|
|
17896
17964
|
name: "blur",
|
|
17897
17965
|
interval: 1,
|
|
17966
|
+
duration: 1,
|
|
17967
|
+
intensity: 1,
|
|
17898
17968
|
animate: "enter",
|
|
17899
17969
|
options: {
|
|
17900
|
-
animate: ["enter", "exit", "both"]
|
|
17970
|
+
animate: ["enter", "exit", "both"],
|
|
17971
|
+
interval: [0.1, 5],
|
|
17972
|
+
duration: [0.1, 5],
|
|
17973
|
+
intensity: [0.1, 100]
|
|
17901
17974
|
},
|
|
17902
17975
|
getSample: () => {
|
|
17903
17976
|
return animationGifs.blur;
|
|
@@ -17906,11 +17979,16 @@ const ANIMATIONS = [
|
|
|
17906
17979
|
{
|
|
17907
17980
|
name: "breathe",
|
|
17908
17981
|
interval: 1,
|
|
17982
|
+
duration: 1,
|
|
17983
|
+
intensity: 1,
|
|
17909
17984
|
mode: "in",
|
|
17910
17985
|
animate: "enter",
|
|
17911
17986
|
options: {
|
|
17912
17987
|
animate: ["enter", "exit", "both"],
|
|
17913
|
-
mode: ["in", "out"]
|
|
17988
|
+
mode: ["in", "out"],
|
|
17989
|
+
interval: [0.1, 5],
|
|
17990
|
+
duration: [0.1, 5],
|
|
17991
|
+
intensity: [0.1, 2]
|
|
17914
17992
|
},
|
|
17915
17993
|
getSample: (animation) => {
|
|
17916
17994
|
return (animation == null ? void 0 : animation.mode) === "out" ? animationGifs["breathe-out"] : animationGifs["breathe-in"];
|
|
@@ -17919,9 +17997,14 @@ const ANIMATIONS = [
|
|
|
17919
17997
|
{
|
|
17920
17998
|
name: "succession",
|
|
17921
17999
|
interval: 1,
|
|
18000
|
+
duration: 1,
|
|
18001
|
+
intensity: 1,
|
|
17922
18002
|
animate: "enter",
|
|
17923
18003
|
options: {
|
|
17924
|
-
animate: ["enter", "exit", "both"]
|
|
18004
|
+
animate: ["enter", "exit", "both"],
|
|
18005
|
+
interval: [0.1, 5],
|
|
18006
|
+
duration: [0.1, 5],
|
|
18007
|
+
intensity: [0.1, 2]
|
|
17925
18008
|
},
|
|
17926
18009
|
getSample: () => {
|
|
17927
18010
|
return animationGifs.succession;
|
|
@@ -17932,6 +18015,7 @@ const TEXT_EFFECTS = [
|
|
|
17932
18015
|
{
|
|
17933
18016
|
name: "typewriter",
|
|
17934
18017
|
delay: 0,
|
|
18018
|
+
duration: 1,
|
|
17935
18019
|
bufferTime: 0.1,
|
|
17936
18020
|
getSample: () => {
|
|
17937
18021
|
return "";
|
|
@@ -17940,6 +18024,7 @@ const TEXT_EFFECTS = [
|
|
|
17940
18024
|
{
|
|
17941
18025
|
name: "erase",
|
|
17942
18026
|
delay: 0,
|
|
18027
|
+
duration: 1,
|
|
17943
18028
|
bufferTime: 0.1,
|
|
17944
18029
|
getSample: () => {
|
|
17945
18030
|
return "";
|
|
@@ -17948,6 +18033,7 @@ const TEXT_EFFECTS = [
|
|
|
17948
18033
|
{
|
|
17949
18034
|
name: "elastic",
|
|
17950
18035
|
delay: 0,
|
|
18036
|
+
duration: 1,
|
|
17951
18037
|
bufferTime: 0.1,
|
|
17952
18038
|
getSample: () => {
|
|
17953
18039
|
return "";
|
|
@@ -17956,6 +18042,7 @@ const TEXT_EFFECTS = [
|
|
|
17956
18042
|
{
|
|
17957
18043
|
name: "stream-word",
|
|
17958
18044
|
delay: 0,
|
|
18045
|
+
duration: 1,
|
|
17959
18046
|
bufferTime: 0.1,
|
|
17960
18047
|
getSample: () => {
|
|
17961
18048
|
return "";
|
|
@@ -17978,6 +18065,7 @@ export {
|
|
|
17978
18065
|
animationGifs,
|
|
17979
18066
|
VideoEditor as default,
|
|
17980
18067
|
getAnimationGif,
|
|
18068
|
+
setElementColors,
|
|
17981
18069
|
usePlayerControl,
|
|
17982
18070
|
useTimelineControl
|
|
17983
18071
|
};
|