|
|
|
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 === 'rasterize_numbers') {
|
|
|
|
const value = msg.up_to;
|
|
|
|
const at = msg.at;
|
|
|
|
|
|
|
|
number_base.x = at.x;
|
|
|
|
number_base.y = at.y;
|
|
|
|
|
|
|
|
for (let i = 1; i <= value; ++i) {
|
|
|
|
queue_rasterize(i, {...at});
|
|
|
|
at.x += 1;
|
|
|
|
if (at.x === Math.floor(config.raster_texture_size / config.w)) {
|
|
|
|
at.x = 0;
|
|
|
|
at.y += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} 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);
|
|
|
|
}
|