vybe/client/space.js

94 lines
2.1 KiB
JavaScript

let space = document.getElementById('space');
let scale = 1;
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;
//save
}
function remove(span) {
//remove
span.remove();
}
function add(x, y) {
let span = document.createElement('span');
span.classList.add('span');
span.contentEditable = true;
span.spellcheck = false;
span.scale = 1;
span.style.left = `${x}px`;
span.style.top = `${y}px`;
span.style.transform = 'translate(-50%, -50%)';
span.onkeydown = function(event) {
if (event.key === 'Enter' && !event.getModifierState('Shift')) {
event.preventDefault();
editing = null;
span.blur();
}
};
span.oninput = function(event) {
this.time = Date.now();
//save
};
span.onblur = function(event) {
if (!this.innerText)
remove(this);
};
span.onwheel = function(event) {
event.preventDefault();
this.scale *= 1 - event.deltaY * .001;
this.style.transform = `translate(-50%, -50%) scale(${this.scale})`;
//save
};
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;
}
space.onmouseup = event => {
if (dragging) {
dragging.onmouseup(event);
return;
}
if (editing) {
if (!editing.innerText)
remove(editing);
if (event.target !== editing)
editing = null;
return;
}
editing = add(event.offsetX + space.scrollLeft, event.offsetY + space.scrollTop);
editing.focus();
};