@overtone-art/canvas-editor-core 0.8.6 → 0.9.0

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/node.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { g as EditorState } from './types-F2GH3dcU.mjs';
1
+ import { h as EditorState } from './specs-B_jOmY6u.mjs';
2
+ export { I as IMAGE_FILTER_PRESETS, aC as imageEffectsFilterSpecs } from './specs-B_jOmY6u.mjs';
2
3
  import 'fabric';
3
4
 
4
5
  interface PrintPdfOptions {
package/dist/node.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { g as EditorState } from './types-F2GH3dcU.js';
1
+ import { h as EditorState } from './specs-B_jOmY6u.js';
2
+ export { I as IMAGE_FILTER_PRESETS, aC as imageEffectsFilterSpecs } from './specs-B_jOmY6u.js';
2
3
  import 'fabric';
3
4
 
4
5
  interface PrintPdfOptions {
package/dist/node.js CHANGED
@@ -679,9 +679,261 @@ var init_print = __esm({
679
679
  }
680
680
  });
681
681
 
682
+ // src/image-effects/presets.ts
683
+ function imageFilterPreset(id) {
684
+ return IMAGE_FILTER_PRESETS.find((preset) => preset.id === id);
685
+ }
686
+ var LUMA, rows, IMAGE_FILTER_PRESETS;
687
+ var init_presets = __esm({
688
+ "src/image-effects/presets.ts"() {
689
+ "use strict";
690
+ LUMA = [0.299, 0.587, 0.114];
691
+ rows = (r, g, b) => [...r, ...g, ...b, 0, 0, 0, 1, 0];
692
+ IMAGE_FILTER_PRESETS = [
693
+ { id: "original", name: "Original", version: 1, adjust: {} },
694
+ {
695
+ id: "black-white",
696
+ name: "Black & White",
697
+ version: 1,
698
+ adjust: {},
699
+ matrix: rows([...LUMA, 0, 0], [...LUMA, 0, 0], [...LUMA, 0, 0])
700
+ },
701
+ {
702
+ id: "sepia",
703
+ name: "Sepia",
704
+ version: 1,
705
+ adjust: {},
706
+ matrix: rows(
707
+ [0.393, 0.769, 0.189, 0, 0],
708
+ [0.349, 0.686, 0.168, 0, 0],
709
+ [0.272, 0.534, 0.131, 0, 0]
710
+ )
711
+ },
712
+ {
713
+ id: "fade",
714
+ name: "Fade",
715
+ version: 1,
716
+ adjust: { contrast: -0.2, saturation: -0.25, brightness: 0.08 }
717
+ },
718
+ {
719
+ id: "vivid",
720
+ name: "Vivid",
721
+ version: 1,
722
+ adjust: { vibrance: 0.5, contrast: 0.15, saturation: 0.15 }
723
+ },
724
+ { id: "fuchsia", name: "Fuchsia", version: 1, adjust: { tint: 0.5, saturation: 0.2 } },
725
+ { id: "cool", name: "Cool", version: 1, adjust: { temperature: -0.45 } },
726
+ { id: "warm", name: "Warm", version: 1, adjust: { temperature: 0.45 } },
727
+ {
728
+ id: "duotone",
729
+ name: "Duotone",
730
+ version: 1,
731
+ adjust: {},
732
+ matrix: rows(
733
+ [0.2544, 0.4995, 0.097, 0, 0.1059],
734
+ [0.2216, 0.435, 0.0845, 0, 0.1647],
735
+ [0.1453, 0.2853, 0.0554, 0, 0.2863]
736
+ )
737
+ },
738
+ {
739
+ id: "nashville",
740
+ name: "Nashville",
741
+ version: 1,
742
+ adjust: { temperature: 0.25, tint: -0.1, contrast: 0.2, saturation: 0.15, brightness: 0.05 }
743
+ },
744
+ {
745
+ id: "valencia",
746
+ name: "Valencia",
747
+ version: 1,
748
+ adjust: { temperature: 0.2, contrast: 0.08, brightness: 0.08, saturation: -0.05 }
749
+ },
750
+ {
751
+ id: "clarendon",
752
+ name: "Clarendon",
753
+ version: 1,
754
+ adjust: { contrast: 0.2, saturation: 0.35, temperature: -0.1 }
755
+ },
756
+ {
757
+ id: "reyes",
758
+ name: "Reyes",
759
+ version: 1,
760
+ adjust: { brightness: 0.1, contrast: -0.15, saturation: -0.35, temperature: 0.15 }
761
+ },
762
+ {
763
+ id: "lark",
764
+ name: "Lark",
765
+ version: 1,
766
+ adjust: { brightness: 0.08, contrast: -0.05, saturation: 0.1, temperature: -0.15 }
767
+ },
768
+ {
769
+ id: "juno",
770
+ name: "Juno",
771
+ version: 1,
772
+ adjust: { saturation: 0.3, contrast: 0.1, temperature: 0.15, tint: 0.1 }
773
+ }
774
+ ];
775
+ }
776
+ });
777
+
778
+ // src/utils/clamp.ts
779
+ function clamp(v, min, max) {
780
+ return Math.min(max, Math.max(min, v));
781
+ }
782
+ var init_clamp = __esm({
783
+ "src/utils/clamp.ts"() {
784
+ "use strict";
785
+ }
786
+ });
787
+
788
+ // src/image-effects/types.ts
789
+ var ADJUST_KEYS, NEUTRAL_ADJUST, ADJUST_RANGES;
790
+ var init_types = __esm({
791
+ "src/image-effects/types.ts"() {
792
+ "use strict";
793
+ ADJUST_KEYS = [
794
+ "temperature",
795
+ "tint",
796
+ "brightness",
797
+ "contrast",
798
+ "highlights",
799
+ "shadows",
800
+ "whites",
801
+ "blacks",
802
+ "invert",
803
+ "vibrance",
804
+ "saturation",
805
+ "hue",
806
+ "sharpness",
807
+ "clarity",
808
+ "vignette",
809
+ "blur",
810
+ "noise",
811
+ "pixelate"
812
+ ];
813
+ NEUTRAL_ADJUST = Object.fromEntries(
814
+ ADJUST_KEYS.map((k) => [k, 0])
815
+ );
816
+ ADJUST_RANGES = {
817
+ invert: [0, 1],
818
+ vignette: [0, 1],
819
+ blur: [0, 1],
820
+ noise: [0, 1],
821
+ pixelate: [0, 1]
822
+ };
823
+ }
824
+ });
825
+
826
+ // src/image-effects/specs.ts
827
+ function clampAdjust(adjust) {
828
+ const out = {};
829
+ for (const key of ADJUST_KEYS) {
830
+ const value = adjust[key];
831
+ if (typeof value !== "number" || !Number.isFinite(value)) continue;
832
+ const [min, max] = ADJUST_RANGES[key] ?? [-1, 1];
833
+ out[key] = key === "invert" ? value >= 0.5 ? 1 : 0 : clamp(value, min, max);
834
+ }
835
+ return out;
836
+ }
837
+ function clampAlphaClip(clip) {
838
+ if (!clip || typeof clip !== "object") return void 0;
839
+ const high = clamp(Number(clip.high) || 0, 1, 255);
840
+ const low = clamp(Math.min(Number(clip.low) || 0, high - 1), 0, 254);
841
+ return low === 0 && high === 255 ? void 0 : { low, high };
842
+ }
843
+ function alphaClipMatrix({ low, high }) {
844
+ const span = Math.max(1, high - low);
845
+ return [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 255 / span, -low / span];
846
+ }
847
+ function specFor(key, v) {
848
+ if (v === 0) return null;
849
+ switch (key) {
850
+ case "highlights":
851
+ return { type: "Highlights", amount: v };
852
+ case "shadows":
853
+ return { type: "Shadows", amount: v };
854
+ case "whites":
855
+ return { type: "Whites", amount: v };
856
+ case "blacks":
857
+ return { type: "Blacks", amount: v };
858
+ case "brightness":
859
+ return { type: "Brightness", brightness: v };
860
+ case "contrast":
861
+ return { type: "Contrast", contrast: v };
862
+ case "temperature":
863
+ return { type: "Temperature", amount: v };
864
+ case "tint":
865
+ return { type: "Tint", amount: v };
866
+ case "vibrance":
867
+ return { type: "Vibrance", vibrance: v };
868
+ case "saturation":
869
+ return { type: "Saturation", saturation: v };
870
+ case "hue":
871
+ return { type: "HueRotation", rotation: v };
872
+ case "invert":
873
+ return { type: "Invert", alpha: false, invert: true };
874
+ case "clarity":
875
+ return { type: "Clarity", amount: v };
876
+ case "sharpness":
877
+ return { type: "Convolute", opaque: false, matrix: [0, -v, 0, -v, 1 + 4 * v, -v, 0, -v, 0] };
878
+ case "noise":
879
+ return { type: "Noise", noise: Math.round(v * 300) };
880
+ case "pixelate":
881
+ return { type: "Pixelate", blocksize: Math.max(1, Math.round(1 + v * 40)) };
882
+ case "blur":
883
+ return { type: "Blur", blur: v };
884
+ case "vignette":
885
+ return { type: "Vignette", amount: v };
886
+ }
887
+ }
888
+ function imageEffectsFilterSpecs(state) {
889
+ const specs = [];
890
+ const preset = state.preset ? imageFilterPreset(state.preset.id) : void 0;
891
+ if (preset?.matrix)
892
+ specs.push({ type: "ColorMatrix", matrix: [...preset.matrix], colorsOnly: true });
893
+ const adjust = clampAdjust(state.adjust);
894
+ for (const key of ORDER) {
895
+ const spec = specFor(key, adjust[key] ?? 0);
896
+ if (spec) specs.push(spec);
897
+ }
898
+ const clip = clampAlphaClip(state.alphaClip);
899
+ if (clip) specs.push({ type: "ColorMatrix", matrix: alphaClipMatrix(clip), colorsOnly: false });
900
+ return specs;
901
+ }
902
+ var ORDER;
903
+ var init_specs = __esm({
904
+ "src/image-effects/specs.ts"() {
905
+ "use strict";
906
+ init_clamp();
907
+ init_presets();
908
+ init_types();
909
+ ORDER = [
910
+ "highlights",
911
+ "shadows",
912
+ "whites",
913
+ "blacks",
914
+ "brightness",
915
+ "contrast",
916
+ "temperature",
917
+ "tint",
918
+ "vibrance",
919
+ "saturation",
920
+ "hue",
921
+ "invert",
922
+ "clarity",
923
+ "sharpness",
924
+ "noise",
925
+ "pixelate",
926
+ "blur",
927
+ "vignette"
928
+ ];
929
+ }
930
+ });
931
+
682
932
  // src/node.ts
683
933
  var node_exports = {};
684
934
  __export(node_exports, {
935
+ IMAGE_FILTER_PRESETS: () => IMAGE_FILTER_PRESETS,
936
+ imageEffectsFilterSpecs: () => imageEffectsFilterSpecs,
685
937
  renderEditorState: () => renderEditorState,
686
938
  renderEditorStateBatch: () => renderEditorStateBatch,
687
939
  renderMockupState: () => renderMockupState,
@@ -936,14 +1188,19 @@ async function renderEditorStateBatch(states, options = {}) {
936
1188
  async function renderMockupStateBatch(states, options = {}) {
937
1189
  return renderBatch(states, options, renderMockupState);
938
1190
  }
939
- var import_node, ALLOWED_PROTOCOLS, URL_KEYS;
1191
+ var import_node, fabricNode, import_canvas_editor_effects, ALLOWED_PROTOCOLS, URL_KEYS;
940
1192
  var init_node = __esm({
941
1193
  "src/node.ts"() {
942
1194
  import_node = require("fabric/node");
1195
+ fabricNode = __toESM(require("fabric/node"));
1196
+ import_canvas_editor_effects = require("@overtone-art/canvas-editor-effects");
943
1197
  init_export();
944
1198
  init_displacement();
945
1199
  init_text_wrap();
946
1200
  init_print();
1201
+ init_presets();
1202
+ init_specs();
1203
+ (0, import_canvas_editor_effects.registerEffects)(fabricNode);
947
1204
  ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "data:"]);
948
1205
  URL_KEYS = /* @__PURE__ */ new Set(["src", "image"]);
949
1206
  }
@@ -951,6 +1208,8 @@ var init_node = __esm({
951
1208
  init_node();
952
1209
  // Annotate the CommonJS export names for ESM import in node:
953
1210
  0 && (module.exports = {
1211
+ IMAGE_FILTER_PRESETS,
1212
+ imageEffectsFilterSpecs,
954
1213
  renderEditorState,
955
1214
  renderEditorStateBatch,
956
1215
  renderMockupState,