sveltekit-ui 1.1.16 → 1.1.17

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.
Files changed (156) hide show
  1. package/package.json +1 -1
  2. package/dist/Components/ArrowToggle/index.svelte +0 -62
  3. package/dist/Components/Attachment/index.svelte +0 -77
  4. package/dist/Components/Attachment/index.svelte.js +0 -119
  5. package/dist/Components/AudioEditor/index.svelte +0 -252
  6. package/dist/Components/AudioEditor/index.svelte.js +0 -977
  7. package/dist/Components/AudioEditor/samples/alloy-voice-sample.mp3 +0 -0
  8. package/dist/Components/AudioEditor/samples/echo-voice-sample.mp3 +0 -0
  9. package/dist/Components/AudioEditor/samples/fable-voice-sample.mp3 +0 -0
  10. package/dist/Components/AudioEditor/samples/nova-voice-sample.mp3 +0 -0
  11. package/dist/Components/AudioEditor/samples/onyx-voice-sample.mp3 +0 -0
  12. package/dist/Components/AudioEditor/samples/shimmer-voice-sample.mp3 +0 -0
  13. package/dist/Components/Breadcrumbs/index.svelte +0 -27
  14. package/dist/Components/Breadcrumbs/index.svelte.js +0 -88
  15. package/dist/Components/Chart/Klines/index.svelte +0 -87
  16. package/dist/Components/Chart/index.svelte +0 -226
  17. package/dist/Components/Chart/index.svelte.js +0 -1090
  18. package/dist/Components/ChartInput/DisplayNav/Klines/index.svelte +0 -150
  19. package/dist/Components/ChartInput/DisplayNav/Lines/index.svelte +0 -45
  20. package/dist/Components/ChartInput/DisplayNav/index.svelte +0 -297
  21. package/dist/Components/ChartInput/EditPanel/index.svelte +0 -155
  22. package/dist/Components/ChartInput/index.svelte +0 -21
  23. package/dist/Components/ChartInput/index.svelte.js +0 -671
  24. package/dist/Components/Color/index.svelte +0 -51
  25. package/dist/Components/Color/index.svelte.js +0 -31
  26. package/dist/Components/ColorInput/ChromaPicker/index.svelte +0 -50
  27. package/dist/Components/ColorInput/ColorPalette/index.svelte +0 -62
  28. package/dist/Components/ColorInput/OpacityPicker/index.svelte +0 -68
  29. package/dist/Components/ColorInput/ShowcasePicker/index.svelte +0 -136
  30. package/dist/Components/ColorInput/index.svelte +0 -70
  31. package/dist/Components/ColorInput/index.svelte.js +0 -386
  32. package/dist/Components/ConditionsInput/index.svelte +0 -46
  33. package/dist/Components/ConditionsInput/index.svelte.js +0 -201
  34. package/dist/Components/Confetti/index.svelte +0 -98
  35. package/dist/Components/Confetti/index.svelte.js +0 -94
  36. package/dist/Components/Content/index.svelte +0 -500
  37. package/dist/Components/Content/index.svelte.js +0 -910
  38. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Audio/index.svelte +0 -31
  39. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Audio/index.svelte.js +0 -258
  40. package/dist/Components/ContentInput/AttributesInput/CustomConfig/AudioAdvanced/index.svelte +0 -31
  41. package/dist/Components/ContentInput/AttributesInput/CustomConfig/AudioAdvanced/index.svelte.js +0 -258
  42. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Dropdown/index.svelte +0 -58
  43. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Dropdown/index.svelte.js +0 -206
  44. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Image/index.svelte +0 -28
  45. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Image/index.svelte.js +0 -224
  46. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Number/index.svelte +0 -44
  47. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Number/index.svelte.js +0 -272
  48. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Qr/index.svelte +0 -41
  49. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Qr/index.svelte.js +0 -202
  50. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Slider/index.svelte +0 -19
  51. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Slider/index.svelte.js +0 -117
  52. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TableAdvanced/index.svelte +0 -60
  53. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TableAdvanced/index.svelte.js +0 -542
  54. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Tag/index.svelte +0 -47
  55. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Tag/index.svelte.js +0 -185
  56. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TextInput/index.svelte +0 -35
  57. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TextInput/index.svelte.js +0 -222
  58. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TimeInput/index.svelte +0 -20
  59. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TimeInput/index.svelte.js +0 -84
  60. package/dist/Components/ContentInput/AttributesInput/DefinedTypeInput/index.svelte +0 -25
  61. package/dist/Components/ContentInput/AttributesInput/DefinedTypeInput/index.svelte.js +0 -91
  62. package/dist/Components/ContentInput/AttributesInput/index.svelte +0 -352
  63. package/dist/Components/ContentInput/AttributesInput/index.svelte.js +0 -1436
  64. package/dist/Components/ContentInput/ContentPanelBuilder/AddElement/index.svelte +0 -64
  65. package/dist/Components/ContentInput/ContentPanelBuilder/AddElement/index.svelte.js +0 -97
  66. package/dist/Components/ContentInput/ContentPanelBuilder/ElementList/index.svelte +0 -184
  67. package/dist/Components/ContentInput/ContentPanelBuilder/index.svelte +0 -41
  68. package/dist/Components/ContentInput/index.svelte +0 -78
  69. package/dist/Components/ContentInput/index.svelte.js +0 -1197
  70. package/dist/Components/CronInput/index.svelte +0 -78
  71. package/dist/Components/CronInput/index.svelte.js +0 -198
  72. package/dist/Components/DataTypeInput/index.svelte +0 -174
  73. package/dist/Components/DataTypeInput/index.svelte.js +0 -565
  74. package/dist/Components/Dropdown/index.svelte +0 -116
  75. package/dist/Components/Dropdown/index.svelte.js +0 -403
  76. package/dist/Components/ErrorX/index.svelte +0 -58
  77. package/dist/Components/FileInput/index.svelte +0 -146
  78. package/dist/Components/FileInput/index.svelte.js +0 -225
  79. package/dist/Components/Hamburger/index.svelte +0 -99
  80. package/dist/Components/HorizScrollBox/index.svelte +0 -145
  81. package/dist/Components/IconInput/index.svelte +0 -77
  82. package/dist/Components/IconInput/index.svelte.js +0 -259
  83. package/dist/Components/Image/index.svelte +0 -126
  84. package/dist/Components/Image/index.svelte.js +0 -116
  85. package/dist/Components/ImageEditor/Image/CropBox/index.svelte +0 -165
  86. package/dist/Components/ImageEditor/Image/index.svelte +0 -104
  87. package/dist/Components/ImageEditor/Panels/AI/index.svelte +0 -44
  88. package/dist/Components/ImageEditor/Panels/Crop/index.svelte +0 -96
  89. package/dist/Components/ImageEditor/Panels/File/QualityPicker/index.svelte +0 -124
  90. package/dist/Components/ImageEditor/Panels/File/index.svelte +0 -74
  91. package/dist/Components/ImageEditor/Panels/Filters/index.svelte +0 -46
  92. package/dist/Components/ImageEditor/Panels/Resize/index.svelte +0 -58
  93. package/dist/Components/ImageEditor/index.svelte +0 -93
  94. package/dist/Components/ImageEditor/index.svelte.js +0 -1961
  95. package/dist/Components/ImageSlider/index.svelte +0 -124
  96. package/dist/Components/ImageSlider/index.svelte.js +0 -99
  97. package/dist/Components/Json/Nested/index.svelte +0 -157
  98. package/dist/Components/LabeledItem/index.svelte +0 -102
  99. package/dist/Components/Layout/NavBar/FullNav/index.svelte +0 -52
  100. package/dist/Components/Layout/NavBar/NavGuts/index.svelte +0 -87
  101. package/dist/Components/Layout/NavBar/index.svelte +0 -72
  102. package/dist/Components/Layout/index.svelte +0 -149
  103. package/dist/Components/Layout/index.svelte.js +0 -360
  104. package/dist/Components/LoadingWheel/index.svelte +0 -38
  105. package/dist/Components/LocationInput/index.svelte +0 -197
  106. package/dist/Components/LocationInput/index.svelte.js +0 -965
  107. package/dist/Components/Number/index.svelte +0 -47
  108. package/dist/Components/Number/index.svelte.js +0 -151
  109. package/dist/Components/PhoneCountryCode/index.svelte +0 -7
  110. package/dist/Components/PhoneCountryCode/index.svelte.js +0 -260
  111. package/dist/Components/Popover/index.svelte +0 -396
  112. package/dist/Components/Popover/index.svelte.js +0 -319
  113. package/dist/Components/Spacer/index.svelte +0 -41
  114. package/dist/Components/StoragePicker/DisplayFile/index.svelte +0 -15
  115. package/dist/Components/StoragePicker/index.svelte +0 -187
  116. package/dist/Components/StoragePicker/index.svelte.js +0 -592
  117. package/dist/Components/TableAdvanced/ColumnInput/index.svelte +0 -117
  118. package/dist/Components/TableAdvanced/ColumnInput/index.svelte.js +0 -456
  119. package/dist/Components/TableAdvanced/FilterInput/index.svelte +0 -54
  120. package/dist/Components/TableAdvanced/FilterInput/index.svelte.js +0 -247
  121. package/dist/Components/TableAdvanced/Pagination/index.svelte +0 -43
  122. package/dist/Components/TableAdvanced/Pagination/index.svelte.js +0 -97
  123. package/dist/Components/TableAdvanced/SortByInput/index.svelte +0 -72
  124. package/dist/Components/TableAdvanced/SortByInput/index.svelte.js +0 -176
  125. package/dist/Components/Tag/index.svelte +0 -45
  126. package/dist/Components/Tag/index.svelte.js +0 -76
  127. package/dist/Components/TextArrayInput/index.svelte +0 -108
  128. package/dist/Components/TextArrayInput/index.svelte.js +0 -239
  129. package/dist/Components/TextInput/PasswordTooltip/index.svelte +0 -89
  130. package/dist/Components/TimeInput/NumberToggler/index.svelte +0 -34
  131. package/dist/Components/TimeInput/NumberToggler/index.svelte.js +0 -79
  132. package/dist/Components/TimeInput/index.js +0 -702
  133. package/dist/Components/TimeInput/index.svelte +0 -211
  134. package/dist/Components/TimeInput/index.svelte.js +0 -638
  135. package/dist/Components/Tooltip/index.svelte +0 -143
  136. package/dist/Components/TransparentBackground/index.svelte +0 -153
  137. package/dist/Components/TypingDots/index.svelte +0 -84
  138. package/dist/Components/VariablePathInput/index.svelte +0 -63
  139. package/dist/Components/VariablePathInput/index.svelte.js +0 -273
  140. package/dist/Components/XFollow/index.svelte +0 -42
  141. package/dist/Components/YoutubeChannelButton/index.svelte +0 -82
  142. package/dist/Components/YoutubeVideo/index.svelte +0 -73
  143. package/dist/Components/YoutubeVideo/index.svelte.js +0 -54
  144. package/dist/actions/draggable.js +0 -49
  145. package/dist/actions/index.js +0 -24
  146. package/dist/actions/no_spaces.js +0 -33
  147. package/dist/actions/numbers_only.js +0 -26
  148. package/dist/actions/scroll_y.js +0 -28
  149. package/dist/actions/stop_scroll_propagation_y.js +0 -42
  150. package/dist/actions/swipe_handler.js +0 -295
  151. package/dist/client/astc_formatting/index.js +0 -1128
  152. package/dist/client/docs/index.js +0 -7622
  153. package/dist/client/index.js +0 -735
  154. package/dist/client/types/index.js +0 -2812
  155. package/dist/index.js +0 -180
  156. package/dist/style.css +0 -682
@@ -1,1961 +0,0 @@
1
- import {
2
- create_unique_id,
3
- clean_custom_identifier,
4
- mime_type_extensions,
5
- deep_copy,
6
- url_to_file,
7
- } from "../../client/index.js"
8
- import { create_button_manager } from "../Button/index.svelte.js"
9
- import { create_popover_manager } from "../Popover/index.svelte.js"
10
- import { create_text_input_manager } from "../TextInput/index.svelte.js"
11
- import { create_dropdown_manager } from "../Dropdown/index.svelte.js"
12
- import { create_slider_manager } from "../Slider/index.svelte.js"
13
- import { create_file_input_manager } from "../FileInput/index.svelte.js"
14
- import { create_checkbox_manager } from "../Checkbox/index.svelte.js"
15
- import "context-filter-polyfill" // ctx.filter doesnt work on safari and this should fix
16
-
17
- export function create_image_editor_manager(config) {
18
- let id = create_unique_id(null, 20)
19
-
20
- let is_popover = $state(true)
21
- let screen_tab = $state("filters")
22
- let image_sources = $state([])
23
- let image_source_index = $state(null)
24
- let file_picker_file = $state(null)
25
- let file_name = $state(null)
26
- let mime_type = $state(null)
27
- let mime_type_input = $state(null)
28
- let file_size_data = $state(null)
29
- let is_lock_resize_aspect_ratio = $state(true)
30
- let resize_width = $state(null)
31
- let resize_height = $state(null)
32
- let crop_width = $state(null)
33
- let crop_height = $state(null)
34
- let crop_left = $state(0)
35
- let crop_top = $state(0)
36
- let crop_aspect_width = $state(null)
37
- let crop_aspect_height = $state(null)
38
- let crop_aspect_ratio = $state(null)
39
- let current_image_width = $state(null)
40
- let current_image_height = $state(null)
41
- let current_image_ar = $state(null)
42
- let image_pixels_crop_width = $state(null)
43
- let image_pixels_crop_height = $state(null)
44
- let crop_drag_type = $state("main")
45
- let crop_top_start = $state(null)
46
- let crop_left_start = $state(null)
47
- let crop_width_start = $state(null)
48
- let crop_height_start = $state(null)
49
- let start_x = $state(null)
50
- let start_y = $state(null)
51
- let last_known_x = $state(null)
52
- let last_known_y = $state(null)
53
- let is_disabled = $state(false)
54
- let ai_error_message = $state(null)
55
- let file_size_kb = $state(null)
56
-
57
- let popover_manager = $state(null)
58
- let file_input_manager = $state(null)
59
- let screen_tab_filters_button_manager = $state(null)
60
- let screen_tab_crop_button_manager = $state(null)
61
- let screen_tab_resize_button_manager = $state(null)
62
- let screen_tab_ai_button_manager = $state(null)
63
- let screen_tab_file_button_manager = $state(null)
64
- let undo_button_manager = $state(null)
65
- let redo_button_manager = $state(null)
66
- let clear_button_manager = $state(null)
67
- let finish_button_manager = $state(null)
68
- let is_show_img_slider = $state(false) // idk if using this really
69
-
70
- let filter_brightness_slider_manager = $state(null)
71
- let filter_contrast_slider_manager = $state(null)
72
- let filter_saturation_slider_manager = $state(null)
73
- let filter_grayscale_slider_manager = $state(null)
74
- let filter_hue_slider_manager = $state(null)
75
- let filter_red_slider_manager = $state(null)
76
- let filter_green_slider_manager = $state(null)
77
- let filter_blue_slider_manager = $state(null)
78
- let filter_blur_slider_manager = $state(null)
79
- let filter_opacity_slider_manager = $state(null)
80
- let filters_set_default_button_manager = $state(null)
81
- let filters_apply_filters_button_manager = $state(null)
82
-
83
- let crop_free_button_manager = $state(null)
84
- let crop_one_to_one_button_manager = $state(null)
85
- let crop_four_to_three_button_manager = $state(null)
86
- let crop_three_to_two_button_manager = $state(null)
87
- let crop_sixteen_to_nine_button_manager = $state(null)
88
- let crop_three_to_four_button_manager = $state(null)
89
- let crop_two_to_three_button_manager = $state(null)
90
- let crop_nine_to_sixteen_button_manager = $state(null)
91
- let crop_width_ratio_text_input_manager = $state(null)
92
- let crop_height_ratio_text_input_manager = $state(null)
93
- let crop_image_button_manager = $state(null)
94
- let crop_aspect_width_loc = $state(null)
95
- let crop_aspect_height_loc = $state(null)
96
-
97
- let file_name_text_input_manager = $state(null)
98
- let mime_type_webp_button_manager = $state(null)
99
- let mime_type_jpeg_button_manager = $state(null)
100
- let mime_type_png_button_manager = $state(null)
101
- let download_image_button_manager = $state(null)
102
- let set_file_changes_button_manager = $state(null)
103
- let file_quality_slider_manager = $state(null)
104
-
105
- let ai_tab_dropdown_manager = $state(null)
106
- let ai_image_generator_is_loading = $state(null)
107
- let ai_generate_image_from_text_text_input_manager = $state(null)
108
- let ai_generate_image_images_prompt_file_input_manager = $state(null)
109
- let ai_generate_image_include_workspace_in_images_prompt_checkbox_manager = $state(null)
110
- let ai_generate_image_from_text_button_manager = $state(null)
111
- let ai_remove_background_is_loading = $state(false)
112
- let ai_restore_resolution_is_loading = $state(false)
113
- let ai_restore_face_is_loading = $state(false)
114
- let ai_remove_bg_button_manager = $state(null)
115
- let ai_restore_resolution_button_manager = $state(null)
116
- let ai_restore_face_button_manager = $state(null)
117
-
118
- let resize_width_dropdown_manager = $state(null)
119
- let resize_height_dropdown_manager = $state(null)
120
- let resize_width_text_input_manager = $state(null)
121
- let resize_height_text_input_manager = $state(null)
122
- let resize_aspect_ratio_lock_button_manager = $state(null)
123
- let resize_image_button_manager = $state(null)
124
-
125
- let selected_image_source = $derived(
126
- Array.isArray(image_sources) && image_source_index < image_sources.length
127
- ? image_sources?.[image_source_index]
128
- : null
129
- )
130
-
131
- let file_name_derived = $derived(clean_custom_identifier(file_name_text_input_manager?.val ?? file_name ?? ""))
132
-
133
- let file_name_derived_with_extension = $derived(
134
- `${clean_custom_identifier(file_name_text_input_manager?.val ?? file_name ?? "")}.${
135
- mime_type_extensions?.[mime_type ?? mime_type_input]
136
- }`
137
- )
138
-
139
- let shown_file_size_data = $derived(file_size_data?.[mime_type_input])
140
-
141
- async function set_file_size_kb() {
142
- if (!selected_image_source) {
143
- return
144
- }
145
- let data_url = await get_image_data_url(
146
- selected_image_source,
147
- mime_type_input ?? mime_type,
148
- file_quality_slider_manager?.val
149
- )
150
- let size = calculate_file_size(data_url, mime_type_input ?? mime_type)
151
- file_size_kb = size
152
- }
153
-
154
- function set_crop_box_loc(w, h) {
155
- crop_aspect_width_loc = w
156
- crop_aspect_height_loc = h
157
- crop_width_ratio_text_input_manager.set_val(crop_aspect_width_loc)
158
- crop_height_ratio_text_input_manager.set_val(crop_aspect_height_loc)
159
- set_crop_box(w, h)
160
- }
161
-
162
- function on_destroy() {
163
- if (document) {
164
- let hidden_image_el = document?.querySelector(`#${id}_hidden_image_el`)
165
- if (hidden_image_el) {
166
- hidden_image_el.remove()
167
- }
168
- }
169
- }
170
-
171
- function set_base_image(new_src) {
172
- setTimeout(() => {
173
- let hidden_image_el = document?.querySelector(`#${id}_hidden_image_el`)
174
- if (hidden_image_el) {
175
- hidden_image_el.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
176
- if (new_src) {
177
- clear_canvas()
178
- reset_fields()
179
- hidden_image_el.src = new_src
180
- }
181
- }
182
- })
183
- }
184
-
185
- function clear_canvas() {
186
- let canvas_container_el = document?.querySelector(`#${id}_canvas_container_el`)
187
- current_image_width = null
188
- current_image_height = null
189
- current_image_ar = null
190
- if (canvas_container_el) {
191
- canvas_container_el.style.min_width = "auto"
192
- canvas_container_el.style.min_height = "auto"
193
- }
194
- let canvas_el = document?.querySelector(`#${id}_canvas_el`)
195
- if (!canvas_el) {
196
- return
197
- }
198
- let ctx = canvas_el.getContext("2d", { willReadFrequently: true })
199
- ctx.clearRect(0, 0, canvas_el.width, canvas_el.height)
200
- }
201
-
202
- function reset_fields() {
203
- filter_brightness_slider_manager.set_val(100)
204
- filter_contrast_slider_manager.set_val(100)
205
- filter_saturation_slider_manager.set_val(100)
206
- filter_grayscale_slider_manager.set_val(0)
207
- filter_hue_slider_manager.set_val(0)
208
- filter_red_slider_manager.set_val(100)
209
- filter_green_slider_manager.set_val(100)
210
- filter_blue_slider_manager.set_val(100)
211
- filter_blur_slider_manager.set_val(0)
212
- filter_opacity_slider_manager.set_val(100)
213
- file_quality_slider_manager.set_val(75)
214
- crop_left = 0
215
- crop_top = 0
216
- crop_width = null
217
- crop_height = null
218
- resize_width = null
219
- resize_height = null
220
- is_lock_resize_aspect_ratio = true
221
- crop_aspect_width = null
222
- crop_aspect_height = null
223
- crop_aspect_ratio = null
224
- }
225
-
226
- function set_screen_tab(screen_tab_loc) {
227
- screen_tab = screen_tab_loc
228
- let hidden_image_el = document?.querySelector(`#${id}_hidden_image_el`)
229
- reset_fields()
230
- if (screen_tab != "ai" && !hidden_image_el) {
231
- set_base_image(selected_image_source)
232
- }
233
- if (screen_tab == "filters") {
234
- main_image_transformer()
235
- } else if (screen_tab == "file") {
236
- set_file_data_base()
237
- } else if (screen_tab == "crop") {
238
- set_crop_box()
239
- } else if (screen_tab == "ai") {
240
- is_show_img_slider = false
241
- }
242
- }
243
-
244
- function main_image_transformer() {
245
- try {
246
- let hidden_image_el = document?.querySelector(`#${id}_hidden_image_el`)
247
- let edit_image_container_el = document?.querySelector(`#${id}_edit_image_container_el`)
248
- let canvas_container_el = document?.querySelector(`#${id}_canvas_container_el`)
249
- let canvas_el = document?.querySelector(`#${id}_canvas_el`)
250
- if (!canvas_el || !hidden_image_el?.height || !(image_sources.length > 0)) {
251
- return
252
- }
253
- let hidden_image_el_width = hidden_image_el?.width
254
- let hidden_image_el_height = hidden_image_el?.height
255
- let canv_width = canvas_el.offsetWidth
256
- let canv_height = canvas_el.offsetHeight
257
- let edit_image_container_el_width = edit_image_container_el.offsetWidth
258
- let edit_image_container_el_height = edit_image_container_el.offsetHeight
259
- clear_canvas()
260
- current_image_width = hidden_image_el_width
261
- current_image_height = hidden_image_el_height
262
- current_image_ar =
263
- current_image_width && current_image_height
264
- ? parseFloat((current_image_width / current_image_height).toPrecision(4))
265
- : null
266
- let resize_width_loc = resize_width
267
- let resize_height_loc = resize_height
268
- if (resize_width_loc < 1) {
269
- if (crop_width > 0) {
270
- resize_width_loc = Math.round((crop_width * hidden_image_el_width) / canv_width)
271
- } else {
272
- resize_width_loc = hidden_image_el_width
273
- }
274
- }
275
- if (resize_height_loc < 1) {
276
- if (crop_height > 0) {
277
- resize_height_loc = Math.round((crop_height * hidden_image_el_height) / canv_height)
278
- } else {
279
- resize_height_loc = hidden_image_el_height
280
- }
281
- }
282
- let resize_aspect_ratio = resize_width_loc / resize_height_loc
283
- let edit_image_frame_aspect_ratio = edit_image_container_el_width / edit_image_container_el_height
284
- let crop_width_loc = crop_width > 0 ? crop_width : canv_width
285
- let crop_height_loc = crop_height > 0 ? crop_height : canv_height
286
- let image_pixels_crop_width = Math.round((crop_width_loc * hidden_image_el_width) / canv_width)
287
- let image_pixels_crop_left = Math.round((crop_left * hidden_image_el_width) / canv_width)
288
- let image_pixels_crop_height = Math.round((crop_height_loc * hidden_image_el_height) / canv_height)
289
- let image_pixels_crop_top = Math.round((crop_top * hidden_image_el_height) / canv_height)
290
- let display_image_height = edit_image_container_el_height
291
- let display_image_width = display_image_height * resize_aspect_ratio
292
- if (edit_image_frame_aspect_ratio < resize_aspect_ratio) {
293
- display_image_width = edit_image_container_el_width
294
- display_image_height = display_image_width / resize_aspect_ratio
295
- }
296
- canvas_container_el.style.min_width = "auto"
297
- canvas_container_el.style.min_height = "auto"
298
- if (resize_width_loc < display_image_width || resize_height_loc < display_image_height) {
299
- canvas_container_el.style.width = display_image_width + "px"
300
- canvas_container_el.style.height = display_image_height + "px"
301
- }
302
- canvas_el.width = Math.round(resize_width_loc)
303
- canvas_el.height = Math.round(resize_height_loc)
304
- let ctx = canvas_el.getContext("2d", { willReadFrequently: true })
305
- ctx.filter = `brightness(${filter_brightness_slider_manager?.val}%) contrast(${filter_contrast_slider_manager?.val}%) saturate(${filter_saturation_slider_manager?.val}%) grayscale(${filter_grayscale_slider_manager?.val}%) opacity(${filter_opacity_slider_manager?.val}%) hue-rotate(${filter_hue_slider_manager?.val}deg) blur(${filter_blur_slider_manager?.val}px)`
306
- ctx.drawImage(
307
- hidden_image_el,
308
- image_pixels_crop_left,
309
- image_pixels_crop_top,
310
- image_pixels_crop_width,
311
- image_pixels_crop_height,
312
- 0,
313
- 0,
314
- resize_width_loc,
315
- resize_height_loc
316
- )
317
- let canv_image_data = ctx.getImageData(0, 0, image_pixels_crop_width, image_pixels_crop_height)
318
- for (let i = 0; i < canv_image_data.data.length; i += 4) {
319
- canv_image_data.data[i] = canv_image_data.data[i] * (filter_red_slider_manager?.val / 100)
320
- canv_image_data.data[i + 1] = canv_image_data.data[i + 1] * (filter_green_slider_manager?.val / 100)
321
- canv_image_data.data[i + 2] = canv_image_data.data[i + 2] * (filter_blue_slider_manager?.val / 100)
322
- }
323
- ctx.putImageData(canv_image_data, 0, 0)
324
- ctx.filter = "none"
325
- if (
326
- (image_pixels_crop_width > 0 && Math.round(image_pixels_crop_width) != Math.round(hidden_image_el_width)) ||
327
- (image_pixels_crop_height > 0 && Math.round(image_pixels_crop_height) != Math.round(hidden_image_el_height)) ||
328
- (resize_width > 0 && resize_height > 0)
329
- ) {
330
- reset_fields()
331
- let new_image_src = canvas_el.toDataURL(mime_type, file_quality_slider_manager?.val)
332
- image_sources = [new_image_src, ...image_sources.slice(image_source_index)]
333
- image_source_index = 0
334
- set_base_image(new_image_src)
335
- }
336
- } catch (err) {
337
- console.log("error updating image", err)
338
- }
339
- }
340
-
341
- function undo() {
342
- if (Array.isArray(image_sources) && image_sources.length > 1 && image_source_index < image_sources.length - 1) {
343
- image_source_index++
344
- set_base_image(selected_image_source)
345
- }
346
- }
347
-
348
- function redo() {
349
- if (Array.isArray(image_sources) && image_sources.length > 1 && image_source_index > 0) {
350
- image_source_index--
351
- set_base_image(selected_image_source)
352
- }
353
- }
354
-
355
- function clear() {
356
- image_sources = []
357
- image_source_index = 0
358
- file_picker_file = null
359
- file_name_text_input_manager.set_val(null)
360
- }
361
-
362
- async function finish() {
363
- let file_to_return = null
364
- if (selected_image_source) {
365
- file_to_return = await url_to_file(selected_image_source, file_name_derived)
366
- }
367
- if (typeof config?.on_finish == "function") {
368
- config?.on_finish(file_to_return)
369
- }
370
- popover_manager?.close()
371
- }
372
-
373
- function drop_handler(e) {
374
- let accept = ["image/webp", "image/jpeg", "image/png"]
375
- let files_loc = []
376
- if (e.dataTransfer.items) {
377
- for (let i = 0; i < e.dataTransfer.items.length; i++) {
378
- if (e.dataTransfer.items[i].kind === "file") {
379
- let file = e.dataTransfer.items[i].getAsFile()
380
- if (accept.includes(file?.type)) {
381
- files_loc = [...files_loc, file]
382
- }
383
- }
384
- }
385
- } else {
386
- for (let i = 0; i < e.dataTransfer.files.length; i++) {
387
- let file = e.dataTransfer.files[i].getAsFile()
388
- files_loc = [...files_loc, file]
389
- }
390
- }
391
- if (files_loc.length > 0) {
392
- init_file(files_loc[0])
393
- }
394
- }
395
-
396
- // filters ↓↓↓
397
-
398
- function apply_filters() {
399
- let canvas_el = document?.querySelector(`#${id}_canvas_el`)
400
- if (canvas_el && selected_image_source) {
401
- let new_image_src = canvas_el.toDataURL(mime_type, file_quality_slider_manager?.val)
402
- image_sources = [new_image_src, ...image_sources.slice(image_source_index)]
403
- image_source_index = 0
404
- reset_fields()
405
- set_base_image(new_image_src)
406
- }
407
- }
408
-
409
- function reset_filters() {
410
- filter_brightness_slider_manager.set_val(100)
411
- filter_contrast_slider_manager.set_val(100)
412
- filter_saturation_slider_manager.set_val(100)
413
- filter_grayscale_slider_manager.set_val(0)
414
- filter_hue_slider_manager.set_val(0)
415
- filter_red_slider_manager.set_val(100)
416
- filter_green_slider_manager.set_val(100)
417
- filter_blue_slider_manager.set_val(100)
418
- filter_blur_slider_manager.set_val(0)
419
- filter_opacity_slider_manager.set_val(100)
420
- set_base_image(selected_image_source)
421
- }
422
- // filters ↑↑↑
423
-
424
- // resize ↓↓↓
425
- const resize_options = [
426
- { key: 512, name: "512px" },
427
- { key: 800, name: "800px" },
428
- { key: 1000, name: "1000px" },
429
- { key: 1200, name: "1200px" },
430
- { key: 1600, name: "1600px" },
431
- { key: 2000, name: "2000px" },
432
- { key: 2400, name: "2400px" },
433
- ]
434
-
435
- function toggle_is_lock_resize_aspect_ratio() {
436
- is_lock_resize_aspect_ratio = !is_lock_resize_aspect_ratio
437
- }
438
-
439
- function set_resize_dimensions(w, h) {
440
- if (w == 0 && !h) {
441
- resize_width = 0
442
- if (is_lock_resize_aspect_ratio) {
443
- resize_height = 0
444
- }
445
- } else if (h == 0 && !w) {
446
- resize_height = 0
447
- if (is_lock_resize_aspect_ratio) {
448
- resize_width = 0
449
- }
450
- } else if (w > 0) {
451
- resize_width = Math.round(Math.min(w, 10000))
452
- if (h > 0) {
453
- resize_height = Math.round(Math.min(h, 10000))
454
- } else if (is_lock_resize_aspect_ratio) {
455
- resize_height = Math.round(w / current_image_ar / 10) * 10
456
- }
457
- } else if (h > 0) {
458
- resize_height = Math.round(Math.min(h, 10000))
459
- if (is_lock_resize_aspect_ratio) {
460
- resize_width = Math.round((h * current_image_ar) / 10) * 10
461
- }
462
- }
463
- }
464
- // resize ↑↑↑
465
-
466
- // crop ↓↓↓
467
- function set_crop_box(w = null, h = null) {
468
- let canvas_el = document?.querySelector(`#${id}_canvas_el`)
469
- if (w != null && w > -1 && h != null && h > -1) {
470
- crop_aspect_ratio = parseFloat((w / h).toPrecision(4))
471
- } else {
472
- crop_aspect_ratio = null
473
- }
474
- let canv_height = canvas_el.offsetHeight
475
- let canv_width = canvas_el.offsetWidth
476
- let canvas_aspect_ratio = crop_aspect_ratio ? crop_aspect_ratio : canv_width / canv_height
477
- crop_top = 0
478
- crop_left = 0
479
- crop_width = canv_width
480
- crop_height = canv_height
481
- if (crop_aspect_ratio <= canvas_aspect_ratio || crop_height > canv_height) {
482
- crop_height = canv_height
483
- crop_width = canv_height * canvas_aspect_ratio
484
- crop_left = (canv_width - crop_width) / 2
485
- }
486
- if (crop_aspect_ratio > canvas_aspect_ratio || crop_width > canv_width) {
487
- crop_left = 0
488
- crop_width = canv_width
489
- crop_height = canv_width / canvas_aspect_ratio
490
- crop_top = (canv_height - crop_height) / 2
491
- }
492
- set_image_pixels_crop()
493
- }
494
-
495
- function crop_image(w, h) {
496
- if (crop_aspect_width != w && crop_aspect_height != h) {
497
- crop_aspect_width = w
498
- crop_aspect_height = h
499
- if (w != null && w > 0 && h != null && h > 0) {
500
- crop_aspect_ratio =
501
- w > 0 && h > 0 ? JSON.parse((Math.min(w, 10000) / Math.min(h, 10000)).toPrecision(4)).toFixed(2) : null
502
- } else {
503
- crop_aspect_ratio = null
504
- }
505
- }
506
- main_image_transformer()
507
- setTimeout(() => {
508
- set_crop_box()
509
- set_image_pixels_crop()
510
- }, 10)
511
- }
512
-
513
- function set_image_pixels_crop() {
514
- let canvas_el = document?.querySelector(`#${id}_canvas_el`)
515
- let canv_height = canvas_el.offsetHeight
516
- let canv_width = canvas_el.offsetWidth
517
- image_pixels_crop_width =
518
- crop_width > 0 && current_image_width > 0
519
- ? Math.round((crop_width * current_image_width) / canv_width)
520
- : current_image_width
521
- image_pixels_crop_height =
522
- crop_height > 0 && current_image_height > 0
523
- ? Math.round((crop_height * current_image_height) / canv_height)
524
- : current_image_height
525
- }
526
-
527
- function update_crop_values(
528
- canv_height,
529
- canv_width,
530
- crop_drag_type,
531
- crop_top,
532
- crop_left,
533
- crop_width,
534
- crop_height,
535
- crop_top_start,
536
- crop_left_start,
537
- crop_width_start,
538
- crop_height_start,
539
- x_change,
540
- y_change,
541
- crop_aspect_ratio
542
- ) {
543
- let new_crop_top = crop_top
544
- let new_crop_left = crop_left
545
- let new_crop_width = crop_width
546
- let new_crop_height = crop_height
547
- if (crop_drag_type == "main") {
548
- new_crop_left = crop_left_start + x_change
549
- new_crop_top = crop_top_start + y_change
550
- if (new_crop_left < 0) {
551
- new_crop_left = 0
552
- }
553
- if (new_crop_top < 0) {
554
- new_crop_top = 0
555
- }
556
- let room_right = canv_width - (new_crop_left + crop_width)
557
- let room_bottom = canv_height - (new_crop_top + crop_height)
558
- let room_left = new_crop_left
559
- let room_top = new_crop_top
560
- if (room_right < 0) {
561
- new_crop_left = canv_width - crop_width
562
- }
563
- if (room_bottom < 0) {
564
- new_crop_top = canv_height - crop_height
565
- }
566
- }
567
- // new_crop_width = new_crop_height * crop_aspect_ratio
568
- // new_crop_height = new_crop_width / crop_aspect_ratio
569
- let center_vert_start = crop_top_start + crop_height_start / 2
570
- let center_horiz_start = crop_left_start + crop_width_start / 2
571
- let shortest_horiz_length_to_wall_start = Math.min(canv_width - center_horiz_start, center_horiz_start)
572
- let shortest_vert_length_to_wall_start = Math.min(canv_height - center_vert_start, center_vert_start)
573
- if (["tl", "t", "tr"].includes(crop_drag_type)) {
574
- let res = linear_low_crop_slide(crop_top_start, crop_height_start, y_change)
575
- new_crop_top = res.crop_lower
576
- new_crop_height = res.crop_range
577
- }
578
- if (["tl", "l", "bl"].includes(crop_drag_type)) {
579
- let res = linear_low_crop_slide(crop_left_start, crop_width_start, x_change)
580
- new_crop_left = res.crop_lower
581
- new_crop_width = res.crop_range
582
- }
583
- if (["bl", "b", "br"].includes(crop_drag_type)) {
584
- new_crop_height = linear_high_crop_slide(crop_height_start, canv_height - crop_top_start, y_change)
585
- }
586
- if (["tr", "r", "br"].includes(crop_drag_type)) {
587
- new_crop_width = linear_high_crop_slide(crop_width_start, canv_width - crop_left_start, x_change)
588
- }
589
- if (crop_aspect_ratio) {
590
- if (["t", "b"].includes(crop_drag_type)) {
591
- let crop_width_based_on_change = new_crop_height * crop_aspect_ratio
592
- if (crop_width_based_on_change / 2 >= shortest_horiz_length_to_wall_start) {
593
- new_crop_width = shortest_horiz_length_to_wall_start * 2
594
- new_crop_left = center_horiz_start - shortest_horiz_length_to_wall_start
595
- new_crop_height = new_crop_width / crop_aspect_ratio
596
- new_crop_top = crop_top_start
597
- if (crop_drag_type == "t") {
598
- new_crop_top = crop_top_start + crop_height_start - new_crop_height
599
- }
600
- } else {
601
- new_crop_width = crop_width_based_on_change
602
- new_crop_left = center_horiz_start - crop_width_based_on_change / 2
603
- new_crop_height = new_crop_width / crop_aspect_ratio
604
- }
605
- } else if (["l", "r"].includes(crop_drag_type)) {
606
- let crop_height_based_on_change = new_crop_width / crop_aspect_ratio
607
- if (crop_height_based_on_change / 2 >= shortest_vert_length_to_wall_start) {
608
- new_crop_height = shortest_vert_length_to_wall_start * 2
609
- new_crop_top = center_vert_start - shortest_vert_length_to_wall_start
610
- new_crop_width = new_crop_height * crop_aspect_ratio
611
- new_crop_left = crop_left_start
612
- if (crop_drag_type == "l") {
613
- new_crop_left = crop_left_start + crop_width_start - new_crop_width
614
- }
615
- } else {
616
- new_crop_height = crop_height_based_on_change
617
- new_crop_top = center_vert_start - crop_height_based_on_change / 2
618
- new_crop_width = new_crop_height * crop_aspect_ratio
619
- }
620
- } else if (crop_drag_type == "tl") {
621
- let max_width = crop_left_start + crop_width_start
622
- let max_height = crop_top_start + crop_height_start
623
- let is_height_shortest_distance = max_width / crop_aspect_ratio > max_height
624
- if (is_height_shortest_distance) {
625
- new_crop_width = new_crop_height * crop_aspect_ratio
626
- new_crop_left = max_width - new_crop_width
627
- } else {
628
- new_crop_height = new_crop_width / crop_aspect_ratio
629
- new_crop_top = max_height - new_crop_height
630
- }
631
- } else if (crop_drag_type == "tr") {
632
- let max_width = canv_width - crop_left_start
633
- let max_height = crop_top_start + crop_height_start
634
- let is_height_shortest_distance = max_width / crop_aspect_ratio > max_height
635
- if (is_height_shortest_distance) {
636
- new_crop_width = new_crop_height * crop_aspect_ratio
637
- new_crop_left = canv_width - max_width
638
- } else {
639
- new_crop_height = new_crop_width / crop_aspect_ratio
640
- new_crop_top = max_height - new_crop_height
641
- }
642
- } else if (crop_drag_type == "bl") {
643
- let max_width = crop_left_start + crop_width_start
644
- let max_height = canv_height - crop_top_start
645
- let is_height_shortest_distance = max_width / crop_aspect_ratio > max_height
646
- if (is_height_shortest_distance) {
647
- new_crop_width = new_crop_height * crop_aspect_ratio
648
- new_crop_left = max_width - new_crop_width
649
- } else {
650
- new_crop_height = new_crop_width / crop_aspect_ratio
651
- new_crop_top = crop_top_start
652
- }
653
- } else if (crop_drag_type == "br") {
654
- let max_width = canv_width - crop_left_start
655
- let max_height = canv_height - crop_top_start
656
- let is_height_shortest_distance = max_width / crop_aspect_ratio > max_height
657
- if (is_height_shortest_distance) {
658
- new_crop_width = new_crop_height * crop_aspect_ratio
659
- new_crop_left = crop_left_start
660
- } else {
661
- new_crop_height = new_crop_width / crop_aspect_ratio
662
- new_crop_top = crop_top_start
663
- }
664
- }
665
- }
666
- return {
667
- crop_top: new_crop_top,
668
- crop_left: new_crop_left,
669
- crop_width: new_crop_width,
670
- crop_height: new_crop_height,
671
- }
672
- }
673
-
674
- function linear_low_crop_slide(crop_lower_start, crop_range_start, lower_change) {
675
- let new_crop_lower = crop_lower_start + lower_change
676
- let new_crop_range = crop_range_start - lower_change
677
- if (new_crop_lower < 0) {
678
- new_crop_range += new_crop_lower
679
- new_crop_lower = 0
680
- }
681
- let max_crop_lower = crop_lower_start + crop_range_start
682
- if (new_crop_lower > max_crop_lower) {
683
- new_crop_range -= new_crop_lower - max_crop_lower
684
- new_crop_lower = max_crop_lower
685
- }
686
- if (new_crop_range < 1) {
687
- new_crop_range = 1
688
- }
689
- let crop_total = new_crop_lower + new_crop_range
690
- if (crop_total !== crop_lower_start + crop_range_start) {
691
- if (crop_total > crop_lower_start + crop_range_start) {
692
- new_crop_range -= crop_total - (crop_lower_start + crop_range_start)
693
- } else {
694
- new_crop_range += crop_lower_start + crop_range_start - crop_total
695
- }
696
- }
697
- return { crop_lower: new_crop_lower, crop_range: new_crop_range }
698
- }
699
-
700
- function linear_high_crop_slide(crop_range_start, frame_range, lower_change) {
701
- let new_crop_range = crop_range_start + lower_change
702
- if (new_crop_range < 1) {
703
- new_crop_range = 1
704
- }
705
- if (new_crop_range > frame_range) {
706
- new_crop_range = frame_range
707
- }
708
- return new_crop_range
709
- }
710
-
711
- function crop_on_up(e) {
712
- if (start_x != null || start_y != null) {
713
- start_x = null
714
- start_y = null
715
- last_known_x = null
716
- last_known_y = null
717
- crop_top_start = null
718
- crop_left_start = null
719
- crop_width_start = null
720
- crop_height_start = null
721
- }
722
- }
723
-
724
- function crop_on_down(e, type) {
725
- e.preventDefault()
726
- if (e?.touches) {
727
- start_x = e.touches[0].pageX
728
- start_y = e.touches[0].pageY
729
- last_known_x = e.touches[0].pageX
730
- last_known_y = e.touches[0].pageY
731
- } else if ((e?.x, e?.y)) {
732
- start_x = e.x
733
- start_y = e.y
734
- last_known_x = e.x
735
- last_known_y = e.y
736
- }
737
- crop_drag_type = type
738
- crop_top_start = crop_top
739
- crop_left_start = crop_left
740
- crop_width_start = crop_width
741
- crop_height_start = crop_height
742
- }
743
-
744
- function crop_on_move(e) {
745
- let canvas_el = document?.querySelector(`#${id}_canvas_el`)
746
- if ((start_x != null && !isNaN(start_x)) || (start_y != null && !isNaN(start_y))) {
747
- if (e?.touches) {
748
- last_known_x = e.touches[0].pageX
749
- last_known_y = e.touches[0].pageY
750
- } else if ((e?.x, e?.y)) {
751
- last_known_x = e.x
752
- last_known_y = e.y
753
- }
754
- let canv_height = canvas_el.offsetHeight
755
- let canv_width = canvas_el.offsetWidth
756
- let x_change = last_known_x - start_x
757
- let y_change = last_known_y - start_y
758
- let res = update_crop_values(
759
- canv_height,
760
- canv_width,
761
- crop_drag_type,
762
- crop_top,
763
- crop_left,
764
- crop_width,
765
- crop_height,
766
- crop_top_start,
767
- crop_left_start,
768
- crop_width_start,
769
- crop_height_start,
770
- x_change,
771
- y_change,
772
- crop_aspect_ratio
773
- )
774
- crop_height = res.crop_height
775
- crop_width = res.crop_width
776
- crop_left = res.crop_left
777
- crop_top = res.crop_top
778
- }
779
- set_image_pixels_crop()
780
- }
781
-
782
- // crop ↑↑↑
783
-
784
- // ai ↓↓↓
785
-
786
- async function ai_image_generator(input) {
787
- ai_error_message = null
788
- if (typeof config?.ai_image_generator != "function") {
789
- ai_error_message = "ai_image_generator function not provided to config"
790
- return
791
- }
792
- ai_image_generator_is_loading = true
793
- const res = await config.ai_image_generator(input)
794
- if (res?.is_success) {
795
- try {
796
- init_file()
797
- const data_url = res?.data?.data_url
798
- image_sources = [data_url, ...image_sources]
799
- image_source_index = 0
800
- set_base_image(data_url)
801
- mime_type = res?.data?.mime_type || "image/webp"
802
- mime_type_input = mime_type
803
- set_file_data_base()
804
- } catch (e) {
805
- ai_error_message = "error generating image"
806
- }
807
- } else {
808
- ai_error_message = res?.error_message ?? "error generating image"
809
- }
810
- ai_image_generator_is_loading = false
811
- }
812
-
813
- async function ai_remove_background(input) {
814
- ai_error_message = null
815
- if (typeof config?.ai_remove_image_background !== "function") {
816
- ai_error_message = "ai_remove_image_background function not provided to config"
817
- return
818
- }
819
- ai_remove_background_is_loading = true
820
- const res = await config?.ai_remove_image_background(input)
821
- if (res?.is_success) {
822
- try {
823
- let response = await fetch(res?.data)
824
- let blob = await response.blob()
825
- let blob_url = URL.createObjectURL(blob)
826
- let data_url = await get_image_data_url(blob_url, "image/webp")
827
- image_sources = [data_url, ...image_sources]
828
- image_source_index = 0
829
- set_base_image(data_url)
830
- mime_type = "image/webp"
831
- mime_type_input = "image/webp"
832
- set_file_data_base()
833
- } catch (error) {
834
- console.error("Error loading image:", error)
835
- ai_error_message = "Error removing image background"
836
- }
837
- } else {
838
- ai_error_message = res?.error_message ?? "Error removing image background"
839
- }
840
- ai_remove_background_is_loading = false
841
- }
842
-
843
- async function ai_restore_resolution(input) {
844
- ai_error_message = null
845
- if (typeof config?.ai_restore_resolution !== "function") {
846
- ai_error_message = "ai_restore_resolution function not provided to config"
847
- return
848
- }
849
- ai_restore_resolution_is_loading = true
850
- const res = await config?.ai_restore_resolution(input)
851
- if (res?.is_success) {
852
- try {
853
- let response = await fetch(res?.data)
854
- let blob = await response.blob()
855
- let blob_url = URL.createObjectURL(blob)
856
- let data_url = await get_image_data_url(blob_url, "image/webp")
857
- image_sources = [data_url, ...image_sources]
858
- image_source_index = 0
859
- set_base_image(data_url)
860
- mime_type = "image/webp"
861
- mime_type_input = "image/webp"
862
- set_file_data_base()
863
- } catch (error) {
864
- console.error("Error loading image:", error)
865
- ai_error_message = "Error removing image background"
866
- }
867
- } else {
868
- ai_error_message = res?.error_message ?? "Error removing image background"
869
- }
870
- ai_restore_resolution_is_loading = false
871
- }
872
-
873
- async function ai_restore_face(input) {
874
- ai_error_message = null
875
- if (typeof config?.ai_restore_face !== "function") {
876
- ai_error_message = "ai_restore_face function not provided to config"
877
- return
878
- }
879
- ai_restore_face_is_loading = true
880
- const res = await config?.ai_restore_face(input)
881
- if (res?.is_success) {
882
- try {
883
- let response = await fetch(res?.data)
884
- let blob = await response.blob()
885
- let blob_url = URL.createObjectURL(blob)
886
- let data_url = await get_image_data_url(blob_url, "image/webp")
887
- image_sources = [data_url, ...image_sources]
888
- image_source_index = 0
889
- set_base_image(data_url)
890
- mime_type = "image/webp"
891
- mime_type_input = "image/webp"
892
- set_file_data_base()
893
- } catch (error) {
894
- console.error("Error loading image:", error)
895
- ai_error_message = "Error removing image background"
896
- }
897
- } else {
898
- ai_error_message = res?.error_message ?? "Error removing image background"
899
- }
900
- ai_restore_face_is_loading = false
901
- }
902
-
903
- // ai ↑↑↑
904
-
905
- // file ↓↓↓
906
- let file_size_data_base = {
907
- "image/png": null,
908
- "image/webp": null,
909
- "image/jpeg": null,
910
- }
911
-
912
- let base_chart_path = "M5,35 C100,35 93,30 95,5"
913
-
914
- async function set_file_data_base() {
915
- if (selected_image_source) {
916
- file_size_data = deep_copy(file_size_data_base)
917
- load_file_size_quality_data(mime_type, selected_image_source)
918
- }
919
- set_file_size_kb() // prob also run on various slider or image type changes
920
- }
921
-
922
- function get_mime_type_from_src(image_src) {
923
- let re = /^data:(image\/\w+);base64,/
924
- let result = image_src.match(re)
925
- return result && result.length > 1 ? result[1] : null
926
- }
927
-
928
- async function file_input_change(file_name, mime_type, quality) {
929
- if (file_name || mime_type) {
930
- mime_type = mime_type && file_size_data_base.hasOwnProperty(mime_type) ? mime_type : mime_type_input
931
- mime_type_input = mime_type
932
- if (mime_type && file_name_text_input_manager?.val != file_name) {
933
- file_name_text_input_manager.set_val(file_name)
934
- }
935
- }
936
- if (mime_type || quality) {
937
- quality = quality ? Math.max(1, Math.min(100, quality)) : file_quality_slider_manager?.val
938
- let image_src = selected_image_source
939
- if (image_src) {
940
- if (!file_size_data?.[mime_type] && image_src) {
941
- load_file_size_quality_data(mime_type, image_src)
942
- }
943
- }
944
- file_quality_slider_manager.set_val(quality)
945
- }
946
- set_file_size_kb()
947
- }
948
-
949
- async function set_file_from_inputs() {
950
- if (selected_image_source) {
951
- let data_url = await get_image_data_url(selected_image_source, mime_type_input, file_quality_slider_manager?.val)
952
- image_sources = [data_url, ...image_sources]
953
- mime_type = mime_type_input
954
- }
955
- }
956
-
957
- async function load_file_size_quality_data(mime_type, image_src) {
958
- if (!file_size_data?.[mime_type]) {
959
- file_size_data = deep_copy(file_size_data_base)
960
- }
961
- file_size_data[mime_type] = {
962
- is_loading: true,
963
- }
964
- if (mime_type == "image/png") {
965
- let data_url = await get_image_data_url(image_src, "image/png", 100)
966
- let file_size = calculate_file_size(data_url, "image/png")
967
- file_size_data[mime_type] = {
968
- is_loading: false,
969
- file_size_xy_data: [file_size],
970
- min_file_size_kb: null,
971
- max_file_size_kb: null,
972
- chart_path: base_chart_path,
973
- }
974
- } else {
975
- let x_vals_sets = [
976
- [1, 80, 100],
977
- [15, 95],
978
- [5, 50, 90, 99],
979
- ]
980
- let file_size_xy_data = file_size_data?.[mime_type]?.file_size_xy_data || []
981
- for (let i = 0; i < x_vals_sets.length; i++) {
982
- let x_vals = x_vals_sets[i]
983
- for (let x_val of x_vals) {
984
- let data_url = await get_image_data_url(image_src, mime_type, x_val)
985
- let file_size = calculate_file_size(data_url, mime_type)
986
- file_size_xy_data.push([x_val, file_size])
987
- }
988
- let chart_data = generate_file_size_chart(file_size_xy_data)
989
- let updated_data = { file_size_xy_data, ...chart_data }
990
- file_size_data[mime_type] = {
991
- is_loading: i < x_vals_sets.length - 1,
992
- ...updated_data,
993
- }
994
- }
995
- }
996
- }
997
-
998
- function generate_file_size_chart(file_size_data) {
999
- let w = 100
1000
- let h = 40
1001
- let x_padding = 5
1002
- let y_padding = 5
1003
- let min_file_size_kb
1004
- let max_file_size_kb
1005
- if (!file_size_data || file_size_data.length < 1) {
1006
- min_file_size_kb = null
1007
- max_file_size_kb = null
1008
- chart_path = base_chart_path
1009
- return
1010
- }
1011
- let x_values = file_size_data.map(([x, y]) => x)
1012
- let y_values = file_size_data.map(([x, y]) => y)
1013
- let min_x = Math.min(...x_values)
1014
- let max_x = Math.max(...x_values)
1015
- let min_y = Math.min(...y_values)
1016
- let max_y = Math.max(...y_values)
1017
- min_file_size_kb = min_y
1018
- max_file_size_kb = max_y
1019
- let x_scale = (w - 2 * x_padding) / w
1020
- let x_padding_scale = x_padding / w
1021
- let y_scale = (h - 2 * y_padding) / h
1022
- let y_padding_scale = y_padding / h
1023
- let normalized_data_scaled = []
1024
- for (let [x, y] of file_size_data) {
1025
- let new_x = ((x - min_x) / (max_x - min_x)) * x_scale + x_padding_scale
1026
- let new_y = (1 - (y - min_y) / (max_y - min_y)) * y_scale + y_padding_scale
1027
- normalized_data_scaled.push([new_x, new_y])
1028
- }
1029
- normalized_data_scaled.sort((a, b) => b[0] - a[0])
1030
- let chart_path = "M"
1031
- for (let item of normalized_data_scaled) {
1032
- chart_path += " " + Math.floor(item[0] * w) + "," + Math.floor(item[1] * h)
1033
- }
1034
- return {
1035
- min_file_size_kb,
1036
- max_file_size_kb,
1037
- chart_path,
1038
- }
1039
- }
1040
-
1041
- function calculate_file_size(data_url, mime_type) {
1042
- let head = `data:${mime_type};base64,`
1043
- let file_size = (data_url.length - head.length) * 0.75
1044
- return Math.round(file_size * 0.001) // size in KB
1045
- }
1046
-
1047
- async function get_image_data_url(image_src, mime_type = "image/webp", quality = 100) {
1048
- return new Promise((resolve, reject) => {
1049
- let img = new Image()
1050
- img.crossOrigin = "Anonymous"
1051
- img.onload = function () {
1052
- let canvas = document.createElement("canvas")
1053
- let ctx = canvas.getContext("2d", { willReadFrequently: true })
1054
- canvas.width = this.naturalWidth
1055
- canvas.height = this.naturalHeight
1056
- ctx.drawImage(this, 0, 0)
1057
- let data_url = canvas.toDataURL(mime_type, quality / 100)
1058
- resolve(data_url)
1059
- }
1060
- img.onerror = reject
1061
- img.src = image_src
1062
- })
1063
- }
1064
-
1065
- async function download_image() {
1066
- if (selected_image_source) {
1067
- get_image_data_url(selected_image_source, mime_type_input ?? "image/webp", file_quality_slider_manager?.val)
1068
- .then((data_url) => {
1069
- let temp_link = document.createElement("a")
1070
- temp_link.download = `${
1071
- file_name_text_input_manager?.val ? file_name_text_input_manager?.val : create_unique_id("image", 6)
1072
- }.${mime_type_extensions?.[mime_type_input ?? mime_type]}`
1073
- temp_link.href = data_url
1074
- temp_link.click()
1075
- })
1076
- .catch((err) => {
1077
- console.error(`Failed to generate download link: ${err}`)
1078
- })
1079
- }
1080
- }
1081
-
1082
- // file ↑↑↑
1083
-
1084
- function init_file(file_input) {
1085
- let hidden_image_el = document.createElement("img")
1086
- hidden_image_el.id = `${id}_hidden_image_el`
1087
- hidden_image_el.style = "display: none;"
1088
- hidden_image_el.alt = "hidden_image_el"
1089
- hidden_image_el.onload = () => main_image_transformer()
1090
- document.body.appendChild(hidden_image_el)
1091
- if (!file_input?.file) {
1092
- image_sources = []
1093
- image_source_index = null
1094
- file_name = null
1095
- file_name_text_input_manager.set_val(null)
1096
- mime_type = null
1097
- mime_type_input = null
1098
- set_base_image(null)
1099
- return
1100
- }
1101
- let src_url = URL.createObjectURL(file_input?.file)
1102
- image_sources = [src_url]
1103
- image_source_index = 0
1104
- let clean_file_name = (file_input?.file_name ?? file_input?.file?.name ?? null).replace(/\..+$/, "")
1105
- file_name = clean_file_name
1106
- file_name_text_input_manager.set_val(clean_file_name)
1107
- mime_type = file_input?.mime_type ?? file_input?.file?.type ?? null
1108
- mime_type_input = file_input?.mime_type ?? file_input?.file?.type ?? null
1109
- set_base_image(src_url)
1110
- set_file_data_base()
1111
- }
1112
-
1113
- function set_is_popover(input) {
1114
- is_popover = !!input
1115
- }
1116
-
1117
- async function init(config) {
1118
- is_popover = !!config?.is_popover
1119
- popover_manager = create_popover_manager({
1120
- min_width: 320,
1121
- target_width: 900,
1122
- min_height: 320,
1123
- target_height: 700,
1124
- header: "Edit Image",
1125
- type: "center",
1126
- })
1127
- file_input_manager = create_file_input_manager({
1128
- is_multiselect: false,
1129
- is_drop_zone: true,
1130
- accept: ["image/png", "image/jpeg", "image/webp"],
1131
- on_get_file: (input) => {
1132
- init_file({ file: input })
1133
- file_input_manager.clear_files()
1134
- },
1135
- height: "100%",
1136
- })
1137
- screen_tab_filters_button_manager = create_button_manager({
1138
- type: "soft",
1139
- text: "Filters",
1140
- icon_sw: 30,
1141
- is_compressed: true,
1142
- support_icon: "sliders",
1143
- selected_type: () => (screen_tab == "filters" ? "selected" : null),
1144
- on_click: () => set_screen_tab("filters"),
1145
- })
1146
- screen_tab_crop_button_manager = create_button_manager({
1147
- type: "soft",
1148
- text: "Crop",
1149
- is_compressed: true,
1150
- icon_sw: 30,
1151
- support_icon: "crop",
1152
- selected_type: () => (screen_tab == "crop" ? "selected" : null),
1153
- on_click: () => set_screen_tab("crop"),
1154
- })
1155
- screen_tab_resize_button_manager = create_button_manager({
1156
- type: "soft",
1157
- text: "Resize",
1158
- icon_sw: 30,
1159
- is_compressed: true,
1160
- support_icon: "resize",
1161
- selected_type: () => (screen_tab == "resize" ? "selected" : null),
1162
- on_click: () => set_screen_tab("resize"),
1163
- })
1164
- screen_tab_ai_button_manager = create_button_manager({
1165
- type: "soft",
1166
- text: "AI",
1167
- icon_sw: 30,
1168
- is_compressed: true,
1169
- support_icon: "brain",
1170
- selected_type: () => (screen_tab == "ai" ? "selected" : null),
1171
- on_click: () => set_screen_tab("ai"),
1172
- })
1173
- screen_tab_file_button_manager = create_button_manager({
1174
- type: "soft",
1175
- text: "File",
1176
- icon_sw: 30,
1177
- is_compressed: true,
1178
- support_icon: "file",
1179
- selected_type: () => (screen_tab == "file" ? "selected" : null),
1180
- on_click: () => set_screen_tab("file"),
1181
- })
1182
- undo_button_manager = create_button_manager({
1183
- type: "soft",
1184
- is_no_wrap: true,
1185
- text: () =>
1186
- `Undo ${
1187
- image_sources.length - image_source_index > 1
1188
- ? "(" + (image_sources.length - image_source_index - 1) + ")"
1189
- : ""
1190
- }`,
1191
- icon_sw: 30,
1192
- is_compressed: true,
1193
- support_icon: "undo_arrow",
1194
- is_disabled: () => image_sources.length < 2 || image_sources.length - image_source_index < 2,
1195
- on_click: () => undo(),
1196
- })
1197
- redo_button_manager = create_button_manager({
1198
- type: "soft",
1199
- is_no_wrap: true,
1200
- text: () => `Redo ${image_source_index > 0 ? "(" + image_source_index + ")" : ""}`,
1201
- icon_sw: 30,
1202
- is_compressed: true,
1203
- support_icon: "redo_arrow",
1204
- is_disabled: () => image_sources.length < 2 || image_source_index < 1,
1205
- on_click: () => redo(),
1206
- })
1207
- clear_button_manager = create_button_manager({
1208
- type: "soft",
1209
- text: "Clear",
1210
- is_compressed: true,
1211
- icon_sw: 30,
1212
- support_icon: "trashcan",
1213
- is_disabled: () => image_sources.length < 1,
1214
- on_click: () => clear(),
1215
- })
1216
- finish_button_manager = create_button_manager({
1217
- h: 10,
1218
- l: 18,
1219
- c: 14,
1220
- is_no_wrap: true,
1221
- text: "Finish",
1222
- icon_sw: 30,
1223
- is_compressed: true,
1224
- support_icon: "check",
1225
- is_disabled: () => image_sources.length < 1,
1226
- on_click: () => finish(),
1227
- })
1228
- filter_brightness_slider_manager = create_slider_manager({
1229
- label: "Brightness",
1230
- label_font_size: 1.4,
1231
- val: 100,
1232
- min: 1,
1233
- max: 200,
1234
- step: 1,
1235
- on_change: () => main_image_transformer(),
1236
- })
1237
- filter_contrast_slider_manager = create_slider_manager({
1238
- label: "Contrast",
1239
- label_font_size: 1.4,
1240
- val: 100,
1241
- min: 1,
1242
- max: 200,
1243
- step: 1,
1244
- on_change: () => main_image_transformer(),
1245
- })
1246
- filter_saturation_slider_manager = create_slider_manager({
1247
- label: "Saturation",
1248
- label_font_size: 1.4,
1249
- val: 100,
1250
- min: 1,
1251
- max: 200,
1252
- step: 1,
1253
- on_change: () => main_image_transformer(),
1254
- })
1255
- filter_grayscale_slider_manager = create_slider_manager({
1256
- label: "Grayscale",
1257
- label_font_size: 1.4,
1258
- val: 0,
1259
- min: 1,
1260
- max: 200,
1261
- step: 1,
1262
- on_change: () => main_image_transformer(),
1263
- })
1264
- filter_hue_slider_manager = create_slider_manager({
1265
- label: "Hue",
1266
- label_font_size: 1.4,
1267
- val: 0,
1268
- min: 1,
1269
- max: 200,
1270
- step: 1,
1271
- on_change: () => main_image_transformer(),
1272
- })
1273
- filter_red_slider_manager = create_slider_manager({
1274
- label: "Red",
1275
- label_font_size: 1.4,
1276
- val: 100,
1277
- min: 1,
1278
- max: 255,
1279
- step: 1,
1280
- on_change: () => main_image_transformer(),
1281
- })
1282
- filter_green_slider_manager = create_slider_manager({
1283
- label: "Green",
1284
- label_font_size: 1.4,
1285
- val: 100,
1286
- min: 1,
1287
- max: 255,
1288
- step: 1,
1289
- on_change: () => main_image_transformer(),
1290
- })
1291
- filter_blue_slider_manager = create_slider_manager({
1292
- label: "Blue",
1293
- label_font_size: 1.4,
1294
- val: 100,
1295
- min: 1,
1296
- max: 100,
1297
- step: 1,
1298
- on_change: () => main_image_transformer(),
1299
- })
1300
- filter_blur_slider_manager = create_slider_manager({
1301
- label: "Blur",
1302
- label_font_size: 1.4,
1303
- val: 0,
1304
- min: 0,
1305
- max: 200,
1306
- step: 1,
1307
- on_change: () => main_image_transformer(),
1308
- })
1309
- filter_opacity_slider_manager = create_slider_manager({
1310
- label: "Opacity",
1311
- label_font_size: 1.4,
1312
- val: 100,
1313
- min: 0,
1314
- max: 100,
1315
- step: 1,
1316
- on_change: () => main_image_transformer(),
1317
- })
1318
- filters_set_default_button_manager = create_button_manager({
1319
- type: "outlined",
1320
- is_no_wrap: true,
1321
- text: "Set Default Values",
1322
- on_click: () => reset_filters(),
1323
- })
1324
- filters_apply_filters_button_manager = create_button_manager({
1325
- is_no_wrap: true,
1326
- text: "Apply Filters",
1327
- on_click: () => apply_filters(),
1328
- })
1329
- crop_free_button_manager = create_button_manager({
1330
- type: "soft",
1331
- text: "Free",
1332
- is_disabled: () => is_disabled,
1333
- on_click: () => set_crop_box_loc(null, null),
1334
- })
1335
- crop_one_to_one_button_manager = create_button_manager({
1336
- type: "soft",
1337
- text: "1/1",
1338
- icon_sw: 30,
1339
- is_icon_left: true,
1340
- text_align: "left",
1341
- support_icon: "ar_one_to_one",
1342
- is_disabled: () => is_disabled,
1343
- is_half_selected: () => crop_aspect_ratio == 1,
1344
- on_click: () => set_crop_box_loc(1, 1),
1345
- })
1346
- crop_four_to_three_button_manager = create_button_manager({
1347
- type: "soft",
1348
- text: "4/3",
1349
- icon_sw: 30,
1350
- is_icon_left: true,
1351
- text_align: "left",
1352
- support_icon: "ar_four_to_three",
1353
- is_disabled: () => is_disabled,
1354
- is_half_selected: () => crop_aspect_ratio == 1.333,
1355
- on_click: () => set_crop_box_loc(4, 3),
1356
- })
1357
- crop_three_to_two_button_manager = create_button_manager({
1358
- type: "soft",
1359
- text: "3/2",
1360
- icon_sw: 30,
1361
- is_icon_left: true,
1362
- text_align: "left",
1363
- support_icon: "ar_three_to_two",
1364
- is_disabled: () => is_disabled,
1365
- is_half_selected: () => crop_aspect_ratio == 1.5,
1366
- on_click: () => set_crop_box_loc(3, 2),
1367
- })
1368
- crop_sixteen_to_nine_button_manager = create_button_manager({
1369
- type: "soft",
1370
- text: "16/9",
1371
- icon_sw: 30,
1372
- is_icon_left: true,
1373
- text_align: "left",
1374
- support_icon: "ar_sixteen_to_nine",
1375
- is_disabled: () => is_disabled,
1376
- is_half_selected: () => crop_aspect_ratio == 1.778,
1377
- on_click: () => set_crop_box_loc(16, 9),
1378
- })
1379
- crop_three_to_four_button_manager = create_button_manager({
1380
- type: "soft",
1381
- text: "3/4",
1382
- icon_deg: 90,
1383
- icon_sw: 30,
1384
- is_icon_left: true,
1385
- text_align: "left",
1386
- support_icon: "ar_four_to_three",
1387
- is_disabled: () => is_disabled,
1388
- is_half_selected: () => crop_aspect_ratio == 0.75,
1389
- on_click: () => set_crop_box_loc(3, 4),
1390
- })
1391
- crop_two_to_three_button_manager = create_button_manager({
1392
- type: "soft",
1393
- text: "2/3",
1394
- icon_deg: 90,
1395
- icon_sw: 30,
1396
- is_icon_left: true,
1397
- text_align: "left",
1398
- support_icon: "ar_three_to_two",
1399
- is_disabled: () => is_disabled,
1400
- is_half_selected: () => crop_aspect_ratio == 0.6667,
1401
- on_click: () => set_crop_box_loc(2, 3),
1402
- })
1403
- crop_nine_to_sixteen_button_manager = create_button_manager({
1404
- type: "soft",
1405
- text: "9/16",
1406
- icon_deg: 90,
1407
- icon_sw: 30,
1408
- is_icon_left: true,
1409
- text_align: "left",
1410
- support_icon: "ar_sixteen_to_nine",
1411
- is_disabled: () => is_disabled,
1412
- is_half_selected: () => crop_aspect_ratio == 0.5625,
1413
- on_click: () => set_crop_box_loc(9, 16),
1414
- })
1415
- crop_width_ratio_text_input_manager = create_text_input_manager({
1416
- type: "number",
1417
- val: crop_aspect_width_loc,
1418
- min: 0,
1419
- mt: 0.5,
1420
- is_compressed: true,
1421
- placeholder: "width ratio",
1422
- is_disabled: () => is_disabled,
1423
- on_change: (input) => {
1424
- crop_aspect_width_loc = input
1425
- set_crop_box(crop_aspect_width_loc, crop_aspect_height_loc)
1426
- },
1427
- })
1428
- crop_height_ratio_text_input_manager = create_text_input_manager({
1429
- type: "number",
1430
- val: crop_aspect_height_loc,
1431
- min: 0,
1432
- mt: 0.5,
1433
- is_compressed: true,
1434
- placeholder: "height ratio",
1435
- is_disabled: () => is_disabled,
1436
- on_change: (input) => {
1437
- crop_aspect_height_loc = input
1438
- set_crop_box(crop_aspect_width_loc, crop_aspect_height_loc)
1439
- },
1440
- })
1441
- crop_image_button_manager = create_button_manager({
1442
- text: "Crop Image",
1443
- mt: 0.5,
1444
- is_disabled: () => is_disabled,
1445
- on_click: () => crop_image(),
1446
- })
1447
- file_name_text_input_manager = create_text_input_manager({
1448
- label: "File Name",
1449
- placeholder: () => (file_name_derived && file_name_derived.length > 0 ? file_name_derived : "some_file_name"),
1450
- val: file_name_derived,
1451
- mb: 1,
1452
- is_disabled: () => is_disabled,
1453
- on_change: (input) => file_input_change(input, mime_type),
1454
- })
1455
- mime_type_webp_button_manager = create_button_manager({
1456
- type: "outlined",
1457
- text: "webp",
1458
- is_disabled: () => is_disabled,
1459
- selected_type: () => (mime_type_input == "image/webp" ? "selected" : null),
1460
- on_click: () => file_input_change(file_name_text_input_manager?.val, "image/webp"),
1461
- })
1462
- mime_type_jpeg_button_manager = create_button_manager({
1463
- type: "outlined",
1464
- text: "jpeg",
1465
- is_disabled: () => is_disabled,
1466
- selected_type: () => (mime_type_input == "image/jpeg" ? "selected" : null),
1467
- on_click: () => file_input_change(file_name_text_input_manager?.val, "image/jpeg"),
1468
- })
1469
- mime_type_png_button_manager = create_button_manager({
1470
- type: "outlined",
1471
- text: "png",
1472
- is_disabled: () => is_disabled,
1473
- selected_type: () => (mime_type_input == "image/png" ? "selected" : null),
1474
- on_click: () => file_input_change(file_name_text_input_manager?.val, "image/png"),
1475
- })
1476
- download_image_button_manager = create_button_manager({
1477
- type: "outlined",
1478
- text: "Download",
1479
- is_disabled: () => is_disabled,
1480
- on_click: () => download_image(),
1481
- })
1482
- set_file_changes_button_manager = create_button_manager({
1483
- text: "Set File Changes",
1484
- is_disabled: () => is_disabled,
1485
- on_click: () => set_file_from_inputs(),
1486
- })
1487
- file_quality_slider_manager = create_slider_manager({
1488
- val: 75,
1489
- min: 1,
1490
- max: 100,
1491
- step: 1,
1492
- is_disabled: () => is_disabled,
1493
- on_change: (input) => file_input_change(file_name_text_input_manager?.val, null, input),
1494
- })
1495
- ai_tab_dropdown_manager = create_dropdown_manager({
1496
- type: "horiz_selector",
1497
- val: "image_generator",
1498
- options: [
1499
- { key: "image_generator", name: "Image Generator" },
1500
- { key: "remove_background", name: "Remove Background" },
1501
- { key: "restore_resolution", name: "Restore Resolution" },
1502
- { key: "restore_face", name: "Restore Face" },
1503
- ],
1504
- })
1505
- ai_generate_image_from_text_text_input_manager = create_text_input_manager({
1506
- label: "Text Prompt",
1507
- type: "text_area",
1508
- rows: 3,
1509
- placeholder: "Describe what you want your image to be of",
1510
- is_disabled: () => ai_image_generator_is_loading,
1511
- })
1512
- ai_generate_image_images_prompt_file_input_manager = create_file_input_manager({
1513
- label: "Image Prompt",
1514
- is_multiselect: true,
1515
- is_drop_zone: false,
1516
- accept: ["image/png", "image/jpeg", "image/webp"],
1517
- })
1518
- ai_generate_image_include_workspace_in_images_prompt_checkbox_manager = create_checkbox_manager({
1519
- label: "Include Workspace Image in Images Prompt",
1520
- type: "toggle",
1521
- val: true,
1522
- })
1523
- ai_generate_image_from_text_button_manager = create_button_manager({
1524
- text: "Generate Image",
1525
- is_compressed: true,
1526
- mt: 1,
1527
- is_loading: () => ai_image_generator_is_loading,
1528
- is_disabled: () => is_disabled,
1529
- on_click: async () => {
1530
- const files = Array.isArray(ai_generate_image_images_prompt_file_input_manager?.val)
1531
- ? [...ai_generate_image_images_prompt_file_input_manager.val]
1532
- : []
1533
- if (selected_image_source && ai_generate_image_include_workspace_in_images_prompt_checkbox_manager?.val) {
1534
- try {
1535
- const target_mime = mime_type_input ?? "image/webp"
1536
- const quality = file_quality_slider_manager?.val ?? 75
1537
- const data_url = await get_image_data_url(selected_image_source, target_mime, quality)
1538
- const m = data_url.match(/^data:(.*?);base64,(.*)$/)
1539
- if (m) {
1540
- const mime = m[1] || target_mime
1541
- const bin = atob(m[2])
1542
- const bytes = new Uint8Array(bin.length)
1543
- for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i)
1544
- const ext = mime_type_extensions?.[mime] || "bin"
1545
- const base =
1546
- file_name_text_input_manager?.val ||
1547
- (typeof create_unique_id === "function" ? create_unique_id("image", 6) : "workspace-image")
1548
- const file = new File([bytes], `${base}.${ext}`, { type: mime })
1549
- files.push(file)
1550
- }
1551
- } catch (e) {
1552
- console.error("failed to include workspace image", e)
1553
- }
1554
- }
1555
- await ai_image_generator({
1556
- text_prompt: ai_generate_image_from_text_text_input_manager?.val,
1557
- images_prompt: files,
1558
- })
1559
- },
1560
- })
1561
- ai_remove_bg_button_manager = create_button_manager({
1562
- text: "Remove Background",
1563
- is_compressed: true,
1564
- is_loading: () => ai_remove_background_is_loading,
1565
- is_disabled: () => is_disabled,
1566
- on_click: () => ai_remove_background(selected_image_source),
1567
- })
1568
- ai_restore_resolution_button_manager = create_button_manager({
1569
- text: "Restore Resolution",
1570
- is_compressed: true,
1571
- is_loading: () => ai_restore_resolution_is_loading,
1572
- is_disabled: () => is_disabled,
1573
- on_click: () => ai_restore_resolution(selected_image_source),
1574
- })
1575
- ai_restore_face_button_manager = create_button_manager({
1576
- text: "Restore Face",
1577
- is_compressed: true,
1578
- is_loading: () => ai_restore_face_is_loading,
1579
- is_disabled: () => is_disabled,
1580
- on_click: () => ai_restore_face(selected_image_source),
1581
- })
1582
- resize_width_dropdown_manager = create_dropdown_manager({
1583
- type: "horiz_selector",
1584
- val: resize_width,
1585
- min_header_width: 9.5,
1586
- header: "Width",
1587
- header_icon: "opposing_arrows",
1588
- header_icon_deg: 90,
1589
- options: resize_options,
1590
- is_disabled: () => is_disabled,
1591
- on_item_click: (input) => {
1592
- set_resize_dimensions(input.key, null)
1593
- resize_width_text_input_manager.set_val(resize_width)
1594
- resize_height_text_input_manager.set_val(resize_height)
1595
- },
1596
- })
1597
- resize_height_dropdown_manager = create_dropdown_manager({
1598
- type: "horiz_selector",
1599
- val: resize_height,
1600
- min_header_width: 9.5,
1601
- header: "Height",
1602
- header_icon: "opposing_arrows",
1603
- header_icon_deg: 0,
1604
- options: resize_options,
1605
- is_disabled: () => is_disabled,
1606
- on_item_click: (input) => {
1607
- set_resize_dimensions(null, input.key)
1608
- resize_width_text_input_manager.set_val(resize_width)
1609
- resize_height_text_input_manager.set_val(resize_height)
1610
- },
1611
- })
1612
- resize_width_text_input_manager = create_text_input_manager({
1613
- type: "number",
1614
- val: resize_width,
1615
- min: 0,
1616
- mt: 0.5,
1617
- label: "Resize Width",
1618
- is_popover: true,
1619
- is_popover_edit_content: true,
1620
- is_compressed: true,
1621
- placeholder: "resize width",
1622
- is_disabled: () => is_disabled,
1623
- on_finish: (input) => {
1624
- set_resize_dimensions(input, null)
1625
- if (resize_height_text_input_manager?.val != resize_height) {
1626
- resize_height_text_input_manager.set_val(resize_height)
1627
- }
1628
- },
1629
- })
1630
- resize_height_text_input_manager = create_text_input_manager({
1631
- type: "number",
1632
- val: resize_height,
1633
- min: 0,
1634
- mt: 0.5,
1635
- label: "Resize Height",
1636
- is_popover: true,
1637
- is_popover_edit_content: true,
1638
- is_compressed: true,
1639
- placeholder: "resize height",
1640
- is_disabled: () => is_disabled,
1641
- on_finish: (input) => {
1642
- set_resize_dimensions(null, input)
1643
- if (resize_width_text_input_manager?.val != resize_width) {
1644
- resize_width_text_input_manager.set_val(resize_width)
1645
- }
1646
- },
1647
- })
1648
- resize_aspect_ratio_lock_button_manager = create_button_manager({
1649
- type: "outlined",
1650
- icon_sw: 30,
1651
- fixed_width: 20,
1652
- mt: 0.5,
1653
- support_icon: () => (is_lock_resize_aspect_ratio ? "linked" : "unlinked"),
1654
- text: () => `${is_lock_resize_aspect_ratio ? "Unlock" : "Lock"} Aspect Ratio`,
1655
- selected_type: () => (is_lock_resize_aspect_ratio ? "selected" : null),
1656
- is_disabled: () => is_disabled,
1657
- on_click: () => toggle_is_lock_resize_aspect_ratio(),
1658
- })
1659
- resize_image_button_manager = create_button_manager({
1660
- text: "Resize Image",
1661
- is_compressed: true,
1662
- mt: 0.5,
1663
- is_success_animation: true,
1664
- is_disabled: () => is_disabled || !resize_width || !resize_height,
1665
- on_click: () => main_image_transformer(),
1666
- })
1667
- // init_file() issue if called without document defined
1668
- }
1669
-
1670
- init(config)
1671
-
1672
- return {
1673
- id,
1674
- get file_picker_file() {
1675
- return file_picker_file
1676
- },
1677
- get image_sources() {
1678
- return image_sources
1679
- },
1680
- get image_source_index() {
1681
- return image_source_index
1682
- },
1683
- get selected_image_source() {
1684
- return selected_image_source
1685
- },
1686
- get screen_tab() {
1687
- return screen_tab
1688
- },
1689
- get crop_left() {
1690
- return crop_left
1691
- },
1692
- get crop_top() {
1693
- return crop_top
1694
- },
1695
- get crop_width() {
1696
- return crop_width
1697
- },
1698
- get crop_height() {
1699
- return crop_height
1700
- },
1701
- get is_disabled() {
1702
- return is_disabled
1703
- },
1704
- get current_image_width() {
1705
- return current_image_width
1706
- },
1707
- get current_image_height() {
1708
- return current_image_height
1709
- },
1710
- get image_pixels_crop_width() {
1711
- return image_pixels_crop_width
1712
- },
1713
- get image_pixels_crop_height() {
1714
- return image_pixels_crop_height
1715
- },
1716
- get current_image_ar() {
1717
- return current_image_ar
1718
- },
1719
- get crop_aspect_ratio() {
1720
- return crop_aspect_ratio
1721
- },
1722
- get is_lock_resize_aspect_ratio() {
1723
- return is_lock_resize_aspect_ratio
1724
- },
1725
- get resize_width() {
1726
- return resize_width
1727
- },
1728
- get resize_height() {
1729
- return resize_height
1730
- },
1731
- get file_size_data() {
1732
- return file_size_data
1733
- },
1734
- get mime_type_input() {
1735
- return mime_type_input
1736
- },
1737
- get file_size_kb() {
1738
- return file_size_kb
1739
- },
1740
- get file_name() {
1741
- return file_name
1742
- },
1743
- get file_name_derived() {
1744
- return file_name_derived
1745
- },
1746
- get file_name_derived_with_extension() {
1747
- return file_name_derived_with_extension
1748
- },
1749
- get ai_error_message() {
1750
- return ai_error_message
1751
- },
1752
- get file_input_manager() {
1753
- return file_input_manager
1754
- },
1755
- get screen_tab_filters_button_manager() {
1756
- return screen_tab_filters_button_manager
1757
- },
1758
- get screen_tab_crop_button_manager() {
1759
- return screen_tab_crop_button_manager
1760
- },
1761
- get screen_tab_resize_button_manager() {
1762
- return screen_tab_resize_button_manager
1763
- },
1764
- get screen_tab_ai_button_manager() {
1765
- return screen_tab_ai_button_manager
1766
- },
1767
- get screen_tab_file_button_manager() {
1768
- return screen_tab_file_button_manager
1769
- },
1770
- get undo_button_manager() {
1771
- return undo_button_manager
1772
- },
1773
- get redo_button_manager() {
1774
- return redo_button_manager
1775
- },
1776
- get clear_button_manager() {
1777
- return clear_button_manager
1778
- },
1779
- get finish_button_manager() {
1780
- return finish_button_manager
1781
- },
1782
- get is_show_img_slider() {
1783
- return is_show_img_slider
1784
- },
1785
- get filter_brightness_slider_manager() {
1786
- return filter_brightness_slider_manager
1787
- },
1788
- get filter_contrast_slider_manager() {
1789
- return filter_contrast_slider_manager
1790
- },
1791
- get filter_saturation_slider_manager() {
1792
- return filter_saturation_slider_manager
1793
- },
1794
- get filter_grayscale_slider_manager() {
1795
- return filter_grayscale_slider_manager
1796
- },
1797
- get filter_hue_slider_manager() {
1798
- return filter_hue_slider_manager
1799
- },
1800
- get filter_red_slider_manager() {
1801
- return filter_red_slider_manager
1802
- },
1803
- get filter_green_slider_manager() {
1804
- return filter_green_slider_manager
1805
- },
1806
- get filter_blue_slider_manager() {
1807
- return filter_blue_slider_manager
1808
- },
1809
- get filter_blur_slider_manager() {
1810
- return filter_blur_slider_manager
1811
- },
1812
- get filter_opacity_slider_manager() {
1813
- return filter_opacity_slider_manager
1814
- },
1815
- get filters_set_default_button_manager() {
1816
- return filters_set_default_button_manager
1817
- },
1818
- get filters_apply_filters_button_manager() {
1819
- return filters_apply_filters_button_manager
1820
- },
1821
- get crop_free_button_manager() {
1822
- return crop_free_button_manager
1823
- },
1824
- get crop_one_to_one_button_manager() {
1825
- return crop_one_to_one_button_manager
1826
- },
1827
- get crop_four_to_three_button_manager() {
1828
- return crop_four_to_three_button_manager
1829
- },
1830
- get crop_three_to_two_button_manager() {
1831
- return crop_three_to_two_button_manager
1832
- },
1833
- get crop_sixteen_to_nine_button_manager() {
1834
- return crop_sixteen_to_nine_button_manager
1835
- },
1836
- get crop_three_to_four_button_manager() {
1837
- return crop_three_to_four_button_manager
1838
- },
1839
- get crop_two_to_three_button_manager() {
1840
- return crop_two_to_three_button_manager
1841
- },
1842
- get crop_nine_to_sixteen_button_manager() {
1843
- return crop_nine_to_sixteen_button_manager
1844
- },
1845
- get crop_width_ratio_text_input_manager() {
1846
- return crop_width_ratio_text_input_manager
1847
- },
1848
- get crop_height_ratio_text_input_manager() {
1849
- return crop_height_ratio_text_input_manager
1850
- },
1851
- get crop_image_button_manager() {
1852
- return crop_image_button_manager
1853
- },
1854
- get crop_aspect_width_loc() {
1855
- return crop_aspect_width_loc
1856
- },
1857
- get crop_aspect_height_loc() {
1858
- return crop_aspect_height_loc
1859
- },
1860
- get file_name_text_input_manager() {
1861
- return file_name_text_input_manager
1862
- },
1863
- get mime_type_webp_button_manager() {
1864
- return mime_type_webp_button_manager
1865
- },
1866
- get mime_type_jpeg_button_manager() {
1867
- return mime_type_jpeg_button_manager
1868
- },
1869
- get mime_type_png_button_manager() {
1870
- return mime_type_png_button_manager
1871
- },
1872
- get download_image_button_manager() {
1873
- return download_image_button_manager
1874
- },
1875
- get set_file_changes_button_manager() {
1876
- return set_file_changes_button_manager
1877
- },
1878
- get shown_file_size_data() {
1879
- return shown_file_size_data
1880
- },
1881
- get file_quality_slider_manager() {
1882
- return file_quality_slider_manager
1883
- },
1884
- get ai_tab_dropdown_manager() {
1885
- return ai_tab_dropdown_manager
1886
- },
1887
- get ai_image_generator_is_loading() {
1888
- return ai_image_generator_is_loading
1889
- },
1890
- get ai_generate_image_from_text_text_input_manager() {
1891
- return ai_generate_image_from_text_text_input_manager
1892
- },
1893
- get ai_generate_image_images_prompt_file_input_manager() {
1894
- return ai_generate_image_images_prompt_file_input_manager
1895
- },
1896
- get ai_generate_image_include_workspace_in_images_prompt_checkbox_manager() {
1897
- return ai_generate_image_include_workspace_in_images_prompt_checkbox_manager
1898
- },
1899
- get ai_generate_image_from_text_button_manager() {
1900
- return ai_generate_image_from_text_button_manager
1901
- },
1902
- get ai_remove_bg_button_manager() {
1903
- return ai_remove_bg_button_manager
1904
- },
1905
- get ai_restore_resolution_button_manager() {
1906
- return ai_restore_resolution_button_manager
1907
- },
1908
- get ai_restore_face_button_manager() {
1909
- return ai_restore_face_button_manager
1910
- },
1911
- get resize_width_dropdown_manager() {
1912
- return resize_width_dropdown_manager
1913
- },
1914
- get resize_height_dropdown_manager() {
1915
- return resize_height_dropdown_manager
1916
- },
1917
- get resize_width_text_input_manager() {
1918
- return resize_width_text_input_manager
1919
- },
1920
- get resize_height_text_input_manager() {
1921
- return resize_height_text_input_manager
1922
- },
1923
- get resize_aspect_ratio_lock_button_manager() {
1924
- return resize_aspect_ratio_lock_button_manager
1925
- },
1926
- get resize_image_button_manager() {
1927
- return resize_image_button_manager
1928
- },
1929
- get is_popover() {
1930
- return is_popover
1931
- },
1932
- get popover_manager() {
1933
- return popover_manager
1934
- },
1935
- init,
1936
- init_file,
1937
- on_destroy,
1938
- set_screen_tab,
1939
- undo,
1940
- redo,
1941
- clear,
1942
- finish,
1943
- set_base_image,
1944
- apply_filters,
1945
- reset_filters,
1946
- main_image_transformer,
1947
- crop_on_up,
1948
- crop_on_move,
1949
- crop_on_down,
1950
- set_crop_box,
1951
- crop_image,
1952
- toggle_is_lock_resize_aspect_ratio,
1953
- set_resize_dimensions,
1954
- main_image_transformer,
1955
- file_input_change,
1956
- download_image,
1957
- set_file_from_inputs,
1958
- drop_handler,
1959
- set_is_popover,
1960
- }
1961
- }