vybe/client/space.js

206 lines
5.3 KiB
JavaScript
Raw Normal View History

2025-03-20 00:01:15 -07:00
let spaceContainer, space;
2024-03-18 23:07:48 -07:00
let editing;
let dragging;
let moved;
2024-10-10 19:44:28 -07:00
let movedFrom;
2024-03-18 23:07:48 -07:00
let offset;
2025-03-20 00:01:15 -07:00
let clicked;
document.addEventListener('mouseup', function(event) {
clicked = false;
});
2024-03-18 23:07:48 -07:00
2025-03-20 00:01:15 -07:00
document.addEventListener('mousemove', function(event) {
2024-08-27 13:12:04 -07:00
moved = true;
2025-03-20 00:01:15 -07:00
if (dragging) {
let left = event.clientX - spaceContainer.offsetLeft - offset.x;
let top = event.clientY - spaceContainer.offsetTop - offset.y;
dragging.style.left = `${left < 0 ? 0 : left}px`;
dragging.style.top = `${top < 0 ? 0 : top}px`;
save(dragging);
}
else if (clicked) {
spaceContainer.scrollLeft -= event.movementX;
spaceContainer.scrollTop -= event.movementY;
}
});
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();
2025-03-20 00:01:15 -07:00
event.stopPropagation();
2024-03-18 23:07:48 -07:00
this.scale *= 1 - event.deltaY * .001;
2025-03-20 00:01:15 -07:00
if (this.scale > 100)
this.scale = 100;
2024-03-18 23:07:48 -07:00
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;
event.preventDefault();
2025-03-20 00:01:15 -07:00
if (event.button !== 0)
return;
dragging = this;
2024-03-18 23:07:48 -07:00
offset = {
2025-03-20 00:01:15 -07:00
x: event.clientX - (spaceContainer.offsetLeft + this.offsetLeft),
y: event.clientY - (spaceContainer.offsetTop + this.offsetTop)
2024-03-18 23:07:48 -07:00
};
};
span.onmouseup = function(event) {
2025-03-20 00:01:15 -07:00
if (event.button !== 0)
return;
2024-03-18 23:07:48 -07:00
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;
2025-03-20 00:01:15 -07:00
let scale = 1;
if (!instance.spaced) {
spaceContainer = document.getElementById('space');
space = document.getElementById('spacediv');
spaceContainer.onwheel = function(event) {
if (event.getModifierState('Shift'))
return;
event.preventDefault();
scale *= 1 - event.deltaY * .001;
if (scale < .5)
scale = .5;
space.style.transform = `scale(${scale})`;
spaceContainer.scrollLeft += event.offsetX * (scale - scale / (1 - event.deltaY * .001));
spaceContainer.scrollTop += event.offsetY * (scale - scale / (1 - event.deltaY * .001));
//spaceContainer.scrollLeft += spaceContainer.clientWidth * (1 - spaceContainer.clientWidth / spaceContainer.scrollWidth + event.offsetX / spaceContainer.clientWidth) * (scale - scale / (1 - event.deltaY * .001));
//spaceContainer.scrollTop += spaceContainer.clientHeight * (1 - spaceContainer.clientHeight / spaceContainer.scrollHeight + event.offsetY / spaceContainer.clientHeight) * (scale - scale / (1 - event.deltaY * .001));
};
spaceContainer.onmousedown = function(event) {
if (event.button !== 0)
return;
clicked = true;
2024-08-27 13:12:04 -07:00
moved = false;
2024-10-10 19:44:28 -07:00
movedFrom = { x: event.offsetX, y: event.offsetY };
2024-08-27 13:12:04 -07:00
};
2025-03-20 00:01:15 -07:00
spaceContainer.onmouseup = function(event) {
if (event.button !== 0)
return;
2024-04-15 14:27:21 -07:00
if (dragging) {
dragging.onmouseup(event);
return;
}
if (editing) {
if (event.target !== editing)
editing = null;
return;
}
2024-10-10 19:44:28 -07:00
if (moved && (event.offsetX - movedFrom.x) * (event.offsetX - movedFrom.x)
+ (event.offsetY - movedFrom.y) * (event.offsetY - movedFrom.y) > 100)
2024-08-27 13:12:04 -07:00
return;
2024-04-15 22:23:14 -07:00
editing = add({
2025-03-20 00:01:15 -07:00
x: (event.offsetX + spaceContainer.scrollLeft) / scale,
y: (event.offsetY + spaceContainer.scrollTop) / scale,
2024-04-15 22:23:14 -07:00
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 => {
2025-03-20 00:01:15 -07:00
if (msg.thread !== window.currentSpace.id || window.currentInstance !== instance)
2024-06-12 03:00:50 -07:00
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);
});
2025-03-20 00:01:15 -07:00
instance.spaced = true;
2024-03-18 23:07:48 -07:00
}
2025-03-20 00:01:15 -07:00
else if (window.currentSpace === window.currentThread)
2024-03-18 23:07:48 -07:00
return;
2025-03-20 00:01:15 -07:00
window.currentSpace = window.currentThread;
2024-04-15 14:27:21 -07:00
space.innerHTML = '';
2025-03-20 00:01:15 -07:00
space.style.transform = '';
2024-06-12 03:00:50 -07:00
instance.emit('get_space', {
2025-03-20 00:01:15 -07:00
thread: window.currentSpace.id
2024-06-12 03:00:50 -07:00
}, 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
};