@twick/canvas 0.14.3 → 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
@@ -131,10 +131,19 @@ const reorderElementsByZIndex = (canvas) => {
131
131
  objects.forEach((obj) => canvas.add(obj));
132
132
  canvas.renderAll();
133
133
  };
134
+ const getCanvasContext = (canvas) => {
135
+ var _a, _b, _c, _d;
136
+ if (!canvas || !((_b = (_a = canvas.elements) == null ? void 0 : _a.lower) == null ? void 0 : _b.ctx)) return;
137
+ return (_d = (_c = canvas.elements) == null ? void 0 : _c.lower) == null ? void 0 : _d.ctx;
138
+ };
134
139
  const clearCanvas = (canvas) => {
135
- if (!canvas) return;
136
- canvas.clear();
137
- canvas.renderAll();
140
+ try {
141
+ if (!canvas || !getCanvasContext(canvas)) return;
142
+ canvas.clear();
143
+ canvas.renderAll();
144
+ } catch (error) {
145
+ console.warn("Error clearing canvas:", error);
146
+ }
138
147
  };
139
148
  const convertToCanvasPosition = (x, y, canvasMetadata) => {
140
149
  return {
@@ -280,7 +289,7 @@ const getThumbnail = async (videoUrl, seekTime = 0.1, playbackRate = 1) => {
280
289
  timeoutId = window.setTimeout(() => {
281
290
  cleanup();
282
291
  reject(new Error("Video loading timed out"));
283
- }, 5e3);
292
+ }, 15e3);
284
293
  video.src = videoUrl;
285
294
  document.body.appendChild(video);
286
295
  });
@@ -331,7 +340,7 @@ const addTextElement = ({
331
340
  canvas,
332
341
  canvasMetadata
333
342
  }) => {
334
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
343
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
335
344
  const { x, y } = convertToCanvasPosition(
336
345
  ((_a = element.props) == null ? void 0 : _a.x) || 0,
337
346
  ((_b = element.props) == null ? void 0 : _b.y) || 0,
@@ -350,15 +359,16 @@ const addTextElement = ({
350
359
  fontStyle: ((_g = element.props) == null ? void 0 : _g.fontStyle) || "normal",
351
360
  fontWeight: ((_h = element.props) == null ? void 0 : _h.fontWeight) || "normal",
352
361
  fill: ((_i = element.props) == null ? void 0 : _i.fill) || DEFAULT_TEXT_PROPS.fill,
362
+ opacity: ((_j = element.props) == null ? void 0 : _j.opacity) ?? 1,
353
363
  skipWrapping: false,
354
- textAlign: ((_j = element.props) == null ? void 0 : _j.textAlign) || "center",
355
- stroke: ((_k = element.props) == null ? void 0 : _k.stroke) || DEFAULT_TEXT_PROPS.stroke,
356
- strokeWidth: ((_l = element.props) == null ? void 0 : _l.lineWidth) || DEFAULT_TEXT_PROPS.lineWidth,
357
- shadow: ((_m = element.props) == null ? void 0 : _m.shadowColor) ? new fabric.Shadow({
358
- offsetX: ((_o = (_n = element.props) == null ? void 0 : _n.shadowOffset) == null ? void 0 : _o.length) && ((_q = (_p = element.props) == null ? void 0 : _p.shadowOffset) == null ? void 0 : _q.length) > 1 ? element.props.shadowOffset[0] / 2 : 1,
359
- offsetY: ((_s = (_r = element.props) == null ? void 0 : _r.shadowOffset) == null ? void 0 : _s.length) && ((_t = element.props) == null ? void 0 : _t.shadowOffset.length) > 1 ? element.props.shadowOffset[1] / 2 : 1,
360
- blur: (((_u = element.props) == null ? void 0 : _u.shadowBlur) || 2) / 2,
361
- color: (_v = element.props) == null ? void 0 : _v.shadowColor
364
+ textAlign: ((_k = element.props) == null ? void 0 : _k.textAlign) || "center",
365
+ stroke: ((_l = element.props) == null ? void 0 : _l.stroke) || DEFAULT_TEXT_PROPS.stroke,
366
+ strokeWidth: ((_m = element.props) == null ? void 0 : _m.lineWidth) || DEFAULT_TEXT_PROPS.lineWidth,
367
+ shadow: ((_n = element.props) == null ? void 0 : _n.shadowColor) ? new fabric.Shadow({
368
+ offsetX: ((_p = (_o = element.props) == null ? void 0 : _o.shadowOffset) == null ? void 0 : _p.length) && ((_r = (_q = element.props) == null ? void 0 : _q.shadowOffset) == null ? void 0 : _r.length) > 1 ? element.props.shadowOffset[0] / 2 : 1,
369
+ offsetY: ((_t = (_s = element.props) == null ? void 0 : _s.shadowOffset) == null ? void 0 : _t.length) && ((_u = element.props) == null ? void 0 : _u.shadowOffset.length) > 1 ? element.props.shadowOffset[1] / 2 : 1,
370
+ blur: (((_v = element.props) == null ? void 0 : _v.shadowBlur) || 2) / 2,
371
+ color: (_w = element.props) == null ? void 0 : _w.shadowColor
362
372
  }) : void 0
363
373
  });
364
374
  text.set("id", element.id);
@@ -381,7 +391,7 @@ const setImageProps = ({
381
391
  index,
382
392
  canvasMetadata
383
393
  }) => {
384
- var _a, _b, _c, _d;
394
+ var _a, _b, _c, _d, _e;
385
395
  const width = (((_a = element.props) == null ? void 0 : _a.width) || 0) * canvasMetadata.scaleX || canvasMetadata.width;
386
396
  const height = (((_b = element.props) == null ? void 0 : _b.height) || 0) * canvasMetadata.scaleY || canvasMetadata.height;
387
397
  const { x, y } = convertToCanvasPosition(
@@ -396,6 +406,7 @@ const setImageProps = ({
396
406
  img.set("height", height);
397
407
  img.set("left", x);
398
408
  img.set("top", y);
409
+ img.set("opacity", ((_e = element.props) == null ? void 0 : _e.opacity) ?? 1);
399
410
  img.set("selectable", true);
400
411
  img.set("hasControls", true);
401
412
  img.set("touchAction", "all");
@@ -407,7 +418,7 @@ const addCaptionElement = ({
407
418
  captionProps,
408
419
  canvasMetadata
409
420
  }) => {
410
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
421
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A;
411
422
  const { x, y } = convertToCanvasPosition(
412
423
  ((_b = (_a = element.props) == null ? void 0 : _a.pos) == null ? void 0 : _b.x) || ((_c = captionProps == null ? void 0 : captionProps.pos) == null ? void 0 : _c.x) || 0,
413
424
  ((_e = (_d = element.props) == null ? void 0 : _d.pos) == null ? void 0 : _e.y) || ((_f = captionProps == null ? void 0 : captionProps.pos) == null ? void 0 : _f.y) || 0,
@@ -426,13 +437,14 @@ const addCaptionElement = ({
426
437
  fill: ((_o = element.props) == null ? void 0 : _o.fill) || ((_p = captionProps.color) == null ? void 0 : _p.text) || DEFAULT_CAPTION_PROPS.fill,
427
438
  fontWeight: DEFAULT_CAPTION_PROPS.fontWeight,
428
439
  stroke: ((_q = element.props) == null ? void 0 : _q.stroke) || DEFAULT_CAPTION_PROPS.stroke,
440
+ opacity: ((_r = element.props) == null ? void 0 : _r.opacity) ?? 1,
429
441
  shadow: new fabric.Shadow({
430
- offsetX: ((_s = (_r = element.props) == null ? void 0 : _r.shadowOffset) == null ? void 0 : _s[0]) || ((_t = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _t[0]),
431
- 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]),
432
- blur: ((_x = element.props) == null ? void 0 : _x.shadowBlur) || DEFAULT_CAPTION_PROPS.shadowBlur,
433
- color: ((_y = element.props) == null ? void 0 : _y.shadowColor) || DEFAULT_CAPTION_PROPS.shadowColor
442
+ offsetX: ((_t = (_s = element.props) == null ? void 0 : _s.shadowOffset) == null ? void 0 : _t[0]) || ((_u = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _u[0]),
443
+ 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]),
444
+ blur: ((_y = element.props) == null ? void 0 : _y.shadowBlur) || DEFAULT_CAPTION_PROPS.shadowBlur,
445
+ color: ((_z = element.props) == null ? void 0 : _z.shadowColor) || DEFAULT_CAPTION_PROPS.shadowColor
434
446
  }),
435
- strokeWidth: ((_z = element.props) == null ? void 0 : _z.lineWidth) || DEFAULT_CAPTION_PROPS.lineWidth
447
+ strokeWidth: ((_A = element.props) == null ? void 0 : _A.lineWidth) || DEFAULT_CAPTION_PROPS.lineWidth
436
448
  });
437
449
  caption.set("id", element.id);
438
450
  caption.set("zIndex", index);
@@ -523,7 +535,7 @@ const addMediaGroup = ({
523
535
  canvasMetadata,
524
536
  currentFrameEffect
525
537
  }) => {
526
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
538
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
527
539
  let frameSize;
528
540
  let angle;
529
541
  let framePosition;
@@ -578,7 +590,8 @@ const addMediaGroup = ({
578
590
  originX: "center",
579
591
  originY: "center",
580
592
  scaleX: newSize.width / img.width,
581
- scaleY: newSize.height / img.height
593
+ scaleY: newSize.height / img.height,
594
+ opacity: ((_n = element.props) == null ? void 0 : _n.opacity) ?? 1
582
595
  });
583
596
  const { x, y } = convertToCanvasPosition(
584
597
  (framePosition == null ? void 0 : framePosition.x) || 0,
@@ -698,6 +711,7 @@ const useTwickCanvas = ({
698
711
  const elementFrameMap = react.useRef({});
699
712
  const twickCanvasRef = react.useRef(null);
700
713
  const videoSizeRef = react.useRef({ width: 1, height: 1 });
714
+ const canvasResolutionRef = react.useRef({ width: 1, height: 1 });
701
715
  const canvasMetadataRef = react.useRef({
702
716
  width: 0,
703
717
  height: 0,
@@ -721,9 +735,13 @@ const useTwickCanvas = ({
721
735
  selectionLineWidth = 2,
722
736
  uniScaleTransform = true,
723
737
  enableRetinaScaling = true,
724
- touchZoomThreshold = 10
738
+ touchZoomThreshold = 10,
739
+ forceBuild = false
725
740
  }) => {
726
741
  if (!canvasRef) return;
742
+ if (!forceBuild && canvasResolutionRef.current.width === canvasSize.width && canvasResolutionRef.current.height === canvasSize.height) {
743
+ return;
744
+ }
727
745
  if (twickCanvasRef.current) {
728
746
  console.log("Destroying twickCanvas");
729
747
  twickCanvasRef.current.off("mouse:up", handleMouseUp);
@@ -743,6 +761,7 @@ const useTwickCanvas = ({
743
761
  canvasMetadataRef.current = canvasMetadata;
744
762
  videoSizeRef.current = videoSize;
745
763
  canvas == null ? void 0 : canvas.on("mouse:up", handleMouseUp);
764
+ canvasResolutionRef.current = canvasSize;
746
765
  setTwickCanvas(canvas);
747
766
  twickCanvasRef.current = canvas;
748
767
  if (onCanvasReady) {
@@ -883,13 +902,18 @@ const useTwickCanvas = ({
883
902
  captionProps,
884
903
  cleanAndAdd = false
885
904
  }) => {
886
- if (!twickCanvas) {
887
- console.warn("Canvas not initialized");
905
+ if (!twickCanvas || !getCanvasContext(twickCanvas)) {
906
+ console.warn("Canvas not properly initialized");
888
907
  return;
889
908
  }
890
909
  try {
891
- if (cleanAndAdd) {
910
+ if (cleanAndAdd && getCanvasContext(twickCanvas)) {
911
+ const backgroundColor = twickCanvas.backgroundColor;
892
912
  clearCanvas(twickCanvas);
913
+ if (backgroundColor) {
914
+ twickCanvas.backgroundColor = backgroundColor;
915
+ twickCanvas.renderAll();
916
+ }
893
917
  }
894
918
  await Promise.all(
895
919
  elements.map(async (element, index) => {