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