artbound_python/static/script.js (view raw)
1const MAX_WIDTH = MAX_HEIGHT = 1000,
2 WATERMARK_SRC = "/static/res/wm.png",
3 WATERMARK_WIDTH = 325,
4 WATERMARK_HEIGHT = 98,
5 IG_TEMPLATE_SRC = "/static/res/ig.png",
6 IG_MIN_OFFSET_X = 0,
7 IG_MIN_OFFSET_Y = 342,
8 IG_MAX_WIDTH = 1080,
9 IG_MAX_HEIGHT = 988,
10
11 WATERMARK = new Image(),
12 IG_TEMPLATE = new Image(),
13 last_updated_link = document.getElementById("last-updated-link"),
14 month_input = document.getElementById("month_input"),
15 month_div = document.getElementById("month_div"),
16 get_button = document.getElementById("get_button"),
17 selectall_button = document.getElementById("selectall_button"),
18 selectnone_button = document.getElementById("selectnone_button"),
19 controls_div = document.getElementById("controls"),
20 opacity_range = document.getElementById("opacity_range"),
21 main_container_div = document.getElementById("main_container"),
22 content_div = document.getElementById("content"),
23 canvas_link = document.getElementById("canvas-download"),
24 canvas_ig = document.getElementById("instagram-canvas"),
25 fanart_template = document.getElementById("fanart-template").innerHTML;
26
27let fanarts = new Array(),
28 new_entries = 0;
29
30WATERMARK.src = WATERMARK_SRC;
31IG_TEMPLATE.src = IG_TEMPLATE_SRC;
32month_input.addEventListener("keyup", (e) => { if (e.key === "Enter") getArtworks(); });
33
34function addCanvasEvents(element, ctx) {
35 function abc(e) {
36 if (element.enabled == 0) return;
37 if (e.button != 0) return;
38 element.watermark.opacity = opacity_range.value;
39 addWatermark(e, element, ctx);
40 }
41 if (element.clicked) {
42 element.canvas.addEventListener('mousedown', abc);
43 return;
44 }
45 element.canvas.addEventListener('mousemove', abc);
46 element.canvas.addEventListener('mouseleave', () => {
47 if (!element.clicked && element.enabled)
48 setBaseImage(element.image, element.canvas, ctx);
49 });
50 element.canvas.addEventListener('mousedown', (e) => {
51 element.clicked = true;
52 element.canvas.removeEventListener('mousemove', abc);
53 element.canvas.addEventListener('mousedown', abc);
54 });
55}
56
57function createElementFromHTML(htmlString) {
58 const div = document.createElement('div');
59 div.innerHTML = htmlString.trim();
60 return div.firstChild;
61}
62
63function getNewCardHtml(element) {
64 const id = element.id,
65 index = element.index,
66 name = element.name,
67 content = element.content,
68 filename = `${('0' + element.index).slice(-2)} - ${element.name}.png`,
69 disabled = element.enabled == 0 ? " entry-disabled" : "";
70 const html_string = Mustache.render("{{={| |}=}}" + fanart_template, { id, index, name, content, filename, disabled });
71 element.div = createElementFromHTML(html_string);
72 element.canvas = element.div.getElementsByTagName("canvas")[0];
73 const ctx = element.canvas.getContext("2d");
74 element.image = new Image();
75 element.image.addEventListener("load", () => {
76 const wm_info = element.watermark;
77 setBaseImage(element.image, element.canvas, ctx);
78 if (element.clicked)
79 drawWatermark(wm_info, ctx);
80 addCanvasEvents(element, ctx);
81 });
82 element.image.src = element.content;
83 return element.div;
84}
85
86async function updateFanartList() {
87 main_container_div.hidden = false;
88 content_div.innerHTML = "";
89 get_button.disabled = false;
90 get_button.innerText = "Aggiungi";
91
92 let i = 0;
93 for (fanart of fanarts) {
94 if (fanart.enabled) {
95 i++;
96 fanart.index = i;
97 content_div.appendChild(getNewCardHtml(fanart));
98 }
99 }
100 for (fanart of fanarts) {
101 if (!fanart.enabled) {
102 fanart.index = 0;
103 content_div.appendChild(getNewCardHtml(fanart));
104 }
105 }
106}
107
108function getFanart(id) {
109 return fanarts.find(element => element.id == id)
110}
111
112function toggleEntry(id) {
113 entry = getFanart(id);
114 if (!entry) return;
115
116 entry.enabled = !entry.enabled;
117 updateFanartList()
118}
119
120function saveCanvas(my_canvas, filename) {
121 canvas_link.href = my_canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
122 canvas_link.setAttribute("download", filename);
123 canvas_link.click()
124}
125
126function reloadEntry(id) {
127 const fanart = getFanart(id);
128 if (!fanart) return;
129
130 const old_div = fanart.div;
131 content_div.replaceChild(getNewCardHtml(fanart), old_div);
132 old_div.remove();
133}
134
135function selectAllNone(toggle) {
136 fanarts.map(x => x.enabled = toggle)
137 updateFanartList()
138}
139
140function clickCoordsToCanvas(clickX, clickY, c) {
141 const rect = c.getBoundingClientRect();
142 const x = (clickX - rect.left) * c.width / c.clientWidth;
143 const y = (clickY - rect.top) * c.height / c.clientHeight;
144 return [x, y];
145}
146
147function drawWatermark(wm_info, ctx) {
148 ctx.globalAlpha = wm_info.opacity;
149 ctx.filter = wm_info.invert;
150 ctx.drawImage(WATERMARK, wm_info.x - (WATERMARK_WIDTH / 2), wm_info.y - (WATERMARK_HEIGHT / 2), WATERMARK_WIDTH, WATERMARK_HEIGHT);
151}
152
153function addWatermark(event, element, ctx) {
154 setBaseImage(element.image, element.canvas, ctx);
155 const [x, y] = clickCoordsToCanvas(event.clientX, event.clientY, element.canvas);
156 element.watermark.x = x;
157 element.watermark.y = y
158 drawWatermark(element.watermark, ctx);
159}
160
161function updateOpacity() {
162 opacity_label.innerHTML = Math.round(opacity_range.value * 100) + '%';
163}
164
165function getFactor(img_width, img_height, max_width, max_height) {
166 return Math.min(max_width / img_width, max_height / img_height);
167}
168
169function setBaseImage(img, c, ctx) {
170 const f = getFactor(img.width, img.height, MAX_WIDTH, MAX_HEIGHT);
171 const new_width = c.width = Math.ceil(img.width * f);
172 const new_height = c.height = Math.ceil(img.height * f)
173 ctx.imageSmoothingEnabled = (f < 1);
174 ctx.drawImage(img, 0, 0, new_width, new_height);
175}
176
177function moveUpDown(id, amount) {
178 const entry = fanarts.find(element => element.id == id);
179 if (!entry) return;
180 if (!entry.enabled) return;
181 const pos = fanarts.indexOf(entry);
182 const new_pos = pos + amount;
183
184 if (new_pos <= -1 || new_pos >= fanarts.length) return;
185
186 [fanarts[pos], fanarts[new_pos]] = [fanarts[new_pos], fanarts[pos]];
187 updateFanartList();
188}
189
190function toggleInvert(id, button) {
191 const entry = fanarts.find(element => element.id == id);
192 if (!entry) return;
193 if (!entry.enabled) return;
194 entry.watermark.invert = entry.watermark.invert == '' ? 'invert(1)' : '';
195 button.innerText = entry.watermark.invert ? "⚫" : "⚪";
196 const ctx = entry.canvas.getContext('2d');
197 setBaseImage(entry.image, entry.canvas, ctx);
198 drawWatermark(entry.watermark, ctx);
199}
200
201async function postData(url = "", data = {}, contentType = "application/json") {
202 const response = await fetch(url, { method: "POST", headers: { "Content-Type": contentType }, body: JSON.stringify(data) });
203 return response.json();
204}
205
206function saveEntry(id) {
207 const entry = getFanart(id);
208 if (!entry) return;
209 if (!entry.enabled) return;
210 saveCanvas(entry.canvas, entry.canvas.getAttribute("data-filename"));
211}
212
213function saveCanvasIG(my_canvas) {
214 const f = getFactor(my_canvas.width, my_canvas.height, IG_MAX_WIDTH, IG_MAX_HEIGHT);
215 const width = Math.ceil(my_canvas.width * f);
216 const height = Math.ceil(my_canvas.height * f);
217 const offset_x = Math.round((IG_MAX_WIDTH - width) / 2);
218 const offset_y = Math.round((IG_MAX_HEIGHT - height) / 2);
219 destCtx = canvas_ig.getContext('2d');
220 destCtx.drawImage(IG_TEMPLATE, 0, 0);
221 destCtx.drawImage(my_canvas, IG_MIN_OFFSET_X + offset_x, IG_MIN_OFFSET_Y + offset_y, width, height);
222 saveCanvas(canvas_ig, "IG - " + my_canvas.getAttribute("data-filename"));
223}
224
225function saveEntryIG(id) {
226 entry = getFanart(id);
227 if (!entry) return;
228 if (!entry.enabled) return;
229 saveCanvasIG(entry.canvas);
230}
231
232function getArtworks() {
233 get_button.disabled = true;
234 get_button.innerText = "…"
235 postData("/", { month: month_input.value }).then((data) => {
236 fanarts = fanarts.concat(data);
237 controls_div.hidden = false;
238 updateOpacity();
239 updateFanartList();
240 });
241}
242
243function saveAll() {
244 const response = confirm("Vuoi davvero scaricare tutte le fanart?");
245 if (response == false) return;
246 fanarts.forEach((fanart) => {
247 if (fanart.enabled)
248 saveCanvas(fanart.canvas, fanart.canvas.getAttribute("data-filename"));
249 })
250}
251
252function saveAllIG() {
253 const response = confirm("Vuoi davvero scaricare tutte le storie per le fanart?");
254 if (response == false) return;
255 fanarts.forEach((fanart) => {
256 if (fanart.enabled)
257 saveCanvasIG(fanart.canvas);
258 });
259}
260
261function updateDb() {
262 postData("/update").then((data) => {
263 last_updated_link.innerText = data.timestamp;
264 if (data.new == 0) return;
265 new_entries += data.new;
266 last_updated_link.innerText += ` (+${new_entries})`;
267 });
268}