@twick/video-editor 0.14.2 → 0.14.4

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
@@ -6816,32 +6816,53 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6816
6816
  };
6817
6817
  t(vh$1, "type", "Vibrance"), t(vh$1, "defaults", { vibrance: 0 }), t(vh$1, "uniformLocations", ["uVibrance"]), tt.setClass(vh$1);
6818
6818
  const DEFAULT_TEXT_PROPS = {
6819
+ /** Font family for text elements */
6819
6820
  family: "Poppins",
6821
+ /** Font size in pixels */
6820
6822
  size: 48,
6823
+ /** Text fill color */
6821
6824
  fill: "#FFFFFF",
6825
+ /** Text stroke color */
6822
6826
  stroke: "#000000",
6827
+ /** Stroke line width */
6823
6828
  lineWidth: 0
6824
6829
  };
6825
6830
  const DEFAULT_CAPTION_PROPS = {
6831
+ /** Font family for caption elements */
6826
6832
  family: "Poppins",
6833
+ /** Font size in pixels */
6827
6834
  size: 48,
6835
+ /** Text fill color */
6828
6836
  fill: "#FFFFFF",
6837
+ /** Font weight */
6829
6838
  fontWeight: 600,
6839
+ /** Text stroke color */
6830
6840
  stroke: "#000000",
6841
+ /** Stroke line width */
6831
6842
  lineWidth: 0.2,
6843
+ /** Shadow color */
6832
6844
  shadowColor: "#000000",
6845
+ /** Shadow blur radius */
6833
6846
  shadowBlur: 2,
6847
+ /** Shadow offset [x, y] */
6834
6848
  shadowOffset: [0, 0]
6835
6849
  };
6836
6850
  const CANVAS_OPERATIONS = {
6851
+ /** An item has been selected on the canvas */
6837
6852
  ITEM_SELECTED: "ITEM_SELECTED",
6853
+ /** An item has been updated/modified on the canvas */
6838
6854
  ITEM_UPDATED: "ITEM_UPDATED"
6839
6855
  };
6840
6856
  const ELEMENT_TYPES = {
6857
+ /** Text element type */
6841
6858
  TEXT: "text",
6859
+ /** Caption element type */
6842
6860
  CAPTION: "caption",
6861
+ /** Image element type */
6843
6862
  IMAGE: "image",
6863
+ /** Video element type */
6844
6864
  VIDEO: "video",
6865
+ /** Rectangle element type */
6845
6866
  RECT: "rect"
6846
6867
  };
6847
6868
  const isBrowser$2 = typeof window !== "undefined";
@@ -6915,10 +6936,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6915
6936
  objects.forEach((obj) => canvas.add(obj));
6916
6937
  canvas.renderAll();
6917
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
+ };
6918
6944
  const clearCanvas = (canvas) => {
6919
- if (!canvas) return;
6920
- canvas.clear();
6921
- 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
+ }
6922
6952
  };
6923
6953
  const convertToCanvasPosition = (x2, y2, canvasMetadata) => {
6924
6954
  return {
@@ -6944,14 +6974,21 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6944
6974
  return currentFrameEffect;
6945
6975
  };
6946
6976
  const disabledControl = new Hs({
6977
+ /** X position offset */
6947
6978
  x: 0,
6979
+ /** Y position offset */
6948
6980
  y: -0.5,
6981
+ /** Additional Y offset */
6949
6982
  offsetY: 0,
6983
+ /** Cursor style when hovering */
6950
6984
  cursorStyle: "pointer",
6985
+ /** Action handler that does nothing */
6951
6986
  actionHandler: () => {
6952
6987
  return true;
6953
6988
  },
6989
+ /** Name of the action */
6954
6990
  actionName: "scale",
6991
+ /** Render function for the control */
6955
6992
  render: function(ctx, left, top) {
6956
6993
  const size = 0;
6957
6994
  ctx.save();
@@ -6962,12 +6999,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6962
6999
  }
6963
7000
  });
6964
7001
  const rotateControl = new Hs({
7002
+ /** X position offset */
6965
7003
  x: 0,
7004
+ /** Y position offset */
6966
7005
  y: -0.5,
7006
+ /** Additional Y offset for positioning */
6967
7007
  offsetY: -25,
7008
+ /** Cursor style when hovering */
6968
7009
  cursorStyle: "crosshair",
7010
+ /** Action handler with rotation and snapping */
6969
7011
  actionHandler: Ma.rotationWithSnapping,
7012
+ /** Name of the action */
6970
7013
  actionName: "rotate",
7014
+ /** Whether to show connection line */
6971
7015
  withConnection: true
6972
7016
  });
6973
7017
  const getThumbnail = async (videoUrl, seekTime = 0.1, playbackRate = 1) => {
@@ -7050,7 +7094,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7050
7094
  timeoutId = window.setTimeout(() => {
7051
7095
  cleanup();
7052
7096
  reject(new Error("Video loading timed out"));
7053
- }, 5e3);
7097
+ }, 15e3);
7054
7098
  video.src = videoUrl;
7055
7099
  document.body.appendChild(video);
7056
7100
  });
@@ -7101,7 +7145,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7101
7145
  canvas,
7102
7146
  canvasMetadata
7103
7147
  }) => {
7104
- 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;
7105
7149
  const { x: x2, y: y2 } = convertToCanvasPosition(
7106
7150
  ((_a2 = element.props) == null ? void 0 : _a2.x) || 0,
7107
7151
  ((_b = element.props) == null ? void 0 : _b.y) || 0,
@@ -7120,15 +7164,16 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7120
7164
  fontStyle: ((_g = element.props) == null ? void 0 : _g.fontStyle) || "normal",
7121
7165
  fontWeight: ((_h = element.props) == null ? void 0 : _h.fontWeight) || "normal",
7122
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,
7123
7168
  skipWrapping: false,
7124
- textAlign: ((_j = element.props) == null ? void 0 : _j.textAlign) || "center",
7125
- stroke: ((_k = element.props) == null ? void 0 : _k.stroke) || DEFAULT_TEXT_PROPS.stroke,
7126
- strokeWidth: ((_l = element.props) == null ? void 0 : _l.lineWidth) || DEFAULT_TEXT_PROPS.lineWidth,
7127
- shadow: ((_m = element.props) == null ? void 0 : _m.shadowColor) ? new ds({
7128
- 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,
7129
- 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,
7130
- blur: (((_u = element.props) == null ? void 0 : _u.shadowBlur) || 2) / 2,
7131
- 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
7132
7177
  }) : void 0
7133
7178
  });
7134
7179
  text.set("id", element.id);
@@ -7151,7 +7196,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7151
7196
  index,
7152
7197
  canvasMetadata
7153
7198
  }) => {
7154
- var _a2, _b, _c, _d;
7199
+ var _a2, _b, _c, _d, _e2;
7155
7200
  const width = (((_a2 = element.props) == null ? void 0 : _a2.width) || 0) * canvasMetadata.scaleX || canvasMetadata.width;
7156
7201
  const height = (((_b = element.props) == null ? void 0 : _b.height) || 0) * canvasMetadata.scaleY || canvasMetadata.height;
7157
7202
  const { x: x2, y: y2 } = convertToCanvasPosition(
@@ -7166,6 +7211,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7166
7211
  img.set("height", height);
7167
7212
  img.set("left", x2);
7168
7213
  img.set("top", y2);
7214
+ img.set("opacity", ((_e2 = element.props) == null ? void 0 : _e2.opacity) ?? 1);
7169
7215
  img.set("selectable", true);
7170
7216
  img.set("hasControls", true);
7171
7217
  img.set("touchAction", "all");
@@ -7177,7 +7223,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7177
7223
  captionProps,
7178
7224
  canvasMetadata
7179
7225
  }) => {
7180
- 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;
7181
7227
  const { x: x2, y: y2 } = convertToCanvasPosition(
7182
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,
7183
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,
@@ -7196,13 +7242,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7196
7242
  fill: ((_o2 = element.props) == null ? void 0 : _o2.fill) || ((_p = captionProps.color) == null ? void 0 : _p.text) || DEFAULT_CAPTION_PROPS.fill,
7197
7243
  fontWeight: DEFAULT_CAPTION_PROPS.fontWeight,
7198
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,
7199
7246
  shadow: new ds({
7200
- 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]),
7201
- 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]),
7202
- blur: ((_x = element.props) == null ? void 0 : _x.shadowBlur) || DEFAULT_CAPTION_PROPS.shadowBlur,
7203
- 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
7204
7251
  }),
7205
- 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
7206
7253
  });
7207
7254
  caption.set("id", element.id);
7208
7255
  caption.set("zIndex", index);
@@ -7293,7 +7340,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7293
7340
  canvasMetadata,
7294
7341
  currentFrameEffect
7295
7342
  }) => {
7296
- 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;
7297
7344
  let frameSize;
7298
7345
  let angle;
7299
7346
  let framePosition;
@@ -7348,7 +7395,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7348
7395
  originX: "center",
7349
7396
  originY: "center",
7350
7397
  scaleX: newSize.width / img.width,
7351
- scaleY: newSize.height / img.height
7398
+ scaleY: newSize.height / img.height,
7399
+ opacity: ((_n2 = element.props) == null ? void 0 : _n2.opacity) ?? 1
7352
7400
  });
7353
7401
  const { x: x2, y: y2 } = convertToCanvasPosition(
7354
7402
  (framePosition == null ? void 0 : framePosition.x) || 0,
@@ -7468,6 +7516,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7468
7516
  const elementFrameMap = React.useRef({});
7469
7517
  const twickCanvasRef = React.useRef(null);
7470
7518
  const videoSizeRef = React.useRef({ width: 1, height: 1 });
7519
+ const canvasResolutionRef = React.useRef({ width: 1, height: 1 });
7471
7520
  const canvasMetadataRef = React.useRef({
7472
7521
  width: 0,
7473
7522
  height: 0,
@@ -7491,9 +7540,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7491
7540
  selectionLineWidth = 2,
7492
7541
  uniScaleTransform = true,
7493
7542
  enableRetinaScaling = true,
7494
- touchZoomThreshold = 10
7543
+ touchZoomThreshold = 10,
7544
+ forceBuild = false
7495
7545
  }) => {
7496
7546
  if (!canvasRef) return;
7547
+ if (!forceBuild && canvasResolutionRef.current.width === canvasSize.width && canvasResolutionRef.current.height === canvasSize.height) {
7548
+ return;
7549
+ }
7497
7550
  if (twickCanvasRef.current) {
7498
7551
  console.log("Destroying twickCanvas");
7499
7552
  twickCanvasRef.current.off("mouse:up", handleMouseUp);
@@ -7513,6 +7566,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7513
7566
  canvasMetadataRef.current = canvasMetadata;
7514
7567
  videoSizeRef.current = videoSize;
7515
7568
  canvas == null ? void 0 : canvas.on("mouse:up", handleMouseUp);
7569
+ canvasResolutionRef.current = canvasSize;
7516
7570
  setTwickCanvas(canvas);
7517
7571
  twickCanvasRef.current = canvas;
7518
7572
  if (onCanvasReady) {
@@ -7653,13 +7707,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7653
7707
  captionProps,
7654
7708
  cleanAndAdd = false
7655
7709
  }) => {
7656
- if (!twickCanvas) {
7657
- console.warn("Canvas not initialized");
7710
+ if (!twickCanvas || !getCanvasContext(twickCanvas)) {
7711
+ console.warn("Canvas not properly initialized");
7658
7712
  return;
7659
7713
  }
7660
7714
  try {
7661
- if (cleanAndAdd) {
7715
+ if (cleanAndAdd && getCanvasContext(twickCanvas)) {
7716
+ const backgroundColor = twickCanvas.backgroundColor;
7662
7717
  clearCanvas(twickCanvas);
7718
+ if (backgroundColor) {
7719
+ twickCanvas.backgroundColor = backgroundColor;
7720
+ twickCanvas.renderAll();
7721
+ }
7663
7722
  }
7664
7723
  await Promise.all(
7665
7724
  elements.map(async (element, index) => {
@@ -7791,7 +7850,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7791
7850
  break;
7792
7851
  case CANVAS_OPERATIONS.ITEM_UPDATED:
7793
7852
  if (element) {
7794
- editor.updateElement(element);
7853
+ const updatedElement = editor.updateElement(element);
7854
+ setSelectedItem(updatedElement);
7795
7855
  }
7796
7856
  break;
7797
7857
  }
@@ -7874,6 +7934,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7874
7934
  height: container == null ? void 0 : container.clientHeight
7875
7935
  };
7876
7936
  buildCanvas({
7937
+ backgroundColor: videoProps.backgroundColor,
7877
7938
  videoSize: {
7878
7939
  width: videoProps.width,
7879
7940
  height: videoProps.height
@@ -7908,7 +7969,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7908
7969
  {
7909
7970
  className: "twick-editor-loading-overlay",
7910
7971
  style: {
7911
- opacity: playerUpdating ? 1 : 0
7972
+ display: playerUpdating ? "flex" : "none"
7912
7973
  },
7913
7974
  children: playerUpdating ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-editor-loading-spinner" }) : null
7914
7975
  }
@@ -9533,7 +9594,7 @@ This message will only show in development mode. It won't appear in production.
9533
9594
  * This source code is licensed under the ISC license.
9534
9595
  * See the LICENSE file in the root directory of this source tree.
9535
9596
  */
9536
- const __iconNode$a = [
9597
+ const __iconNode$b = [
9537
9598
  ["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
9538
9599
  ["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
9539
9600
  ["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
@@ -9541,45 +9602,56 @@ This message will only show in development mode. It won't appear in production.
9541
9602
  ["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
9542
9603
  ["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
9543
9604
  ];
9544
- const GripVertical = createLucideIcon("grip-vertical", __iconNode$a);
9605
+ const GripVertical = createLucideIcon("grip-vertical", __iconNode$b);
9545
9606
  /**
9546
9607
  * @license lucide-react v0.511.0 - ISC
9547
9608
  *
9548
9609
  * This source code is licensed under the ISC license.
9549
9610
  * See the LICENSE file in the root directory of this source tree.
9550
9611
  */
9551
- const __iconNode$9 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
9552
- const LoaderCircle = createLucideIcon("loader-circle", __iconNode$9);
9612
+ const __iconNode$a = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
9613
+ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$a);
9553
9614
  /**
9554
9615
  * @license lucide-react v0.511.0 - ISC
9555
9616
  *
9556
9617
  * This source code is licensed under the ISC license.
9557
9618
  * See the LICENSE file in the root directory of this source tree.
9558
9619
  */
9559
- const __iconNode$8 = [
9620
+ const __iconNode$9 = [
9560
9621
  ["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2", key: "1w4ew1" }],
9561
9622
  ["path", { d: "M7 11V7a5 5 0 0 1 10 0v4", key: "fwvmzm" }]
9562
9623
  ];
9563
- const Lock = createLucideIcon("lock", __iconNode$8);
9624
+ const Lock = createLucideIcon("lock", __iconNode$9);
9564
9625
  /**
9565
9626
  * @license lucide-react v0.511.0 - ISC
9566
9627
  *
9567
9628
  * This source code is licensed under the ISC license.
9568
9629
  * See the LICENSE file in the root directory of this source tree.
9569
9630
  */
9570
- const __iconNode$7 = [
9631
+ const __iconNode$8 = [
9571
9632
  ["rect", { x: "14", y: "4", width: "4", height: "16", rx: "1", key: "zuxfzm" }],
9572
9633
  ["rect", { x: "6", y: "4", width: "4", height: "16", rx: "1", key: "1okwgv" }]
9573
9634
  ];
9574
- const Pause = createLucideIcon("pause", __iconNode$7);
9635
+ const Pause = createLucideIcon("pause", __iconNode$8);
9636
+ /**
9637
+ * @license lucide-react v0.511.0 - ISC
9638
+ *
9639
+ * This source code is licensed under the ISC license.
9640
+ * See the LICENSE file in the root directory of this source tree.
9641
+ */
9642
+ const __iconNode$7 = [["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]];
9643
+ const Play = createLucideIcon("play", __iconNode$7);
9575
9644
  /**
9576
9645
  * @license lucide-react v0.511.0 - ISC
9577
9646
  *
9578
9647
  * This source code is licensed under the ISC license.
9579
9648
  * See the LICENSE file in the root directory of this source tree.
9580
9649
  */
9581
- const __iconNode$6 = [["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]];
9582
- const Play = createLucideIcon("play", __iconNode$6);
9650
+ const __iconNode$6 = [
9651
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
9652
+ ["path", { d: "M12 5v14", key: "s699le" }]
9653
+ ];
9654
+ const Plus = createLucideIcon("plus", __iconNode$6);
9583
9655
  /**
9584
9656
  * @license lucide-react v0.511.0 - ISC
9585
9657
  *
@@ -16849,64 +16921,100 @@ This message will only show in development mode. It won't appear in production.
16849
16921
  };
16850
16922
  const MIN_DURATION = 0.1;
16851
16923
  const DRAG_TYPE = {
16924
+ /** Drag operation is starting */
16852
16925
  START: "start",
16926
+ /** Drag operation is in progress */
16853
16927
  MOVE: "move",
16928
+ /** Drag operation has ended */
16854
16929
  END: "end"
16855
16930
  };
16856
16931
  const DEFAULT_TIMELINE_ZOOM = 1.5;
16857
16932
  const DEFAULT_ELEMENT_COLORS = {
16858
- fragment: "#111111",
16859
- video: "#4B2E83",
16860
- // Muted deep violet (primary purple tone)
16861
- caption: "#5C5470",
16862
- // Faded violet/blue
16863
- image: "#805A38",
16864
- // Earthy brown-orange
16865
- audio: "#3C665B",
16866
- // Dark muted teal-green
16867
- text: "#375A7F",
16868
- // Dusty steel blue
16869
- element: "#6B3A5B",
16870
- // Muted berry purple
16871
- rect: "#4C3A72",
16872
- // Desaturated deep indigo
16873
- frameEffect: "#703C57",
16874
- // Dusty rose/maroon
16875
- filters: "#5A4C82",
16876
- // Muted twilight purple
16877
- transition: "#7A573A",
16878
- // Toasted copper
16879
- animation: "#32645C"
16880
- // Slate pine green
16933
+ /** Fragment element color - deep charcoal matching UI background */
16934
+ fragment: "#1A1A1A",
16935
+ /** Video element color - vibrant royal purple */
16936
+ video: "#8B5FBF",
16937
+ /** Caption element color - soft wisteria purple */
16938
+ caption: "#9B8ACE",
16939
+ /** Image element color - warm copper accent */
16940
+ image: "#D4956C",
16941
+ /** Audio element color - deep teal */
16942
+ audio: "#3D8B8B",
16943
+ /** Text element color - medium lavender */
16944
+ text: "#8D74C4",
16945
+ /** Generic element color - muted amethyst */
16946
+ element: "#7B68B8",
16947
+ /** Rectangle element color - deep indigo */
16948
+ rect: "#5B4B99",
16949
+ /** Frame effect color - rich magenta */
16950
+ frameEffect: "#B55B9C",
16951
+ /** Filters color - periwinkle blue */
16952
+ filters: "#7A89D4",
16953
+ /** Transition color - burnished bronze */
16954
+ transition: "#BE8157",
16955
+ /** Animation color - muted emerald */
16956
+ animation: "#4B9B78",
16957
+ /** Icon element color - bright orchid */
16958
+ icon: "#A76CD4",
16959
+ /** Circle element color - deep byzantium */
16960
+ circle: "#703D8B"
16881
16961
  };
16882
16962
  const AVAILABLE_TEXT_FONTS = {
16883
16963
  // Google Fonts
16964
+ /** Modern sans-serif font */
16884
16965
  RUBIK: "Rubik",
16966
+ /** Clean and readable font */
16885
16967
  MULISH: "Mulish",
16968
+ /** Bold display font */
16886
16969
  LUCKIEST_GUY: "Luckiest Guy",
16970
+ /** Elegant serif font */
16887
16971
  PLAYFAIR_DISPLAY: "Playfair Display",
16972
+ /** Classic sans-serif font */
16888
16973
  ROBOTO: "Roboto",
16974
+ /** Modern geometric font */
16889
16975
  POPPINS: "Poppins",
16890
16976
  // Display and Decorative Fonts
16977
+ /** Comic-style display font */
16891
16978
  BANGERS: "Bangers",
16979
+ /** Handwritten-style font */
16892
16980
  BIRTHSTONE: "Birthstone",
16981
+ /** Elegant script font */
16893
16982
  CORINTHIA: "Corinthia",
16983
+ /** Formal script font */
16894
16984
  IMPERIAL_SCRIPT: "Imperial Script",
16985
+ /** Bold outline font */
16895
16986
  KUMAR_ONE_OUTLINE: "Kumar One Outline",
16987
+ /** Light outline font */
16896
16988
  LONDRI_OUTLINE: "Londrina Outline",
16989
+ /** Casual script font */
16897
16990
  MARCK_SCRIPT: "Marck Script",
16991
+ /** Modern sans-serif font */
16898
16992
  MONTSERRAT: "Montserrat",
16993
+ /** Stylish display font */
16899
16994
  PATTAYA: "Pattaya",
16900
16995
  // CDN Fonts
16996
+ /** Unique display font */
16901
16997
  PERALTA: "Peralta",
16998
+ /** Bold impact font */
16902
16999
  IMPACT: "Impact",
17000
+ /** Handwritten-style font */
16903
17001
  LUMANOSIMO: "Lumanosimo",
17002
+ /** Custom display font */
16904
17003
  KAPAKANA: "Kapakana",
17004
+ /** Handwritten font */
16905
17005
  HANDYRUSH: "HandyRush",
17006
+ /** Decorative font */
16906
17007
  DASHER: "Dasher",
17008
+ /** Signature-style font */
16907
17009
  BRITTANY_SIGNATURE: "Brittany Signature"
16908
17010
  };
16909
17011
  let ELEMENT_COLORS = { ...DEFAULT_ELEMENT_COLORS };
17012
+ const setElementColors = (colors) => {
17013
+ ELEMENT_COLORS = {
17014
+ ...DEFAULT_ELEMENT_COLORS,
17015
+ ...colors
17016
+ };
17017
+ };
16910
17018
  const TrackElementView = ({
16911
17019
  element,
16912
17020
  parentWidth,
@@ -16941,10 +17049,12 @@ This message will only show in development mode. It won't appear in production.
16941
17049
  const span = prev.end - prev.start;
16942
17050
  let newStart = Math.max(0, prev.start + dx / parentWidth * duration);
16943
17051
  newStart = Math.min(newStart, prev.end - MIN_DURATION);
16944
- if (prevEnd !== null && !allowOverlap && newStart < prevEnd) {
16945
- newStart = prevEnd;
16946
- } else if (nextStart !== null && !allowOverlap && newStart + span > nextStart) {
16947
- newStart = nextStart - span;
17052
+ if (!allowOverlap) {
17053
+ if (prevEnd !== null && newStart < prevEnd) {
17054
+ newStart = prevEnd;
17055
+ } else if (nextStart !== null && !allowOverlap && newStart + span > nextStart) {
17056
+ newStart = nextStart - span;
17057
+ }
16948
17058
  }
16949
17059
  return {
16950
17060
  start: newStart,
@@ -16985,8 +17095,10 @@ This message will only show in development mode. It won't appear in production.
16985
17095
  setPosition((prev) => {
16986
17096
  let newEnd = prev.end + dx / parentWidth * duration;
16987
17097
  newEnd = Math.max(newEnd, prev.start + MIN_DURATION);
16988
- if (nextStart !== null && !allowOverlap && newEnd > nextStart) {
16989
- newEnd = nextStart;
17098
+ if (!allowOverlap) {
17099
+ if (nextStart !== null && newEnd > nextStart) {
17100
+ newEnd = nextStart;
17101
+ }
16990
17102
  }
16991
17103
  return {
16992
17104
  start: prev.start,
@@ -17023,11 +17135,19 @@ This message will only show in development mode. It won't appear in production.
17023
17135
  const motionProps = {
17024
17136
  ref,
17025
17137
  className: `twick-track-element ${isSelected ? "twick-track-element-selected" : "twick-track-element-default"} ${isDragging2 ? "twick-track-element-dragging" : ""}`,
17026
- onMouseDown: setLastPos,
17027
- onTouchStart: setLastPos,
17138
+ onMouseDown: (e2) => {
17139
+ if (e2.target === ref.current) {
17140
+ setLastPos();
17141
+ }
17142
+ },
17143
+ onTouchStart: (e2) => {
17144
+ if (e2.target === ref.current) {
17145
+ setLastPos();
17146
+ }
17147
+ },
17028
17148
  onMouseUp: sendUpdate,
17029
17149
  onTouchEnd: sendUpdate,
17030
- onDoubleClick: () => {
17150
+ onClick: () => {
17031
17151
  if (onSelection) {
17032
17152
  onSelection(element);
17033
17153
  }
@@ -17043,7 +17163,7 @@ This message will only show in development mode. It won't appear in production.
17043
17163
  isSelected ? /* @__PURE__ */ jsxRuntime.jsx(
17044
17164
  "div",
17045
17165
  {
17046
- style: { touchAction: "none" },
17166
+ style: { touchAction: "none", zIndex: isSelected ? 100 : 1 },
17047
17167
  ...bindStartHandle(),
17048
17168
  className: "twick-track-element-handle twick-track-element-handle-start"
17049
17169
  }
@@ -17052,7 +17172,7 @@ This message will only show in development mode. It won't appear in production.
17052
17172
  isSelected ? /* @__PURE__ */ jsxRuntime.jsx(
17053
17173
  "div",
17054
17174
  {
17055
- style: { touchAction: "none" },
17175
+ style: { touchAction: "none", zIndex: isSelected ? 100 : 1 },
17056
17176
  ...bindEndHandle(),
17057
17177
  className: "twick-track-element-handle twick-track-element-handle-end"
17058
17178
  }
@@ -17104,7 +17224,7 @@ This message will only show in development mode. It won't appear in production.
17104
17224
  selectedItem,
17105
17225
  onSelection: onItemSelection,
17106
17226
  onDrag,
17107
- nextStart: index < elements.length - 1 ? elements[index + 1].getStart() : duration,
17227
+ nextStart: index < elements.length - 1 ? elements[index + 1].getStart() : null,
17108
17228
  prevEnd: index > 0 ? elements[index - 1].getEnd() : 0
17109
17229
  },
17110
17230
  element.getId()
@@ -17118,6 +17238,7 @@ This message will only show in development mode. It won't appear in production.
17118
17238
  duration,
17119
17239
  tracks,
17120
17240
  seekTrack,
17241
+ onAddTrack,
17121
17242
  onReorder,
17122
17243
  onSelectionChange,
17123
17244
  onElementDrag
@@ -17207,7 +17328,7 @@ This message will only show in development mode. It won't appear in production.
17207
17328
  onScroll: handleScroll,
17208
17329
  children: [
17209
17330
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: timelineWidthPx }, children: seekTrack ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", position: "relative" }, children: [
17210
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-seek-track-empty-space" }),
17331
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-seek-track-empty-space", onClick: onAddTrack, children: /* @__PURE__ */ jsxRuntime.jsx(Plus, { color: "white", size: 20 }) }),
17211
17332
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexGrow: 1 }, children: seekTrack })
17212
17333
  ] }) : null }),
17213
17334
  /* @__PURE__ */ jsxRuntime.jsx("div", { ref: timelineContentRef, style: { width: timelineWidthPx }, children: (tracks || []).map((track) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-timeline-container", children: [
@@ -17241,13 +17362,7 @@ This message will only show in development mode. It won't appear in production.
17241
17362
  );
17242
17363
  }
17243
17364
  const useTimelineManager = () => {
17244
- const {
17245
- selectedItem,
17246
- changeLog,
17247
- setSelectedItem,
17248
- totalDuration,
17249
- editor
17250
- } = timeline.useTimelineContext();
17365
+ const { selectedItem, changeLog, setSelectedItem, totalDuration, editor } = timeline.useTimelineContext();
17251
17366
  const onElementDrag = ({
17252
17367
  element,
17253
17368
  dragType,
@@ -17266,7 +17381,8 @@ This message will only show in development mode. It won't appear in production.
17266
17381
  }
17267
17382
  element.setStart(updates.start);
17268
17383
  element.setEnd(updates.end);
17269
- editor.updateElement(element);
17384
+ const updatedElement = editor.updateElement(element);
17385
+ setSelectedItem(updatedElement);
17270
17386
  };
17271
17387
  const timelineData = React.useMemo(() => {
17272
17388
  const timelineDataFromEditor = editor.getTimelineData();
@@ -17283,8 +17399,14 @@ This message will only show in development mode. It won't appear in production.
17283
17399
  const onSelectionChange = (selectedItem2) => {
17284
17400
  setSelectedItem(selectedItem2);
17285
17401
  };
17402
+ const onAddTrack = () => {
17403
+ var _a2;
17404
+ const tracks = ((_a2 = editor.getTimelineData()) == null ? void 0 : _a2.tracks) || [];
17405
+ editor.addTrack(`Track_${tracks.length + 1}`);
17406
+ };
17286
17407
  return {
17287
17408
  timelineData,
17409
+ onAddTrack,
17288
17410
  onElementDrag,
17289
17411
  onReorder,
17290
17412
  onSeek,
@@ -17298,7 +17420,7 @@ This message will only show in development mode. It won't appear in production.
17298
17420
  trackZoom
17299
17421
  }) => {
17300
17422
  var _a2;
17301
- const { timelineData, totalDuration, selectedItem, onReorder, onElementDrag, onSeek, onSelectionChange } = useTimelineManager();
17423
+ const { timelineData, totalDuration, selectedItem, onAddTrack, onReorder, onElementDrag, onSeek, onSelectionChange } = useTimelineManager();
17302
17424
  return /* @__PURE__ */ jsxRuntime.jsx(
17303
17425
  TimelineView,
17304
17426
  {
@@ -17309,6 +17431,7 @@ This message will only show in development mode. It won't appear in production.
17309
17431
  selectedItem,
17310
17432
  onDeletion: () => {
17311
17433
  },
17434
+ onAddTrack,
17312
17435
  onReorder,
17313
17436
  onElementDrag,
17314
17437
  onSeek,
@@ -17347,6 +17470,9 @@ This message will only show in development mode. It won't appear in production.
17347
17470
  )
17348
17471
  ] });
17349
17472
  };
17473
+ const MAX_ZOOM = 3;
17474
+ const MIN_ZOOM = 0.5;
17475
+ const ZOOM_STEP = 0.25;
17350
17476
  const PlayerControls = ({
17351
17477
  selectedItem,
17352
17478
  duration,
@@ -17359,6 +17485,8 @@ This message will only show in development mode. It won't appear in production.
17359
17485
  onRedo,
17360
17486
  onSplit,
17361
17487
  onDelete,
17488
+ zoomLevel = 1,
17489
+ setZoomLevel,
17362
17490
  className = ""
17363
17491
  }) => {
17364
17492
  const formatTime = React.useCallback((time2) => {
@@ -17376,61 +17504,92 @@ This message will only show in development mode. It won't appear in production.
17376
17504
  onSplit(selectedItem, currentTime);
17377
17505
  }
17378
17506
  }, [selectedItem, onSplit, currentTime]);
17379
- return /* @__PURE__ */ jsxRuntime.jsxs(
17380
- "div",
17381
- {
17382
- className: `player-controls player-controls-card-vertical ${className}`,
17383
- children: [
17384
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "edit-controls player-controls-edit-controls", children: [
17385
- /* @__PURE__ */ jsxRuntime.jsx(
17386
- "button",
17387
- {
17388
- className: `control-btn delete-btn player-controls-delete-btn${!!selectedItem ? " active" : " btn-disabled"}`,
17389
- onClick: handleDelete,
17390
- disabled: !selectedItem,
17391
- title: "Delete",
17392
- children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 18, strokeWidth: 2 })
17393
- }
17394
- ),
17395
- /* @__PURE__ */ jsxRuntime.jsx(
17396
- "button",
17397
- {
17398
- className: `control-btn split-btn player-controls-split-btn${selectedItem instanceof timeline.TrackElement ? " active" : " btn-disabled"}`,
17399
- onClick: handleSplit,
17400
- title: "Split",
17401
- children: /* @__PURE__ */ jsxRuntime.jsx(Scissors, { size: 18, strokeWidth: 2 })
17402
- }
17403
- ),
17404
- /* @__PURE__ */ jsxRuntime.jsx(
17405
- UndoRedoControls,
17406
- {
17407
- canUndo,
17408
- canRedo,
17409
- onUndo,
17410
- onRedo
17411
- }
17412
- )
17413
- ] }),
17414
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "playback-controls player-controls-playback-controls", children: [
17415
- /* @__PURE__ */ jsxRuntime.jsx(
17416
- "button",
17417
- {
17418
- className: `control-btn play-pause-btn player-controls-play-pause-btn${playerState === livePlayer.PLAYER_STATE.PLAYING ? " playing" : ""}${playerState === livePlayer.PLAYER_STATE.REFRESH ? " refreshing" : ""}`,
17419
- onClick: togglePlayback,
17420
- title: playerState === livePlayer.PLAYER_STATE.PLAYING ? "Pause" : playerState === livePlayer.PLAYER_STATE.REFRESH ? "Refreshing" : "Play",
17421
- disabled: playerState === livePlayer.PLAYER_STATE.REFRESH,
17422
- 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 })
17423
- }
17424
- ),
17425
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "time-display player-controls-time-display", children: [
17426
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "current-time", children: formatTime(currentTime) }),
17427
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "time-separator player-controls-time-separator", children: "|" }),
17428
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "total-time player-controls-total-time", children: formatTime(duration) })
17429
- ] })
17430
- ] })
17431
- ]
17432
- }
17433
- );
17507
+ const handleZoomIn = React.useCallback(() => {
17508
+ if (setZoomLevel && zoomLevel < MAX_ZOOM) {
17509
+ setZoomLevel(zoomLevel + ZOOM_STEP);
17510
+ }
17511
+ }, [zoomLevel, setZoomLevel]);
17512
+ const handleZoomOut = React.useCallback(() => {
17513
+ if (setZoomLevel && zoomLevel > MIN_ZOOM) {
17514
+ setZoomLevel(zoomLevel - ZOOM_STEP);
17515
+ }
17516
+ }, [zoomLevel, setZoomLevel]);
17517
+ 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: [
17518
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
17519
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
17520
+ /* @__PURE__ */ jsxRuntime.jsx(
17521
+ "button",
17522
+ {
17523
+ onClick: handleDelete,
17524
+ disabled: !selectedItem,
17525
+ title: "Delete",
17526
+ className: `btn btn-ghost ${!!selectedItem ? "text-red-400 hover:text-red-300" : "text-gray-500 cursor-not-allowed"}`,
17527
+ children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { className: "w-5 h-5" })
17528
+ }
17529
+ ),
17530
+ /* @__PURE__ */ jsxRuntime.jsx(
17531
+ "button",
17532
+ {
17533
+ onClick: handleSplit,
17534
+ disabled: !(selectedItem instanceof timeline.TrackElement),
17535
+ title: "Split",
17536
+ className: `btn btn-ghost ${selectedItem instanceof timeline.TrackElement ? "text-purple-400 hover:text-purple-300" : "text-gray-500 cursor-not-allowed"}`,
17537
+ children: /* @__PURE__ */ jsxRuntime.jsx(Scissors, { className: "w-5 h-5" })
17538
+ }
17539
+ ),
17540
+ /* @__PURE__ */ jsxRuntime.jsx(
17541
+ UndoRedoControls,
17542
+ {
17543
+ canUndo,
17544
+ canRedo,
17545
+ onUndo,
17546
+ onRedo
17547
+ }
17548
+ )
17549
+ ] }),
17550
+ /* @__PURE__ */ jsxRuntime.jsx(
17551
+ "button",
17552
+ {
17553
+ onClick: togglePlayback,
17554
+ disabled: playerState === livePlayer.PLAYER_STATE.REFRESH,
17555
+ title: playerState === livePlayer.PLAYER_STATE.PLAYING ? "Pause" : playerState === livePlayer.PLAYER_STATE.REFRESH ? "Refreshing" : "Play",
17556
+ className: "btn btn-ghost text-white",
17557
+ 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" })
17558
+ }
17559
+ ),
17560
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-gray-300", children: [
17561
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: formatTime(currentTime) }),
17562
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500", children: "/" }),
17563
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: formatTime(duration) })
17564
+ ] })
17565
+ ] }),
17566
+ setZoomLevel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
17567
+ /* @__PURE__ */ jsxRuntime.jsx(
17568
+ "button",
17569
+ {
17570
+ onClick: handleZoomOut,
17571
+ disabled: zoomLevel <= MIN_ZOOM,
17572
+ title: "Zoom Out",
17573
+ className: `btn btn-ghost ${zoomLevel > MIN_ZOOM ? "text-gray-300 hover:text-white" : "text-gray-500 cursor-not-allowed"}`,
17574
+ children: /* @__PURE__ */ jsxRuntime.jsx(ZoomOut, { className: "w-5 h-5" })
17575
+ }
17576
+ ),
17577
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-gray-300 font-medium min-w-[3rem] text-center", children: [
17578
+ Math.round(zoomLevel * 100),
17579
+ "%"
17580
+ ] }),
17581
+ /* @__PURE__ */ jsxRuntime.jsx(
17582
+ "button",
17583
+ {
17584
+ onClick: handleZoomIn,
17585
+ disabled: zoomLevel >= MAX_ZOOM,
17586
+ title: "Zoom In",
17587
+ className: `btn btn-ghost ${zoomLevel < MAX_ZOOM ? "text-gray-300 hover:text-white" : "text-gray-500 cursor-not-allowed"}`,
17588
+ children: /* @__PURE__ */ jsxRuntime.jsx(ZoomIn, { className: "w-5 h-5" })
17589
+ }
17590
+ )
17591
+ ] })
17592
+ ] }) });
17434
17593
  };
17435
17594
  const usePlayerControl = () => {
17436
17595
  const { playerState, setPlayerState } = livePlayer.useLivePlayerContext();
@@ -17458,59 +17617,15 @@ This message will only show in development mode. It won't appear in production.
17458
17617
  togglePlayback
17459
17618
  };
17460
17619
  };
17461
- const MAX_ZOOM = 3;
17462
- const MIN_ZOOM = 0.5;
17463
- const ZOOM_STEP = 0.25;
17464
- const TimelineZoom = ({
17465
- zoomLevel,
17466
- setZoomLevel,
17467
- minZoom = MIN_ZOOM,
17468
- maxZoom = MAX_ZOOM,
17469
- zoomStep = ZOOM_STEP
17470
- }) => {
17471
- const handleZoomIn = () => {
17472
- if (zoomLevel < maxZoom) {
17473
- setZoomLevel(zoomLevel + zoomStep);
17474
- }
17475
- };
17476
- const handleZoomOut = () => {
17477
- if (zoomLevel > minZoom) {
17478
- setZoomLevel(zoomLevel - zoomStep);
17479
- }
17480
- };
17481
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-track-zoom-container", children: [
17482
- /* @__PURE__ */ jsxRuntime.jsx(ZoomOut, { size: 28, onClick: handleZoomOut }),
17483
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-zoom-slider", children: [
17484
- /* @__PURE__ */ jsxRuntime.jsx(
17485
- "div",
17486
- {
17487
- className: "twick-zoom-slider-track",
17488
- style: {
17489
- width: `${(zoomLevel - minZoom) / (maxZoom - minZoom) * 100}%`
17490
- }
17491
- }
17492
- ),
17493
- /* @__PURE__ */ jsxRuntime.jsx(
17494
- "div",
17495
- {
17496
- className: "twick-zoom-slider-thumb",
17497
- style: {
17498
- left: `calc(${(zoomLevel - minZoom) / (maxZoom - minZoom) * 100}%)`
17499
- }
17500
- }
17501
- )
17502
- ] }),
17503
- /* @__PURE__ */ jsxRuntime.jsx(ZoomIn, { size: 28, onClick: handleZoomIn })
17504
- ] });
17505
- };
17506
17620
  const useTimelineControl = () => {
17507
- const { editor } = timeline.useTimelineContext();
17621
+ const { editor, setSelectedItem } = timeline.useTimelineContext();
17508
17622
  const deleteItem = (item) => {
17509
17623
  if (item instanceof timeline.Track) {
17510
17624
  editor.removeTrack(item);
17511
17625
  } else if (item instanceof timeline.TrackElement) {
17512
17626
  editor.removeElement(item);
17513
17627
  }
17628
+ setSelectedItem(null);
17514
17629
  };
17515
17630
  const splitElement = (element, currentTime) => {
17516
17631
  editor.splitElement(element, currentTime);
@@ -17536,25 +17651,24 @@ This message will only show in development mode. It won't appear in production.
17536
17651
  const { togglePlayback } = usePlayerControl();
17537
17652
  const { canRedo, canUndo, totalDuration, selectedItem } = timeline.useTimelineContext();
17538
17653
  const { deleteItem, splitElement, handleUndo, handleRedo } = useTimelineControl();
17539
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-editor-timeline-controls", children: [
17540
- /* @__PURE__ */ jsxRuntime.jsx(
17541
- PlayerControls,
17542
- {
17543
- selectedItem,
17544
- duration: totalDuration,
17545
- currentTime,
17546
- playerState,
17547
- togglePlayback,
17548
- canUndo,
17549
- canRedo,
17550
- onDelete: deleteItem,
17551
- onSplit: splitElement,
17552
- onUndo: handleUndo,
17553
- onRedo: handleRedo
17554
- }
17555
- ),
17556
- /* @__PURE__ */ jsxRuntime.jsx(TimelineZoom, { zoomLevel: trackZoom, setZoomLevel: setTrackZoom })
17557
- ] });
17654
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "twick-editor-timeline-controls", children: /* @__PURE__ */ jsxRuntime.jsx(
17655
+ PlayerControls,
17656
+ {
17657
+ selectedItem,
17658
+ duration: totalDuration,
17659
+ currentTime,
17660
+ playerState,
17661
+ togglePlayback,
17662
+ canUndo,
17663
+ canRedo,
17664
+ onDelete: deleteItem,
17665
+ onSplit: splitElement,
17666
+ onUndo: handleUndo,
17667
+ onRedo: handleRedo,
17668
+ zoomLevel: trackZoom,
17669
+ setZoomLevel: setTrackZoom
17670
+ }
17671
+ ) });
17558
17672
  };
17559
17673
  const VideoEditor = ({
17560
17674
  leftPanel,
@@ -17565,27 +17679,26 @@ This message will only show in development mode. It won't appear in production.
17565
17679
  defaultPlayControls = true
17566
17680
  }) => {
17567
17681
  const [trackZoom, setTrackZoom] = React.useState(DEFAULT_TIMELINE_ZOOM);
17682
+ const useMemoizedPlayerManager = React.useMemo(
17683
+ () => /* @__PURE__ */ jsxRuntime.jsx(
17684
+ PlayerManager,
17685
+ {
17686
+ videoProps: editorConfig.videoProps,
17687
+ canvasMode: editorConfig.canvasMode ?? true
17688
+ }
17689
+ ),
17690
+ [editorConfig]
17691
+ );
17568
17692
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-editor-main-container", children: [
17569
17693
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-editor-view-section", children: [
17570
17694
  leftPanel ? leftPanel : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
17571
- /* @__PURE__ */ jsxRuntime.jsx(
17572
- PlayerManager,
17573
- {
17574
- videoProps: editorConfig.videoProps,
17575
- canvasMode: editorConfig.canvasMode ?? true
17576
- }
17577
- ),
17695
+ useMemoizedPlayerManager,
17578
17696
  rightPanel ? rightPanel : /* @__PURE__ */ jsxRuntime.jsx("div", {})
17579
17697
  ] }),
17580
17698
  bottomPanel ? bottomPanel : null,
17581
17699
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "twick-editor-timeline-section", children: [
17582
17700
  playControls ? playControls : defaultPlayControls ? /* @__PURE__ */ jsxRuntime.jsx(ControlManager, { trackZoom, setTrackZoom }) : null,
17583
- /* @__PURE__ */ jsxRuntime.jsx(
17584
- TimelineManager,
17585
- {
17586
- trackZoom
17587
- }
17588
- )
17701
+ /* @__PURE__ */ jsxRuntime.jsx(TimelineManager, { trackZoom })
17589
17702
  ] })
17590
17703
  ] });
17591
17704
  };
@@ -17756,7 +17869,7 @@ This message will only show in development mode. It won't appear in production.
17756
17869
  request.onsuccess = async () => {
17757
17870
  let items = request.result;
17758
17871
  const filteredItems = items.filter((item) => {
17759
- const matchesQuery = item.url.toLowerCase().includes(options.query.toLowerCase());
17872
+ const matchesQuery = item.url.toLowerCase().includes((options.query || "").toLowerCase());
17760
17873
  const matchesType = !options.type || item.type === options.type;
17761
17874
  const matchesMetadata = !options.metadata || Object.entries(options.metadata).every(
17762
17875
  ([key, value]) => {
@@ -17810,9 +17923,14 @@ This message will only show in development mode. It won't appear in production.
17810
17923
  {
17811
17924
  name: "fade",
17812
17925
  interval: 1,
17926
+ duration: 1,
17927
+ intensity: 1,
17813
17928
  animate: "enter",
17814
17929
  options: {
17815
- animate: ["enter", "exit", "both"]
17930
+ animate: ["enter", "exit", "both"],
17931
+ interval: [0.1, 5],
17932
+ duration: [0.1, 5],
17933
+ intensity: [0.1, 2]
17816
17934
  },
17817
17935
  getSample: () => {
17818
17936
  return animationGifs.fade;
@@ -17821,11 +17939,16 @@ This message will only show in development mode. It won't appear in production.
17821
17939
  {
17822
17940
  name: "rise",
17823
17941
  interval: 1,
17942
+ duration: 1,
17943
+ intensity: 1,
17824
17944
  animate: "enter",
17825
17945
  direction: "up",
17826
17946
  options: {
17827
17947
  animate: ["enter", "exit", "both"],
17828
- direction: ["up", "down"]
17948
+ direction: ["up", "down", "left", "right", "center"],
17949
+ interval: [0.1, 5],
17950
+ duration: [0.1, 5],
17951
+ intensity: [1, 300]
17829
17952
  },
17830
17953
  getSample: (animation) => {
17831
17954
  return (animation == null ? void 0 : animation.direction) === "down" ? animationGifs["rise-down"] : animationGifs["rise-up"];
@@ -17834,9 +17957,14 @@ This message will only show in development mode. It won't appear in production.
17834
17957
  {
17835
17958
  name: "blur",
17836
17959
  interval: 1,
17960
+ duration: 1,
17961
+ intensity: 1,
17837
17962
  animate: "enter",
17838
17963
  options: {
17839
- animate: ["enter", "exit", "both"]
17964
+ animate: ["enter", "exit", "both"],
17965
+ interval: [0.1, 5],
17966
+ duration: [0.1, 5],
17967
+ intensity: [0.1, 100]
17840
17968
  },
17841
17969
  getSample: () => {
17842
17970
  return animationGifs.blur;
@@ -17845,11 +17973,16 @@ This message will only show in development mode. It won't appear in production.
17845
17973
  {
17846
17974
  name: "breathe",
17847
17975
  interval: 1,
17976
+ duration: 1,
17977
+ intensity: 1,
17848
17978
  mode: "in",
17849
17979
  animate: "enter",
17850
17980
  options: {
17851
17981
  animate: ["enter", "exit", "both"],
17852
- mode: ["in", "out"]
17982
+ mode: ["in", "out"],
17983
+ interval: [0.1, 5],
17984
+ duration: [0.1, 5],
17985
+ intensity: [0.1, 2]
17853
17986
  },
17854
17987
  getSample: (animation) => {
17855
17988
  return (animation == null ? void 0 : animation.mode) === "out" ? animationGifs["breathe-out"] : animationGifs["breathe-in"];
@@ -17858,9 +17991,14 @@ This message will only show in development mode. It won't appear in production.
17858
17991
  {
17859
17992
  name: "succession",
17860
17993
  interval: 1,
17994
+ duration: 1,
17995
+ intensity: 1,
17861
17996
  animate: "enter",
17862
17997
  options: {
17863
- animate: ["enter", "exit", "both"]
17998
+ animate: ["enter", "exit", "both"],
17999
+ interval: [0.1, 5],
18000
+ duration: [0.1, 5],
18001
+ intensity: [0.1, 2]
17864
18002
  },
17865
18003
  getSample: () => {
17866
18004
  return animationGifs.succession;
@@ -17871,6 +18009,7 @@ This message will only show in development mode. It won't appear in production.
17871
18009
  {
17872
18010
  name: "typewriter",
17873
18011
  delay: 0,
18012
+ duration: 1,
17874
18013
  bufferTime: 0.1,
17875
18014
  getSample: () => {
17876
18015
  return "";
@@ -17879,6 +18018,7 @@ This message will only show in development mode. It won't appear in production.
17879
18018
  {
17880
18019
  name: "erase",
17881
18020
  delay: 0,
18021
+ duration: 1,
17882
18022
  bufferTime: 0.1,
17883
18023
  getSample: () => {
17884
18024
  return "";
@@ -17887,6 +18027,7 @@ This message will only show in development mode. It won't appear in production.
17887
18027
  {
17888
18028
  name: "elastic",
17889
18029
  delay: 0,
18030
+ duration: 1,
17890
18031
  bufferTime: 0.1,
17891
18032
  getSample: () => {
17892
18033
  return "";
@@ -17895,6 +18036,7 @@ This message will only show in development mode. It won't appear in production.
17895
18036
  {
17896
18037
  name: "stream-word",
17897
18038
  delay: 0,
18039
+ duration: 1,
17898
18040
  bufferTime: 0.1,
17899
18041
  getSample: () => {
17900
18042
  return "";
@@ -17916,6 +18058,7 @@ This message will only show in development mode. It won't appear in production.
17916
18058
  exports2.animationGifs = animationGifs;
17917
18059
  exports2.default = VideoEditor;
17918
18060
  exports2.getAnimationGif = getAnimationGif;
18061
+ exports2.setElementColors = setElementColors;
17919
18062
  exports2.usePlayerControl = usePlayerControl;
17920
18063
  exports2.useTimelineControl = useTimelineControl;
17921
18064
  Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });