@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/index.js CHANGED
@@ -6936,10 +6936,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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
- if (!canvas) return;
6941
- canvas.clear();
6942
- canvas.renderAll();
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6985
6994
  ctx.save();
6986
6995
  ctx.translate(left, top);
6987
6996
  ctx.fillStyle = "#red";
6988
- ctx.fillRect(-0 / 2, -0 / 2, size, size);
6997
+ ctx.fillRect(-size / 2, -size / 2, size, size);
6989
6998
  ctx.restore();
6990
6999
  }
6991
7000
  });
@@ -7085,7 +7094,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7085
7094
  timeoutId = window.setTimeout(() => {
7086
7095
  cleanup();
7087
7096
  reject(new Error("Video loading timed out"));
7088
- }, 5e3);
7097
+ }, 15e3);
7089
7098
  video.src = videoUrl;
7090
7099
  document.body.appendChild(video);
7091
7100
  });
@@ -7136,7 +7145,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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: ((_j = element.props) == null ? void 0 : _j.textAlign) || "center",
7160
- stroke: ((_k = element.props) == null ? void 0 : _k.stroke) || DEFAULT_TEXT_PROPS.stroke,
7161
- strokeWidth: ((_l = element.props) == null ? void 0 : _l.lineWidth) || DEFAULT_TEXT_PROPS.lineWidth,
7162
- shadow: ((_m = element.props) == null ? void 0 : _m.shadowColor) ? new ds({
7163
- offsetX: ((_o2 = (_n2 = element.props) == null ? void 0 : _n2.shadowOffset) == null ? void 0 : _o2.length) && ((_q = (_p = element.props) == null ? void 0 : _p.shadowOffset) == null ? void 0 : _q.length) > 1 ? element.props.shadowOffset[0] / 2 : 1,
7164
- offsetY: ((_s2 = (_r2 = element.props) == null ? void 0 : _r2.shadowOffset) == null ? void 0 : _s2.length) && ((_t2 = element.props) == null ? void 0 : _t2.shadowOffset.length) > 1 ? element.props.shadowOffset[1] / 2 : 1,
7165
- blur: (((_u = element.props) == null ? void 0 : _u.shadowBlur) || 2) / 2,
7166
- color: (_v = element.props) == null ? void 0 : _v.shadowColor
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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: ((_s2 = (_r2 = element.props) == null ? void 0 : _r2.shadowOffset) == null ? void 0 : _s2[0]) || ((_t2 = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _t2[0]),
7236
- offsetY: ((_v = (_u = element.props) == null ? void 0 : _u.shadowOffset) == null ? void 0 : _v[1]) || ((_w = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _w[1]),
7237
- blur: ((_x = element.props) == null ? void 0 : _x.shadowBlur) || DEFAULT_CAPTION_PROPS.shadowBlur,
7238
- color: ((_y = element.props) == null ? void 0 : _y.shadowColor) || DEFAULT_CAPTION_PROPS.shadowColor
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: ((_z = element.props) == null ? void 0 : _z.lineWidth) || DEFAULT_CAPTION_PROPS.lineWidth
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7503
7516
  const elementFrameMap = React.useRef({});
7504
7517
  const twickCanvasRef = React.useRef(null);
7505
7518
  const videoSizeRef = React.useRef({ width: 1, height: 1 });
7519
+ const canvasResolutionRef = React.useRef({ width: 1, height: 1 });
7506
7520
  const canvasMetadataRef = React.useRef({
7507
7521
  width: 0,
7508
7522
  height: 0,
@@ -7526,9 +7540,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7813
7837
  videoProps
7814
7838
  }) => {
7815
7839
  const [projectData, setProjectData] = React.useState(null);
7816
- const { timelineAction, setTimelineAction, setSelectedItem, editor } = timeline.useTimelineContext();
7840
+ const { timelineAction, setTimelineAction, setSelectedItem, editor, changeLog } = timeline.useTimelineContext();
7841
+ const currentChangeLog = React.useRef(changeLog);
7817
7842
  const [playerUpdating, setPlayerUpdating] = React.useState(false);
7818
7843
  const handleCanvasReady = (canvas) => {
7819
7844
  console.log("canvas ready", canvas);
@@ -7826,7 +7851,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7837
7864
  });
7838
7865
  const updateCanvas = (seekTime) => {
7839
7866
  var _a2;
7867
+ if (changeLog === currentChangeLog.current) {
7868
+ return;
7869
+ }
7840
7870
  const elements = timeline.getCurrentElements(
7841
7871
  seekTime,
7842
7872
  ((_a2 = editor.getTimelineData()) == null ? void 0 : _a2.tracks) ?? []
@@ -7847,6 +7877,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7888
7919
  };
7889
7920
  const PlayerManager = ({
7890
7921
  videoProps,
7922
+ playerProps,
7891
7923
  canvasMode
7892
7924
  }) => {
7893
7925
  const { changeLog } = timeline.useTimelineContext();
@@ -7909,6 +7941,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
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 @@ This message will only show in development mode. It won't appear in production.
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$a = [
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 @@ This message will only show in development mode. It won't appear in production.
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$a);
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$9 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
9587
- const LoaderCircle = createLucideIcon("loader-circle", __iconNode$9);
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$8 = [
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$8);
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$7 = [
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$7);
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$6 = [["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]];
9617
- const Play = createLucideIcon("play", __iconNode$6);
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 @@ This message will only show in development mode. It won't appear in production.
12511
12556
  envelope = (undampedFreq2) => {
12512
12557
  const a2 = Math.exp(-undampedFreq2 * duration);
12513
12558
  const b2 = (undampedFreq2 - velocity) * duration + 1;
12514
- return -1e-3 + a2 * b2;
12559
+ return -safeMin + a2 * b2;
12515
12560
  };
12516
12561
  derivative = (undampedFreq2) => {
12517
12562
  const a2 = Math.exp(-undampedFreq2 * duration);
@@ -16893,30 +16938,34 @@ This message will only show in development mode. It won't appear in production.
16893
16938
  };
16894
16939
  const DEFAULT_TIMELINE_ZOOM = 1.5;
16895
16940
  const DEFAULT_ELEMENT_COLORS = {
16896
- /** Fragment element color */
16897
- fragment: "#111111",
16898
- /** Video element color - muted deep violet */
16899
- video: "#4B2E83",
16900
- /** Caption element color - faded violet/blue */
16901
- caption: "#5C5470",
16902
- /** Image element color - earthy brown-orange */
16903
- image: "#805A38",
16904
- /** Audio element color - dark muted teal-green */
16905
- audio: "#3C665B",
16906
- /** Text element color - dusty steel blue */
16907
- text: "#375A7F",
16908
- /** Generic element color - muted berry purple */
16909
- element: "#6B3A5B",
16910
- /** Rectangle element color - desaturated deep indigo */
16911
- rect: "#4C3A72",
16912
- /** Frame effect color - dusty rose/maroon */
16913
- frameEffect: "#703C57",
16914
- /** Filters color - muted twilight purple */
16915
- filters: "#5A4C82",
16916
- /** Transition color - toasted copper */
16917
- transition: "#7A573A",
16918
- /** Animation color - slate pine green */
16919
- animation: "#32645C"
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 (prevEnd !== null && !allowOverlap && newStart < prevEnd) {
17006
- newStart = prevEnd;
17007
- } else if (nextStart !== null && !allowOverlap && newStart + span > nextStart) {
17008
- newStart = nextStart - span;
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 @@ This message will only show in development mode. It won't appear in production.
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 (nextStart !== null && !allowOverlap && newEnd > nextStart) {
17050
- newEnd = nextStart;
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 @@ This message will only show in development mode. It won't appear in production.
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: setLastPos,
17088
- onTouchStart: setLastPos,
17146
+ onMouseDown: (e2) => {
17147
+ if (e2.target === ref.current) {
17148
+ setLastPos();
17149
+ }
17150
+ },
17151
+ onTouchStart: (e2) => {
17152
+ if (e2.target === ref.current) {
17153
+ setLastPos();
17154
+ }
17155
+ },
17089
17156
  onMouseUp: sendUpdate,
17090
17157
  onTouchEnd: sendUpdate,
17091
- onDoubleClick: () => {
17158
+ onClick: () => {
17092
17159
  if (onSelection) {
17093
17160
  onSelection(element);
17094
17161
  }
@@ -17104,7 +17171,7 @@ This message will only show in development mode. It won't appear in production.
17104
17171
  isSelected ? /* @__PURE__ */ jsxRuntime.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 @@ This message will only show in development mode. It won't appear in production.
17113
17180
  isSelected ? /* @__PURE__ */ jsxRuntime.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 @@ This message will only show in development mode. It won't appear in production.
17165
17232
  selectedItem,
17166
17233
  onSelection: onItemSelection,
17167
17234
  onDrag,
17168
- nextStart: index < elements.length - 1 ? elements[index + 1].getStart() : duration,
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 @@ This message will only show in development mode. It won't appear in production.
17179
17246
  duration,
17180
17247
  tracks,
17181
17248
  seekTrack,
17249
+ onAddTrack,
17182
17250
  onReorder,
17183
17251
  onSelectionChange,
17184
17252
  onElementDrag
@@ -17268,7 +17336,7 @@ This message will only show in development mode. It won't appear in production.
17268
17336
  onScroll: handleScroll,
17269
17337
  children: [
17270
17338
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: timelineWidthPx }, children: seekTrack ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", position: "relative" }, children: [
17271
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-seek-track-empty-space" }),
17339
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-seek-track-empty-space", onClick: onAddTrack, children: /* @__PURE__ */ jsxRuntime.jsx(Plus, { color: "white", size: 20 }) }),
17272
17340
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexGrow: 1 }, children: seekTrack })
17273
17341
  ] }) : null }),
17274
17342
  /* @__PURE__ */ jsxRuntime.jsx("div", { ref: timelineContentRef, style: { width: timelineWidthPx }, children: (tracks || []).map((track) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-timeline-container", children: [
@@ -17302,13 +17370,7 @@ This message will only show in development mode. It won't appear in production.
17302
17370
  );
17303
17371
  }
17304
17372
  const useTimelineManager = () => {
17305
- const {
17306
- selectedItem,
17307
- changeLog,
17308
- setSelectedItem,
17309
- totalDuration,
17310
- editor
17311
- } = timeline.useTimelineContext();
17373
+ const { selectedItem, changeLog, setSelectedItem, totalDuration, editor } = timeline.useTimelineContext();
17312
17374
  const onElementDrag = ({
17313
17375
  element,
17314
17376
  dragType,
@@ -17327,7 +17389,8 @@ This message will only show in development mode. It won't appear in production.
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 = React.useMemo(() => {
17333
17396
  const timelineDataFromEditor = editor.getTimelineData();
@@ -17344,8 +17407,14 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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__ */ jsxRuntime.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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
17420
17491
  onRedo,
17421
17492
  onSplit,
17422
17493
  onDelete,
17494
+ zoomLevel = 1,
17495
+ setZoomLevel,
17423
17496
  className = ""
17424
17497
  }) => {
17425
17498
  const formatTime = React.useCallback((time2) => {
@@ -17437,61 +17510,92 @@ This message will only show in development mode. It won't appear in production.
17437
17510
  onSplit(selectedItem, currentTime);
17438
17511
  }
17439
17512
  }, [selectedItem, onSplit, currentTime]);
17440
- return /* @__PURE__ */ jsxRuntime.jsxs(
17441
- "div",
17442
- {
17443
- className: `player-controls player-controls-card-vertical ${className}`,
17444
- children: [
17445
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "edit-controls player-controls-edit-controls", children: [
17446
- /* @__PURE__ */ jsxRuntime.jsx(
17447
- "button",
17448
- {
17449
- className: `control-btn delete-btn player-controls-delete-btn${!!selectedItem ? " active" : " btn-disabled"}`,
17450
- onClick: handleDelete,
17451
- disabled: !selectedItem,
17452
- title: "Delete",
17453
- children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 18, strokeWidth: 2 })
17454
- }
17455
- ),
17456
- /* @__PURE__ */ jsxRuntime.jsx(
17457
- "button",
17458
- {
17459
- className: `control-btn split-btn player-controls-split-btn${selectedItem instanceof timeline.TrackElement ? " active" : " btn-disabled"}`,
17460
- onClick: handleSplit,
17461
- title: "Split",
17462
- children: /* @__PURE__ */ jsxRuntime.jsx(Scissors, { size: 18, strokeWidth: 2 })
17463
- }
17464
- ),
17465
- /* @__PURE__ */ jsxRuntime.jsx(
17466
- UndoRedoControls,
17467
- {
17468
- canUndo,
17469
- canRedo,
17470
- onUndo,
17471
- onRedo
17472
- }
17473
- )
17474
- ] }),
17475
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "playback-controls player-controls-playback-controls", children: [
17476
- /* @__PURE__ */ jsxRuntime.jsx(
17477
- "button",
17478
- {
17479
- className: `control-btn play-pause-btn player-controls-play-pause-btn${playerState === livePlayer.PLAYER_STATE.PLAYING ? " playing" : ""}${playerState === livePlayer.PLAYER_STATE.REFRESH ? " refreshing" : ""}`,
17480
- onClick: togglePlayback,
17481
- title: playerState === livePlayer.PLAYER_STATE.PLAYING ? "Pause" : playerState === livePlayer.PLAYER_STATE.REFRESH ? "Refreshing" : "Play",
17482
- disabled: playerState === livePlayer.PLAYER_STATE.REFRESH,
17483
- children: playerState === livePlayer.PLAYER_STATE.PLAYING ? /* @__PURE__ */ jsxRuntime.jsx(Pause, { size: 28, strokeWidth: 2 }) : playerState === livePlayer.PLAYER_STATE.REFRESH ? /* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { size: 28, strokeWidth: 2, className: "refreshing-spinner" }) : /* @__PURE__ */ jsxRuntime.jsx(Play, { size: 28, strokeWidth: 2 })
17484
- }
17485
- ),
17486
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "time-display player-controls-time-display", children: [
17487
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "current-time", children: formatTime(currentTime) }),
17488
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "time-separator player-controls-time-separator", children: "|" }),
17489
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "total-time player-controls-total-time", children: formatTime(duration) })
17490
- ] })
17491
- ] })
17492
- ]
17493
- }
17494
- );
17513
+ const handleZoomIn = React.useCallback(() => {
17514
+ if (setZoomLevel && zoomLevel < MAX_ZOOM) {
17515
+ setZoomLevel(zoomLevel + ZOOM_STEP);
17516
+ }
17517
+ }, [zoomLevel, setZoomLevel]);
17518
+ const handleZoomOut = React.useCallback(() => {
17519
+ if (setZoomLevel && zoomLevel > MIN_ZOOM) {
17520
+ setZoomLevel(zoomLevel - ZOOM_STEP);
17521
+ }
17522
+ }, [zoomLevel, setZoomLevel]);
17523
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-16 bg-gray-800 border-t border-gray-700 p-4 ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
17524
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
17525
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
17526
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(Trash2, { className: "w-5 h-5" })
17534
+ }
17535
+ ),
17536
+ /* @__PURE__ */ jsxRuntime.jsx(
17537
+ "button",
17538
+ {
17539
+ onClick: handleSplit,
17540
+ disabled: !(selectedItem instanceof timeline.TrackElement),
17541
+ title: "Split",
17542
+ className: `btn btn-ghost ${selectedItem instanceof timeline.TrackElement ? "text-purple-400 hover:text-purple-300" : "text-gray-500 cursor-not-allowed"}`,
17543
+ children: /* @__PURE__ */ jsxRuntime.jsx(Scissors, { className: "w-5 h-5" })
17544
+ }
17545
+ ),
17546
+ /* @__PURE__ */ jsxRuntime.jsx(
17547
+ UndoRedoControls,
17548
+ {
17549
+ canUndo,
17550
+ canRedo,
17551
+ onUndo,
17552
+ onRedo
17553
+ }
17554
+ )
17555
+ ] }),
17556
+ /* @__PURE__ */ jsxRuntime.jsx(
17557
+ "button",
17558
+ {
17559
+ onClick: togglePlayback,
17560
+ disabled: playerState === livePlayer.PLAYER_STATE.REFRESH,
17561
+ title: playerState === livePlayer.PLAYER_STATE.PLAYING ? "Pause" : playerState === livePlayer.PLAYER_STATE.REFRESH ? "Refreshing" : "Play",
17562
+ className: "btn btn-ghost text-white",
17563
+ children: playerState === livePlayer.PLAYER_STATE.PLAYING ? /* @__PURE__ */ jsxRuntime.jsx(Pause, { className: "w-6 h-6" }) : playerState === livePlayer.PLAYER_STATE.REFRESH ? /* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { className: "w-6 h-6 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(Play, { className: "w-6 h-6" })
17564
+ }
17565
+ ),
17566
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-gray-300", children: [
17567
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: formatTime(currentTime) }),
17568
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500", children: "/" }),
17569
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: formatTime(duration) })
17570
+ ] })
17571
+ ] }),
17572
+ setZoomLevel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
17573
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(ZoomOut, { className: "w-5 h-5" })
17581
+ }
17582
+ ),
17583
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.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__ */ jsxRuntime.jsx(ZoomIn, { className: "w-5 h-5" })
17595
+ }
17596
+ )
17597
+ ] })
17598
+ ] }) });
17495
17599
  };
17496
17600
  const usePlayerControl = () => {
17497
17601
  const { playerState, setPlayerState } = livePlayer.useLivePlayerContext();
@@ -17519,59 +17623,15 @@ This message will only show in development mode. It won't appear in production.
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__ */ jsxRuntime.jsxs("div", { className: "twick-track-zoom-container", children: [
17543
- /* @__PURE__ */ jsxRuntime.jsx(ZoomOut, { size: 28, onClick: handleZoomOut }),
17544
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-zoom-slider", children: [
17545
- /* @__PURE__ */ jsxRuntime.jsx(
17546
- "div",
17547
- {
17548
- className: "twick-zoom-slider-track",
17549
- style: {
17550
- width: `${(zoomLevel - minZoom) / (maxZoom - minZoom) * 100}%`
17551
- }
17552
- }
17553
- ),
17554
- /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(ZoomIn, { size: 28, onClick: handleZoomIn })
17565
- ] });
17566
- };
17567
17626
  const useTimelineControl = () => {
17568
- const { editor } = timeline.useTimelineContext();
17627
+ const { editor, setSelectedItem } = timeline.useTimelineContext();
17569
17628
  const deleteItem = (item) => {
17570
17629
  if (item instanceof timeline.Track) {
17571
17630
  editor.removeTrack(item);
17572
17631
  } else if (item instanceof timeline.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 @@ This message will only show in development mode. It won't appear in production.
17597
17657
  const { togglePlayback } = usePlayerControl();
17598
17658
  const { canRedo, canUndo, totalDuration, selectedItem } = timeline.useTimelineContext();
17599
17659
  const { deleteItem, splitElement, handleUndo, handleRedo } = useTimelineControl();
17600
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-editor-timeline-controls", children: [
17601
- /* @__PURE__ */ jsxRuntime.jsx(
17602
- PlayerControls,
17603
- {
17604
- selectedItem,
17605
- duration: totalDuration,
17606
- currentTime,
17607
- playerState,
17608
- togglePlayback,
17609
- canUndo,
17610
- canRedo,
17611
- onDelete: deleteItem,
17612
- onSplit: splitElement,
17613
- onUndo: handleUndo,
17614
- onRedo: handleRedo
17615
- }
17616
- ),
17617
- /* @__PURE__ */ jsxRuntime.jsx(TimelineZoom, { zoomLevel: trackZoom, setZoomLevel: setTrackZoom })
17618
- ] });
17660
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-editor-timeline-controls", children: /* @__PURE__ */ jsxRuntime.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] = React.useState(DEFAULT_TIMELINE_ZOOM);
17687
+ const useMemoizedPlayerManager = React.useMemo(
17688
+ () => /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "twick-editor-main-container", children: [
17630
17699
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-editor-view-section", children: [
17631
17700
  leftPanel ? leftPanel : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
17632
- /* @__PURE__ */ jsxRuntime.jsx(
17633
- PlayerManager,
17634
- {
17635
- videoProps: editorConfig.videoProps,
17636
- canvasMode: editorConfig.canvasMode ?? true
17637
- }
17638
- ),
17701
+ useMemoizedPlayerManager,
17639
17702
  rightPanel ? rightPanel : /* @__PURE__ */ jsxRuntime.jsx("div", {})
17640
17703
  ] }),
17641
17704
  bottomPanel ? bottomPanel : null,
17642
17705
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-editor-timeline-section", children: [
17643
- playControls ? playControls : defaultPlayControls ? /* @__PURE__ */ jsxRuntime.jsx(ControlManager, { trackZoom, setTrackZoom }) : null,
17644
- /* @__PURE__ */ jsxRuntime.jsx(
17645
- TimelineManager,
17646
- {
17647
- trackZoom
17648
- }
17649
- )
17706
+ defaultPlayControls ? /* @__PURE__ */ jsxRuntime.jsx(ControlManager, { trackZoom, setTrackZoom }) : null,
17707
+ /* @__PURE__ */ jsxRuntime.jsx(TimelineManager, { trackZoom })
17650
17708
  ] })
17651
17709
  ] });
17652
17710
  };
@@ -17817,7 +17875,7 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 @@ This message will only show in development mode. It won't appear in production.
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 "";
@@ -17977,6 +18064,7 @@ This message will only show in development mode. It won't appear in production.
17977
18064
  exports2.animationGifs = animationGifs;
17978
18065
  exports2.default = VideoEditor;
17979
18066
  exports2.getAnimationGif = getAnimationGif;
18067
+ exports2.setElementColors = setElementColors;
17980
18068
  exports2.usePlayerControl = usePlayerControl;
17981
18069
  exports2.useTimelineControl = useTimelineControl;
17982
18070
  Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });