function init_listeners() { document.querySelector('#c').addEventListener('dragover', cancel); document.querySelector('#c').addEventListener('drop', drop); document.querySelector('#c').addEventListener('click', debug); document.querySelector('#c').addEventListener('mousedown', mousedown); document.querySelector('#c').addEventListener('mousemove', mousemove); document.querySelector('#c').addEventListener('mouseup', mouseup); document.querySelector('#c').addEventListener('mouseleave', mouseleave); document.querySelector('#c').addEventListener('wheel', wheel); document.querySelector('#file-input').addEventListener('change', form_upload); window.addEventListener('keydown', keydown); window.addEventListener('keyup', keyup); } function debug() { schedule_draw(); } function cancel(e) { e.preventDefault(); e.stopPropagation(); } function mousedown(e) { if (e.button === 1 || (e.button === 0 && spacedown)) { moving = true; return; } } function mousemove(e) { let do_draw = false; if (moving) { offset.x += e.movementX; offset.y += e.movementY; do_draw = true; } if (do_draw) { schedule_draw(); } } function mouseleave(e) { if (moving) { moving = false; } } function mouseup(e) { if ((e.button === 1 || e.button === 0 && spacedown) && moving) { moving = false; } } function wheel(e) { const screenp = {'x': window.devicePixelRatio * e.clientX, 'y': window.devicePixelRatio * e.clientY}; const zooming_in = e.deltaY < 0; let level = zooming_in ? zoom_level + 2 : zoom_level - 2; const dz = (level > 0 ? config.zoom_delta : -config.zoom_delta); if (level > config.max_zoom_level) { level = config.max_zoom_level; } zoom_level = level; zoom_target = Math.pow(1.0 + dz, Math.abs(zoom_level)) zoom_screenp = screenp; schedule_draw(); } function jump_to_first_instruction() { if (Object.keys(traces).length > 0) { const quads = traces[Object.keys(traces)[0]].geo; offset.x = -quads.pos[0] + config.padding * 2; offset.y = quads.pos[1] + config.padding * 2; zoom_target = 1; zoom = 1; schedule_draw(); } } function keydown(e) { if (e.code === 'Digit0') { jump_to_first_instruction(); } else if (e.code === 'Space') { spacedown = true; } } function keyup(e) { if (e.code === 'Space') { spacedown = false; if (moving) { moving = false; } } } function upload_file(file) { const fr = new FileReader(); const upload_failed = () => { console.error('Upload failed'); }; const upload_started = () => { console.log('Upload started'); }; const upload_finished = () => { const text = fr.result; console.log('Upload finished. String length:', text.length); import_worker.onmessage = (e) => { const msg = e.data; if (msg.type === 'trace') { traces['0'] = msg.data; jump_to_first_instruction(); schedule_draw(); } else if (msg.type === 'rasterize') { const data = msg.data; queue_rasterize(data.text, data.at); } else if (msg.type === 'progress_parse') { console.log(`Parsing: ${msg.data}%`); } else if (msg.type === 'progress_generate') { console.log(`Generating geometry: ${msg.data}%`); } }; import_worker.postMessage({'type': 'import', 'text': text}); }; const upload_progress = (e) => { if (e.lengthComputable) { const percent = Math.floor(e.loaded / e.total * 100); console.log(`Uploading: ${percent}%`); } else { console.log('Uploading: unknown'); } }; fr.addEventListener('abort', upload_failed); fr.addEventListener('error', upload_failed); fr.addEventListener('load', upload_finished); fr.addEventListener('loadstart', upload_started); fr.addEventListener('progress', upload_progress); fr.readAsText(file); } function form_upload(e) { if (e.target.files.length === 1) { upload_file(e.target.files[0]); } else if (e.target.files > 1) { console.error('Only one file at a time for now!'); } } function drop(e) { e.preventDefault(); if (e.dataTransfer.files.length !== 1) { console.error('Only one file at once, please!'); return false; } const file = e.dataTransfer.files[0]; upload_file(file); }