@twick/canvas 0.15.26 → 0.15.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -72,6 +72,8 @@ const ELEMENT_TYPES = {
72
72
  CIRCLE: "circle",
73
73
  /** Icon element type */
74
74
  ICON: "icon",
75
+ /** Emoji sticker element type */
76
+ EMOJI: "emoji",
75
77
  /** Arrow annotation element type */
76
78
  ARROW: "arrow",
77
79
  /** Line annotation / shape element type */
@@ -322,6 +324,24 @@ const rotateControl = new fabric.Control({
322
324
  /** Whether to show connection line */
323
325
  withConnection: true
324
326
  });
327
+ const COLOR_FILTERS = {
328
+ SATURATED: "saturated",
329
+ BRIGHT: "bright",
330
+ VIBRANT: "vibrant",
331
+ RETRO: "retro",
332
+ BLACK_WHITE: "blackWhite",
333
+ SEPIA: "sepia",
334
+ COOL: "cool",
335
+ WARM: "warm",
336
+ CINEMATIC: "cinematic",
337
+ SOFT_GLOW: "softGlow",
338
+ MOODY: "moody",
339
+ DREAMY: "dreamy",
340
+ INVERTED: "inverted",
341
+ VINTAGE: "vintage",
342
+ DRAMATIC: "dramatic",
343
+ FADED: "faded"
344
+ };
325
345
  class LRUCache {
326
346
  constructor(maxSize = 100) {
327
347
  if (maxSize <= 0) {
@@ -705,6 +725,275 @@ const getObjectFitSize = (objectFit, elementSize, containerSize) => {
705
725
  };
706
726
  }
707
727
  };
728
+ const {
729
+ Blur,
730
+ Brightness,
731
+ ColorMatrix,
732
+ Contrast,
733
+ Grayscale,
734
+ HueRotation,
735
+ Invert,
736
+ Saturation,
737
+ Sepia
738
+ } = fabric.filters;
739
+ let canvas2dFilterBackendInstalled = false;
740
+ function ensureCanvas2dImageFilterBackend() {
741
+ if (canvas2dFilterBackendInstalled) return;
742
+ canvas2dFilterBackendInstalled = true;
743
+ fabric.setFilterBackend(new fabric.Canvas2dFilterBackend());
744
+ }
745
+ function getSourceBitmapSize(img) {
746
+ const el = img.getElement();
747
+ if (!el) return null;
748
+ const w = "naturalWidth" in el && el.naturalWidth > 0 ? el.naturalWidth : el.width;
749
+ const h = "naturalHeight" in el && el.naturalHeight > 0 ? el.naturalHeight : el.height;
750
+ if (!w || !h) return null;
751
+ return { w, h };
752
+ }
753
+ function applyFiltersSafe(img) {
754
+ ensureCanvas2dImageFilterBackend();
755
+ img.applyFilters();
756
+ }
757
+ const bright = (m) => Math.min(1, Math.max(-1, (m - 1) * 0.48));
758
+ const contr = (m) => Math.min(1, Math.max(-1, (m - 1) * 0.55));
759
+ const sat = (m) => Math.min(1, Math.max(-1, (m - 1) * 0.72));
760
+ const IDENTITY = [
761
+ 1,
762
+ 0,
763
+ 0,
764
+ 0,
765
+ 0,
766
+ 0,
767
+ 1,
768
+ 0,
769
+ 0,
770
+ 0,
771
+ 0,
772
+ 0,
773
+ 1,
774
+ 0,
775
+ 0,
776
+ 0,
777
+ 0,
778
+ 0,
779
+ 1,
780
+ 0
781
+ ];
782
+ const SEPIA_MATRIX = [
783
+ 0.393,
784
+ 0.769,
785
+ 0.189,
786
+ 0,
787
+ 0,
788
+ 0.349,
789
+ 0.686,
790
+ 0.168,
791
+ 0,
792
+ 0,
793
+ 0.272,
794
+ 0.534,
795
+ 0.131,
796
+ 0,
797
+ 0,
798
+ 0,
799
+ 0,
800
+ 0,
801
+ 1,
802
+ 0
803
+ ];
804
+ function sepiaMix(strength) {
805
+ const t = Math.min(1, Math.max(0, strength));
806
+ const m = IDENTITY.map((v, i) => v + (SEPIA_MATRIX[i] - v) * t);
807
+ return new ColorMatrix({ matrix: m, colorsOnly: true });
808
+ }
809
+ const twickBlurToFabric = (v) => Math.min(0.22, Math.max(0, v * 0.045));
810
+ function buildFilters(filterType) {
811
+ switch (filterType) {
812
+ case COLOR_FILTERS.SATURATED:
813
+ return {
814
+ filters: [
815
+ new Saturation({ saturation: sat(1.4) }),
816
+ new Contrast({ contrast: contr(1.1) })
817
+ ],
818
+ opacityFactor: 1
819
+ };
820
+ case COLOR_FILTERS.BRIGHT:
821
+ return {
822
+ filters: [
823
+ new Brightness({ brightness: bright(1.3) }),
824
+ new Contrast({ contrast: contr(1.05) })
825
+ ],
826
+ opacityFactor: 1
827
+ };
828
+ case COLOR_FILTERS.VIBRANT:
829
+ return {
830
+ filters: [
831
+ new Saturation({ saturation: sat(1.6) }),
832
+ new Brightness({ brightness: bright(1.15) }),
833
+ new Contrast({ contrast: contr(1.1) })
834
+ ],
835
+ opacityFactor: 1
836
+ };
837
+ case COLOR_FILTERS.RETRO:
838
+ return {
839
+ filters: [
840
+ sepiaMix(0.8),
841
+ new Contrast({ contrast: contr(1.3) }),
842
+ new Brightness({ brightness: bright(0.85) }),
843
+ new Saturation({ saturation: sat(0.8) })
844
+ ],
845
+ opacityFactor: 1
846
+ };
847
+ case COLOR_FILTERS.BLACK_WHITE:
848
+ return {
849
+ filters: [
850
+ new Grayscale(),
851
+ new Contrast({ contrast: contr(1.25) }),
852
+ new Brightness({ brightness: bright(1.05) })
853
+ ],
854
+ opacityFactor: 1
855
+ };
856
+ case COLOR_FILTERS.SEPIA:
857
+ return {
858
+ filters: [
859
+ new Sepia(),
860
+ new Contrast({ contrast: contr(1.08) })
861
+ ],
862
+ opacityFactor: 1
863
+ };
864
+ case COLOR_FILTERS.COOL:
865
+ return {
866
+ filters: [
867
+ new HueRotation({ rotation: 15 / 180 }),
868
+ new Brightness({ brightness: bright(1.1) }),
869
+ new Saturation({ saturation: sat(1.3) }),
870
+ new Contrast({ contrast: contr(1.05) })
871
+ ],
872
+ opacityFactor: 1
873
+ };
874
+ case COLOR_FILTERS.WARM:
875
+ return {
876
+ filters: [
877
+ new HueRotation({ rotation: -15 / 180 }),
878
+ new Brightness({ brightness: bright(1.15) }),
879
+ new Saturation({ saturation: sat(1.3) }),
880
+ new Contrast({ contrast: contr(1.05) })
881
+ ],
882
+ opacityFactor: 1
883
+ };
884
+ case COLOR_FILTERS.CINEMATIC:
885
+ return {
886
+ filters: [
887
+ new Contrast({ contrast: contr(1.4) }),
888
+ new Brightness({ brightness: bright(0.95) }),
889
+ new Saturation({ saturation: sat(0.85) }),
890
+ sepiaMix(0.2)
891
+ ],
892
+ opacityFactor: 1
893
+ };
894
+ case COLOR_FILTERS.SOFT_GLOW:
895
+ return {
896
+ filters: [
897
+ new Brightness({ brightness: bright(1.2) }),
898
+ new Contrast({ contrast: contr(0.95) }),
899
+ new Blur({ blur: twickBlurToFabric(1.2) }),
900
+ new Saturation({ saturation: sat(1.1) })
901
+ ],
902
+ opacityFactor: 1
903
+ };
904
+ case COLOR_FILTERS.MOODY:
905
+ return {
906
+ filters: [
907
+ new Brightness({ brightness: bright(1.05) }),
908
+ new Contrast({ contrast: contr(1.4) }),
909
+ new Saturation({ saturation: sat(0.65) }),
910
+ sepiaMix(0.2)
911
+ ],
912
+ opacityFactor: 1
913
+ };
914
+ case COLOR_FILTERS.DREAMY:
915
+ return {
916
+ filters: [
917
+ new Brightness({ brightness: bright(1.3) }),
918
+ new Blur({ blur: twickBlurToFabric(2) }),
919
+ new Saturation({ saturation: sat(1.4) }),
920
+ new Contrast({ contrast: contr(0.95) })
921
+ ],
922
+ opacityFactor: 1
923
+ };
924
+ case COLOR_FILTERS.INVERTED:
925
+ return {
926
+ filters: [
927
+ new Invert({ invert: true, alpha: false }),
928
+ new HueRotation({ rotation: 1 })
929
+ ],
930
+ opacityFactor: 1
931
+ };
932
+ case COLOR_FILTERS.VINTAGE:
933
+ return {
934
+ filters: [
935
+ sepiaMix(0.4),
936
+ new Saturation({ saturation: sat(1.4) }),
937
+ new Contrast({ contrast: contr(1.2) }),
938
+ new Brightness({ brightness: bright(1.1) })
939
+ ],
940
+ opacityFactor: 1
941
+ };
942
+ case COLOR_FILTERS.DRAMATIC:
943
+ return {
944
+ filters: [
945
+ new Contrast({ contrast: contr(1.5) }),
946
+ new Brightness({ brightness: bright(0.9) }),
947
+ new Saturation({ saturation: sat(1.2) })
948
+ ],
949
+ opacityFactor: 1
950
+ };
951
+ case COLOR_FILTERS.FADED:
952
+ return {
953
+ filters: [
954
+ new Brightness({ brightness: bright(1.2) }),
955
+ new Saturation({ saturation: sat(0.8) }),
956
+ new Contrast({ contrast: contr(0.9) })
957
+ ],
958
+ opacityFactor: 0.9
959
+ };
960
+ default:
961
+ return { filters: [], opacityFactor: 1 };
962
+ }
963
+ }
964
+ function applyFabricMediaColorFilters(img, mediaFilter, elementOpacity) {
965
+ const key = (mediaFilter == null ? void 0 : mediaFilter.trim()) || "none";
966
+ if (key === "none") {
967
+ img.filters = [];
968
+ img.set("opacity", elementOpacity);
969
+ applyFiltersSafe(img);
970
+ return;
971
+ }
972
+ const { filters: filterList, opacityFactor } = buildFilters(key);
973
+ if (filterList.length === 0) {
974
+ img.filters = [];
975
+ img.set("opacity", elementOpacity);
976
+ applyFiltersSafe(img);
977
+ return;
978
+ }
979
+ if (!getSourceBitmapSize(img)) {
980
+ img.filters = [];
981
+ img.set("opacity", elementOpacity);
982
+ return;
983
+ }
984
+ img.filters = filterList;
985
+ img.set("opacity", elementOpacity * opacityFactor);
986
+ try {
987
+ applyFiltersSafe(img);
988
+ } catch {
989
+ img.filters = [];
990
+ img.set("opacity", elementOpacity);
991
+ try {
992
+ applyFiltersSafe(img);
993
+ } catch {
994
+ }
995
+ }
996
+ }
708
997
  const MARGIN = 10;
709
998
  const addTextElement = ({
710
999
  element,
@@ -795,7 +1084,7 @@ const setImageProps = ({
795
1084
  canvasMetadata,
796
1085
  lockAspectRatio = true
797
1086
  }) => {
798
- var _a, _b, _c, _d, _e;
1087
+ var _a, _b, _c, _d, _e, _f;
799
1088
  const width = (((_a = element.props) == null ? void 0 : _a.width) || 0) * canvasMetadata.scaleX || canvasMetadata.width;
800
1089
  const height = (((_b = element.props) == null ? void 0 : _b.height) || 0) * canvasMetadata.scaleY || canvasMetadata.height;
801
1090
  const { x, y } = convertToCanvasPosition(
@@ -809,11 +1098,15 @@ const setImageProps = ({
809
1098
  img.set("height", height);
810
1099
  img.set("left", x);
811
1100
  img.set("top", y);
812
- img.set("opacity", ((_e = element.props) == null ? void 0 : _e.opacity) ?? 1);
813
1101
  img.set("selectable", true);
814
1102
  img.set("hasControls", true);
815
1103
  img.set("touchAction", "all");
816
1104
  img.set("lockUniScaling", lockAspectRatio);
1105
+ applyFabricMediaColorFilters(
1106
+ img,
1107
+ (_e = element.props) == null ? void 0 : _e.mediaFilter,
1108
+ ((_f = element.props) == null ? void 0 : _f.opacity) ?? 1
1109
+ );
817
1110
  };
818
1111
  const addCaptionElement = ({
819
1112
  element,
@@ -823,48 +1116,52 @@ const addCaptionElement = ({
823
1116
  canvasMetadata,
824
1117
  lockAspectRatio = false
825
1118
  }) => {
826
- 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, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L;
827
- const applyToAll = (captionProps == null ? void 0 : captionProps.applyToAll) ?? false;
828
- const captionTextColor = ((_a = captionProps == null ? void 0 : captionProps.colors) == null ? void 0 : _a.text) ?? ((_b = captionProps == null ? void 0 : captionProps.color) == null ? void 0 : _b.text);
1119
+ 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;
1120
+ const useTrackDefaults = ((_a = element.props) == null ? void 0 : _a.useTrackDefaults) ?? true;
1121
+ const trackColors = captionProps == null ? void 0 : captionProps.colors;
1122
+ const elementColors = (_b = element.props) == null ? void 0 : _b.colors;
1123
+ const resolvedColors = useTrackDefaults ? trackColors : { ...trackColors ?? {}, ...elementColors ?? {} };
1124
+ const captionTextColor = (resolvedColors == null ? void 0 : resolvedColors.text) ?? ((_c = captionProps == null ? void 0 : captionProps.color) == null ? void 0 : _c.text);
829
1125
  const { x, y } = convertToCanvasPosition(
830
- (applyToAll ? captionProps == null ? void 0 : captionProps.x : ((_c = element.props) == null ? void 0 : _c.x) ?? (captionProps == null ? void 0 : captionProps.x)) ?? 0,
831
- (applyToAll ? captionProps == null ? void 0 : captionProps.y : ((_d = element.props) == null ? void 0 : _d.y) ?? (captionProps == null ? void 0 : captionProps.y)) ?? 0,
1126
+ (useTrackDefaults ? captionProps == null ? void 0 : captionProps.x : (_d = element.props) == null ? void 0 : _d.x) ?? (captionProps == null ? void 0 : captionProps.x) ?? 0,
1127
+ (useTrackDefaults ? captionProps == null ? void 0 : captionProps.y : (_e = element.props) == null ? void 0 : _e.y) ?? (captionProps == null ? void 0 : captionProps.y) ?? 0,
832
1128
  canvasMetadata
833
1129
  );
834
- let width = ((_e = element.props) == null ? void 0 : _e.width) ? element.props.width * canvasMetadata.scaleX : canvasMetadata.width - 2 * MARGIN;
835
- if ((_f = element.props) == null ? void 0 : _f.maxWidth) {
1130
+ let width = ((_f = element.props) == null ? void 0 : _f.width) ? element.props.width * canvasMetadata.scaleX : canvasMetadata.width - 2 * MARGIN;
1131
+ if ((_g = element.props) == null ? void 0 : _g.maxWidth) {
836
1132
  width = Math.min(width, element.props.maxWidth * canvasMetadata.scaleX);
837
1133
  }
838
- const elementColors = (_g = element.props) == null ? void 0 : _g.colors;
839
- const resolvedFill = (applyToAll ? captionTextColor : ((_h = element.props) == null ? void 0 : _h.fill) ?? (elementColors == null ? void 0 : elementColors.text) ?? captionTextColor) ?? DEFAULT_CAPTION_PROPS.fill;
840
- const trackColors = captionProps == null ? void 0 : captionProps.colors;
1134
+ const resolvedFill = (useTrackDefaults ? void 0 : (_h = element.props) == null ? void 0 : _h.fill) ?? captionTextColor ?? DEFAULT_CAPTION_PROPS.fill;
841
1135
  const trackStroke = trackColors == null ? void 0 : trackColors.outlineColor;
842
1136
  const elementStroke = (elementColors == null ? void 0 : elementColors.outlineColor) ?? ((_i = element.props) == null ? void 0 : _i.stroke);
843
- const resolvedStroke = (applyToAll ? trackStroke ?? elementStroke : elementStroke ?? trackStroke) ?? void 0;
844
- const caption = new fabric.Textbox(((_j = element.props) == null ? void 0 : _j.text) || element.t || "", {
1137
+ const resolvedStroke = (useTrackDefaults ? trackStroke : elementStroke ?? trackStroke) ?? void 0;
1138
+ const trackFont = (captionProps == null ? void 0 : captionProps.font) ?? {};
1139
+ const elementFont = ((_j = element.props) == null ? void 0 : _j.font) ?? {};
1140
+ const resolvedFont = useTrackDefaults ? trackFont : { ...trackFont, ...elementFont };
1141
+ const caption = new fabric.Textbox(((_k = element.props) == null ? void 0 : _k.text) || element.t || "", {
845
1142
  left: x,
846
1143
  top: y,
847
1144
  originX: "center",
848
1145
  originY: "center",
849
- angle: ((_k = element.props) == null ? void 0 : _k.rotation) || 0,
1146
+ angle: ((_l = element.props) == null ? void 0 : _l.rotation) || 0,
850
1147
  fontSize: Math.round(
851
- ((applyToAll ? (_l = captionProps == null ? void 0 : captionProps.font) == null ? void 0 : _l.size : ((_n = (_m = element.props) == null ? void 0 : _m.font) == null ? void 0 : _n.size) ?? ((_o = captionProps == null ? void 0 : captionProps.font) == null ? void 0 : _o.size)) ?? DEFAULT_CAPTION_PROPS.size) * canvasMetadata.scaleX
1148
+ ((resolvedFont == null ? void 0 : resolvedFont.size) ?? DEFAULT_CAPTION_PROPS.size) * canvasMetadata.scaleX
852
1149
  ),
853
- fontFamily: (applyToAll ? (_p = captionProps == null ? void 0 : captionProps.font) == null ? void 0 : _p.family : ((_r = (_q = element.props) == null ? void 0 : _q.font) == null ? void 0 : _r.family) ?? ((_s = captionProps == null ? void 0 : captionProps.font) == null ? void 0 : _s.family)) ?? DEFAULT_CAPTION_PROPS.family,
1150
+ fontFamily: (resolvedFont == null ? void 0 : resolvedFont.family) ?? DEFAULT_CAPTION_PROPS.family,
854
1151
  fill: resolvedFill,
855
- fontWeight: (applyToAll ? (_t = captionProps == null ? void 0 : captionProps.font) == null ? void 0 : _t.weight : ((_v = (_u = element.props) == null ? void 0 : _u.font) == null ? void 0 : _v.weight) ?? ((_w = captionProps == null ? void 0 : captionProps.font) == null ? void 0 : _w.weight)) ?? DEFAULT_CAPTION_PROPS.fontWeight,
1152
+ fontWeight: (resolvedFont == null ? void 0 : resolvedFont.weight) ?? DEFAULT_CAPTION_PROPS.fontWeight,
856
1153
  ...resolvedStroke ? { stroke: resolvedStroke } : {},
857
- opacity: (applyToAll ? captionProps == null ? void 0 : captionProps.opacity : ((_x = element.props) == null ? void 0 : _x.opacity) ?? (captionProps == null ? void 0 : captionProps.opacity)) ?? 1,
1154
+ opacity: (useTrackDefaults ? void 0 : (_m = element.props) == null ? void 0 : _m.opacity) ?? (captionProps == null ? void 0 : captionProps.opacity) ?? 1,
858
1155
  width,
859
1156
  splitByGrapheme: false,
860
- textAlign: ((_y = element.props) == null ? void 0 : _y.textAlign) ?? "center",
1157
+ textAlign: ((_n = element.props) == null ? void 0 : _n.textAlign) ?? "center",
861
1158
  shadow: new fabric.Shadow({
862
- offsetX: (applyToAll ? (_z = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _z[0] : ((_B = (_A = element.props) == null ? void 0 : _A.shadowOffset) == null ? void 0 : _B[0]) ?? ((_C = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _C[0])) ?? ((_D = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _D[0]),
863
- offsetY: (applyToAll ? (_E = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _E[1] : ((_G = (_F = element.props) == null ? void 0 : _F.shadowOffset) == null ? void 0 : _G[1]) ?? ((_H = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _H[1])) ?? ((_I = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _I[1]),
864
- blur: (applyToAll ? captionProps == null ? void 0 : captionProps.shadowBlur : ((_J = element.props) == null ? void 0 : _J.shadowBlur) ?? (captionProps == null ? void 0 : captionProps.shadowBlur)) ?? DEFAULT_CAPTION_PROPS.shadowBlur,
865
- color: (applyToAll ? captionProps == null ? void 0 : captionProps.shadowColor : ((_K = element.props) == null ? void 0 : _K.shadowColor) ?? (captionProps == null ? void 0 : captionProps.shadowColor)) ?? DEFAULT_CAPTION_PROPS.shadowColor
1159
+ offsetX: (useTrackDefaults ? void 0 : (_p = (_o = element.props) == null ? void 0 : _o.shadowOffset) == null ? void 0 : _p[0]) ?? ((_q = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _q[0]) ?? ((_r = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _r[0]),
1160
+ offsetY: (useTrackDefaults ? void 0 : (_t = (_s = element.props) == null ? void 0 : _s.shadowOffset) == null ? void 0 : _t[1]) ?? ((_u = captionProps == null ? void 0 : captionProps.shadowOffset) == null ? void 0 : _u[1]) ?? ((_v = DEFAULT_CAPTION_PROPS.shadowOffset) == null ? void 0 : _v[1]),
1161
+ blur: (useTrackDefaults ? void 0 : (_w = element.props) == null ? void 0 : _w.shadowBlur) ?? (captionProps == null ? void 0 : captionProps.shadowBlur) ?? DEFAULT_CAPTION_PROPS.shadowBlur,
1162
+ color: (useTrackDefaults ? void 0 : (_x = element.props) == null ? void 0 : _x.shadowColor) ?? (captionProps == null ? void 0 : captionProps.shadowColor) ?? DEFAULT_CAPTION_PROPS.shadowColor
866
1163
  }),
867
- strokeWidth: ((applyToAll ? captionProps == null ? void 0 : captionProps.lineWidth : ((_L = element.props) == null ? void 0 : _L.lineWidth) ?? (captionProps == null ? void 0 : captionProps.lineWidth)) ?? DEFAULT_CAPTION_PROPS.lineWidth) * 0.025
1164
+ strokeWidth: ((useTrackDefaults ? void 0 : (_y = element.props) == null ? void 0 : _y.lineWidth) ?? (captionProps == null ? void 0 : captionProps.lineWidth) ?? DEFAULT_CAPTION_PROPS.lineWidth) * 0.025
868
1165
  });
869
1166
  caption.set("id", element.id);
870
1167
  caption.set("zIndex", index);
@@ -919,8 +1216,13 @@ const addImageElement = async ({
919
1216
  currentFrameEffect,
920
1217
  lockAspectRatio = true
921
1218
  }) => {
1219
+ var _a, _b;
922
1220
  try {
923
- const img = await fabric.FabricImage.fromURL(imageUrl || element.props.src || "");
1221
+ const rawSrc = imageUrl || element.props.src || "";
1222
+ const mediaFilter = (_b = (_a = element.props) == null ? void 0 : _a.mediaFilter) == null ? void 0 : _b.trim();
1223
+ const useFilter = !!mediaFilter && mediaFilter !== "none";
1224
+ const fromUrlOpts = useFilter && /^https?:\/\//i.test(rawSrc) ? { crossOrigin: "anonymous" } : {};
1225
+ const img = await fabric.FabricImage.fromURL(rawSrc, fromUrlOpts);
924
1226
  img.set({
925
1227
  originX: "center",
926
1228
  originY: "center",
@@ -957,7 +1259,7 @@ const addMediaGroup = ({
957
1259
  currentFrameEffect,
958
1260
  lockAspectRatio = true
959
1261
  }) => {
960
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1262
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
961
1263
  let frameSize;
962
1264
  let angle;
963
1265
  let framePosition;
@@ -1012,9 +1314,13 @@ const addMediaGroup = ({
1012
1314
  originX: "center",
1013
1315
  originY: "center",
1014
1316
  scaleX: newSize.width / img.width,
1015
- scaleY: newSize.height / img.height,
1016
- opacity: ((_n = element.props) == null ? void 0 : _n.opacity) ?? 1
1317
+ scaleY: newSize.height / img.height
1017
1318
  });
1319
+ applyFabricMediaColorFilters(
1320
+ img,
1321
+ (_n = element.props) == null ? void 0 : _n.mediaFilter,
1322
+ ((_o = element.props) == null ? void 0 : _o.opacity) ?? 1
1323
+ );
1018
1324
  const { x, y } = convertToCanvasPosition(
1019
1325
  (framePosition == null ? void 0 : framePosition.x) || 0,
1020
1326
  (framePosition == null ? void 0 : framePosition.y) || 0,
@@ -1500,7 +1806,8 @@ const CaptionElement = {
1500
1806
  context.canvasMetadata,
1501
1807
  context.videoSize
1502
1808
  );
1503
- if ((_a = context.captionPropsRef.current) == null ? void 0 : _a.applyToAll) {
1809
+ const useTrackDefaults = ((_a = element.props) == null ? void 0 : _a.useTrackDefaults) ?? true;
1810
+ if (useTrackDefaults) {
1504
1811
  return {
1505
1812
  element,
1506
1813
  operation: CANVAS_OPERATIONS.CAPTION_PROPS_UPDATED,
@@ -1717,6 +2024,72 @@ const EffectElement = {
1717
2024
  return;
1718
2025
  }
1719
2026
  };
2027
+ const EmojiElement = {
2028
+ name: ELEMENT_TYPES.EMOJI,
2029
+ async add(params) {
2030
+ var _a;
2031
+ const { element, index, canvas, canvasMetadata, lockAspectRatio } = params;
2032
+ await addImageElement({
2033
+ element,
2034
+ index,
2035
+ canvas,
2036
+ canvasMetadata,
2037
+ lockAspectRatio: lockAspectRatio ?? ((_a = element.props) == null ? void 0 : _a.lockAspectRatio) ?? true
2038
+ });
2039
+ },
2040
+ updateFromFabricObject(object, element, context) {
2041
+ const canvasCenter = getObjectCanvasCenter(object);
2042
+ const { x, y } = convertToVideoPosition(
2043
+ canvasCenter.x,
2044
+ canvasCenter.y,
2045
+ context.canvasMetadata,
2046
+ context.videoSize
2047
+ );
2048
+ if (object.type === "group") {
2049
+ const scaledW2 = (object.width ?? 0) * (object.scaleX ?? 1);
2050
+ const scaledH2 = (object.height ?? 0) * (object.scaleY ?? 1);
2051
+ const { width: fw, height: fh } = convertToVideoDimensions(
2052
+ scaledW2,
2053
+ scaledH2,
2054
+ context.canvasMetadata
2055
+ );
2056
+ const updatedFrameSize = [fw, fh];
2057
+ const frame = element.frame;
2058
+ return {
2059
+ element: {
2060
+ ...element,
2061
+ frame: {
2062
+ ...frame,
2063
+ rotation: getObjectCanvasAngle(object),
2064
+ size: updatedFrameSize,
2065
+ x,
2066
+ y
2067
+ }
2068
+ }
2069
+ };
2070
+ }
2071
+ const scaledW = (object.width ?? 0) * (object.scaleX ?? 1);
2072
+ const scaledH = (object.height ?? 0) * (object.scaleY ?? 1);
2073
+ const { width, height } = convertToVideoDimensions(
2074
+ scaledW,
2075
+ scaledH,
2076
+ context.canvasMetadata
2077
+ );
2078
+ return {
2079
+ element: {
2080
+ ...element,
2081
+ props: {
2082
+ ...element.props,
2083
+ rotation: getObjectCanvasAngle(object),
2084
+ width,
2085
+ height,
2086
+ x,
2087
+ y
2088
+ }
2089
+ }
2090
+ };
2091
+ }
2092
+ };
1720
2093
  class ElementController {
1721
2094
  constructor() {
1722
2095
  __publicField(this, "elements", /* @__PURE__ */ new Map());
@@ -1738,6 +2111,7 @@ function registerElements() {
1738
2111
  elementController.register(RectElement);
1739
2112
  elementController.register(CircleElement);
1740
2113
  elementController.register(TextElement);
2114
+ elementController.register(EmojiElement);
1741
2115
  elementController.register(CaptionElement);
1742
2116
  elementController.register(WatermarkElement);
1743
2117
  elementController.register(ArrowElement);