From 3459c5fb9ab8e74276442989f7b82826ed6c0cae Mon Sep 17 00:00:00 2001 From: Kai Vogelgesang Date: Sat, 21 Mar 2020 13:06:42 +0100 Subject: [PATCH] Refactor JS into its own file --- index.html | 226 +---------------------------------------------------- main.js | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+), 225 deletions(-) create mode 100644 main.js diff --git a/index.html b/index.html index 532377e..f0a235c 100644 --- a/index.html +++ b/index.html @@ -96,230 +96,6 @@ - + \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..943a349 --- /dev/null +++ b/main.js @@ -0,0 +1,221 @@ +let pixel_per_cm = 1, + img, + monitors = []; + +let canvas = document.getElementById("canvas"), + global_width_cm = document.getElementById("global_width_cm"), + global_height_cm = document.getElementById("global_height_cm"), + img_width_cm = document.getElementById("img_width_cm"), + img_height_cm = document.getElementById("img_height_cm"), + img_offset_top = document.getElementById("img_offset_top"), + img_offset_left = document.getElementById("img_offset_left"), + img_upload = document.getElementById("img_upload"); + +canvas.getContext("2d").fillRect(0, 0, canvas.width, canvas.height); + +const update_hash = () => { + location.hash = global_width_cm.value + "x" + global_height_cm.value; + + for (let monitor of monitors) { + location.hash += "," + + monitor.aspect_ratio.value + + "/" + monitor.diagonal_cm.value + + "/" + monitor.offset_top_cm.value + + "/" + monitor.offset_left_cm.value + } +}; + +const redraw = () => { + canvas.width = global_width_cm.value * pixel_per_cm; + canvas.height = global_height_cm.value * pixel_per_cm; + + let ctx = canvas.getContext("2d"); + + ctx.fillRect(0, 0, canvas.width, canvas.height); + + if (img) { + ctx.drawImage( + img, + img_offset_left.value * pixel_per_cm, img_offset_top.value * pixel_per_cm, + img_width_cm.value * pixel_per_cm, img_height_cm.value * pixel_per_cm + ); + } + + for (let monitor of monitors) monitor.redraw(); +}; + +const round_to_float = (x) => { + return Math.round(x * 10) / 10; +}; + +const upload_image = (e) => { + let reader = new FileReader(), + f = e.target.files.item(0); + + reader.onload = (e) => { + + let new_img = new Image(); + new_img.setAttribute("src", e.target.result.toString()); + new_img.addEventListener("load", () => { + img = new_img; + + if ((img.width / img.height < global_width_cm.value / global_height_cm.value)) { + // image is wider + img_width_cm.value = global_width_cm.value; + img_height_cm.value = round_to_float(img.height / img.width * img_width_cm.value); + img_offset_left.value = 0; + img_offset_top.value = round_to_float((global_height_cm.value - img_height_cm.value) / 2); + } else { + // canvas is wider + img_height_cm.value = global_height_cm.value; + img_width_cm.value = round_to_float(img.width / img.height * img_height_cm.value); + img_offset_top.value = 0; + img_offset_left.value = round_to_float((global_width_cm.value - img_width_cm.value) / 2); + } + + pixel_per_cm = new_img.width / img_width_cm.value; + + redraw(); + }); + }; + + reader.readAsDataURL(f); +}; + +img_upload.addEventListener("change", upload_image); + +global_width_cm.addEventListener("input", () => { + redraw(); + update_hash(); +}); +global_height_cm.addEventListener("input", () => { + redraw(); + update_hash(); +}); + +img_width_cm.addEventListener("input", () => { + img_height_cm.value = round_to_float(img.height / img.width * img_width_cm.value); + redraw(); +}); +img_height_cm.addEventListener("input", () => { + img_width_cm.value = round_to_float(img.width / img.height * img_height_cm.value); + redraw(); +}); + +img_offset_top.addEventListener("input", redraw); +img_offset_left.addEventListener("input", redraw); + +let add_monitor_button = document.getElementById("add_monitor_button"), + monitor_setings_template = document.getElementById("monitor_settings_template"), + monitors_column = document.getElementById("monitors_column"), + monitor_images = document.getElementById("monitor_images"); + +const add_monitor = () => { + + let monitor_id = monitors.length + 1; + + let settings_clone = document.importNode(monitor_setings_template.content, true); + let monitor_canvas = document.createElement("canvas"); + + monitor_canvas.style.position = "absolute"; + monitor_canvas.style.top = "0"; + monitor_canvas.style.left = "0"; + monitor_canvas.draggable = true; + monitor_canvas.style.outline = "2px solid grey"; + + let aspect_ratio = settings_clone.querySelector('[name="aspect_ratio"]'), + diagonal_cm = settings_clone.querySelector('[name="diagonal_cm"]'), + offset_top_cm = settings_clone.querySelector('[name="offset_top_cm"]'), + offset_left_cm = settings_clone.querySelector('[name="offset_left_cm"]'), + get_image_button = settings_clone.querySelector('[name="get_image_button"]'); + + settings_clone.querySelector('h2').innerText += ' ' + monitor_id; + + let redraw_monitor = () => { + let [width, height] = aspect_ratio.value.split(":"); + let alpha = Math.atan2(height, width); + + let width_cm = diagonal_cm.value * Math.cos(alpha), + height_cm = diagonal_cm.value * Math.sin(alpha); + + let width_percent = round_to_float(100 * width_cm / global_width_cm.value), + height_percent = round_to_float(100 * height_cm / global_height_cm.value), + + offset_top_percent = round_to_float(100 * offset_top_cm.value / global_height_cm.value), + offset_left_percent = round_to_float(100 * offset_left_cm.value / global_width_cm.value); + + monitor_canvas.width = width_cm * pixel_per_cm; + monitor_canvas.height = height_cm * pixel_per_cm; + + monitor_canvas.getContext("2d").drawImage( + canvas, + offset_left_cm.value * pixel_per_cm, offset_top_cm.value * pixel_per_cm, + width_cm * pixel_per_cm, height_cm * pixel_per_cm, + 0, 0, + monitor_canvas.width, monitor_canvas.height + ); + + monitor_canvas.style.width = width_percent + "%"; + monitor_canvas.style.height = height_percent + "%"; + monitor_canvas.style.top = offset_top_percent + "%"; + monitor_canvas.style.left = offset_left_percent + "%"; + }; + + redraw_monitor(); + + const input_handler = () => { + redraw_monitor(); + update_hash(); + }; + + aspect_ratio.addEventListener('change', input_handler); + diagonal_cm.addEventListener('input', input_handler); + offset_top_cm.addEventListener('input', input_handler); + offset_left_cm.addEventListener('input', input_handler); + + get_image_button.addEventListener('click', () => { + console.log(monitor_canvas.toDataURL()); + + let temp_a = document.createElement('a'); + temp_a.setAttribute('href', monitor_canvas.toDataURL()); + temp_a.setAttribute('download', 'monitor_' + monitor_id + '.png'); + temp_a.style.display = 'none'; + + document.body.appendChild(temp_a); + temp_a.click(); + document.body.removeChild(temp_a); + }); + + let current_monitor = { + aspect_ratio: aspect_ratio, + diagonal_cm: diagonal_cm, + offset_top_cm: offset_top_cm, + offset_left_cm: offset_left_cm, + canvas: monitor_canvas, + + redraw: redraw_monitor, + }; + + monitors.push(current_monitor); + + monitors_column.appendChild(settings_clone); + monitor_images.appendChild(monitor_canvas); + + return current_monitor; +}; + +add_monitor_button.addEventListener("click", add_monitor); + +if (location.hash !== "") { + + let [global_hash, ...monitor_hashes] = location.hash.substr(1).split(","); + + [global_width_cm.value, global_height_cm.value] = global_hash.split("x"); + + for (let monitor_hash of monitor_hashes) { + let monitor = add_monitor(); + [monitor.aspect_ratio.value, monitor.diagonal_cm.value, monitor.offset_top_cm.value, monitor.offset_left_cm.value] = monitor_hash.split("/"); + } + + redraw(); +} \ No newline at end of file