vybe/client/space.js

164 lines
3.7 KiB
JavaScript
Raw Normal View History

2024-04-15 14:27:21 -07:00
let space;
2024-03-18 23:07:48 -07:00
2024-06-12 03:00:50 -07:00
let scale = 1; // todo: make zooming work
2024-03-18 23:07:48 -07:00
let editing;
let dragging;
let moved;
let offset;
function mousemove(event) {
let left = (event.clientX - space.offsetLeft) * scale - offset.x;
let top = (event.clientY - space.offsetTop) * scale - offset.y;
dragging.style.left = `${left < 0 ? 0 : left}px`;
dragging.style.top = `${top < 0 ? 0 : top}px`;
moved = true;
2024-04-15 14:27:21 -07:00
save(dragging);
2024-03-18 23:07:48 -07:00
}
2024-04-26 18:46:00 -07:00
let saving;
let queue;
2024-04-15 14:27:21 -07:00
function save(span) {
2024-04-26 18:46:00 -07:00
if (saving) {
queue = span;
return;
}
saving = true;
2024-06-12 03:00:50 -07:00
window.currentInstance.emit('save_span', {
thread: window.currentThread.id,
2024-04-15 14:27:21 -07:00
id: span.id ? span.id.slice(4) : '',
content: span.innerText,
x: span.style.left.slice(0, -2),
y: span.style.top.slice(0, -2),
scale: span.scale
}, msg => {
2024-04-15 21:52:21 -07:00
if (!msg.success)
console.log('span save failed: ' + msg.message);
2024-04-15 14:27:21 -07:00
if (!span.id)
span.id = 'span' + msg.id;
2024-04-26 18:46:00 -07:00
saving = false;
if (queue) {
save(queue);
queue = null;
}
2024-04-15 14:27:21 -07:00
});
2024-03-18 23:07:48 -07:00
}
2024-04-15 22:23:14 -07:00
function add(s) {
2024-03-18 23:07:48 -07:00
let span = document.createElement('span');
span.classList.add('span');
2024-04-15 22:23:14 -07:00
if (s.id)
span.id = 'span' + s.id;
span.innerText = s.content;
2024-03-18 23:07:48 -07:00
span.contentEditable = true;
span.spellcheck = false;
2024-04-15 22:23:14 -07:00
span.scale = s.scale;
span.style.left = `${s.x}px`;
span.style.top = `${s.y}px`;
span.style.transform = `translate(-50%, -50%) scale(${s.scale})`;
2024-03-18 23:07:48 -07:00
span.onkeydown = function(event) {
if (event.key === 'Enter' && !event.getModifierState('Shift')) {
event.preventDefault();
editing = null;
span.blur();
}
};
span.oninput = function(event) {
2024-04-15 14:27:21 -07:00
save(this);
2024-03-18 23:07:48 -07:00
};
span.onblur = function(event) {
2024-04-15 14:27:21 -07:00
if (this.innerText)
return;
this.remove();
2024-06-12 03:00:50 -07:00
if (this.id)
save(this);
2024-03-18 23:07:48 -07:00
};
span.onwheel = function(event) {
event.preventDefault();
2024-04-29 21:05:45 -07:00
if (event.deltaY < 0 && this.scale >= 200)
return;
2024-03-18 23:07:48 -07:00
this.scale *= 1 - event.deltaY * .001;
this.style.transform = `translate(-50%, -50%) scale(${this.scale})`;
2024-04-15 21:52:21 -07:00
save(this);
2024-03-18 23:07:48 -07:00
};
span.onmousedown = function(event) {
if (dragging || editing === this)
return;
dragging = this;
event.preventDefault();
offset = {
x: event.clientX - (space.offsetLeft + this.offsetLeft),
y: event.clientY - (space.offsetTop + this.offsetTop)
};
moved = false;
document.addEventListener('mousemove', mousemove);
};
span.onmouseup = function(event) {
event.stopPropagation();
document.removeEventListener('mousemove', mousemove);
dragging = null;
if (moved)
return;
this.focus();
editing = this;
};
space.append(span);
return span;
}
2024-05-16 20:40:09 -07:00
export default function loadSpace(callback) {
2024-06-12 03:00:50 -07:00
let instance = window.currentInstance;
if (!instance.spaceid) {
2024-04-15 14:27:21 -07:00
space = document.getElementById('space');
space.onmouseup = event => {
if (dragging) {
dragging.onmouseup(event);
return;
}
if (editing) {
if (event.target !== editing)
editing = null;
return;
}
2024-04-15 22:23:14 -07:00
editing = add({
x: event.offsetX + space.scrollLeft,
y: event.offsetY + space.scrollTop,
scale: 1,
content: ''
});
2024-04-15 14:27:21 -07:00
editing.focus();
};
2024-06-12 03:00:50 -07:00
instance.socket.on('span', msg => {
if (msg.thread !== instance.spaceid || window.currentInstance !== instance)
return;
let span = document.getElementById('span' + msg.id);
if (span) {
span.innerText = msg.content;
span.style.left = `${msg.x}px`;
span.style.top = `${msg.y}px`;
span.scale = msg.scale;
span.style.transform = `translate(-50%, -50%) scale(${msg.scale})`;
}
else
add(msg);
});
2024-03-18 23:07:48 -07:00
}
2024-06-12 03:00:50 -07:00
else if (instance.spaceid === window.currentThread.id)
2024-03-18 23:07:48 -07:00
return;
2024-06-12 03:00:50 -07:00
instance.spaceid = window.currentThread.id;
2024-04-15 14:27:21 -07:00
space.innerHTML = '';
2024-06-12 03:00:50 -07:00
instance.emit('get_space', {
thread: window.currentThread.id
}, msg => {
2024-05-16 20:40:09 -07:00
if (!msg.success) {
2024-04-15 21:52:21 -07:00
console.log('get space failed: ' + msg.message);
2024-05-16 20:40:09 -07:00
return;
}
callback && callback(msg.spans);
2024-06-12 03:00:50 -07:00
msg.spans.forEach(add);
2024-04-15 14:27:21 -07:00
});
2024-03-18 23:07:48 -07:00
};