all repos — artbound-python @ 2bfd559153b962cd9dc4a06c668905d196984b8a

A client-server reimplementation of the administration panel for ArtBound.

artbound_python/static/script.js (view raw)

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