#images.js
// images.js

// Assumes uploadFile, showContextMenu, addResizeListeners are available globally

socket.on('new_image', (data) => {
const image = createImageElement(data);
document.getElementById('board').appendChild(image);
});

socket.on('updated_image', (data) => {
const image = document.querySelector(.image[data-id="${data.id}"]);
if (image) {
image.style.left = ${data.x}px;
image.style.top = ${data.y}px;
image.style.width = ${data.width}px;
image.style.height = ${data.height}px;
image.querySelector('img').src = data.url;
}
});

socket.on('element_deleted', (data) => {
if (data.type === 'image') {
const element = document.querySelector(.image[data-id="${data.id}"]);
if (element) {
element.remove();
}
}
});

function createImageElement(data) {
const image = document.createElement('div');
image.className = 'image';
image.dataset.id = data.id;
image.style.left = ${data.x}px;
image.style.top = ${data.y}px;
image.style.width = ${data.width}px;
image.style.height = ${data.height}px;

const img = document.createElement('img');
img.src = data.url;
img.style.width = '100%';
img.style.height = '100%';
img.style.objectFit = 'contain'; // Maintains aspect ratio

image.appendChild(img);

addImageEventListeners(image, data.id);

return image;
}

function addImageEventListeners(image, id) {
image.addEventListener('mousedown', (e) => {
if (e.button !== 0) return; // Left mouse button
e.preventDefault();
e.stopPropagation();
const startX = e.clientX;
const startY = e.clientY;
const startLeft = parseFloat(image.style.left) || 0;
const startTop = parseFloat(image.style.top) || 0;


function moveImage(e) {
    const deltaX = (e.clientX - startX) / scale;
    const deltaY = (e.clientY - startY) / scale;
    image.style.left = `${startLeft + deltaX}px`;
    image.style.top = `${startTop + deltaY}px`;
    const x = parseFloat(image.style.left) || 0;
    const y = parseFloat(image.style.top) || 0;
    const width = image.offsetWidth;
    const height = image.offsetHeight;
    socket.emit('update_image', { id, url: image.querySelector('img').src, x, y, width, height });
}

document.addEventListener('mousemove', moveImage);

document.addEventListener('mouseup', () => {
    document.removeEventListener('mousemove', moveImage);
}, { once: true });
});

image.addEventListener('touchstart', (e) => {
e.preventDefault();
e.stopPropagation();
const startX = e.touches[0].clientX;
const startY = e.touches[0].clientY;
const startLeft = parseFloat(image.style.left) || 0;
const startTop = parseFloat(image.style.top) || 0;


function moveImage(e) {
    const deltaX = (e.touches[0].clientX - startX) / scale;
    const deltaY = (e.touches[0].clientY - startY) / scale;
    image.style.left = `${startLeft + deltaX}px`;
    image.style.top = `${startTop + deltaY}px`;
    const x = parseFloat(image.style.left) || 0;
    const y = parseFloat(image.style.top) || 0;
    const width = image.offsetWidth;
    const height = image.offsetHeight;
    socket.emit('update_image', { id, url: image.querySelector('img').src, x, y, width, height });
}

document.addEventListener('touchmove', moveImage);

document.addEventListener('touchend', () => {
    document.removeEventListener('touchmove', moveImage);
}, { once: true });
});

image.addEventListener('dblclick', (e) => {
e.preventDefault();
e.stopPropagation();
showContextMenu(image, id, e.clientX, e.clientY);
});

image.addEventListener('touchstart', (e) => {
if (e.touches.length === 2) {
e.preventDefault();
e.stopPropagation();
showContextMenu(image, id, e.touches[0].clientX, e.touches[0].clientY);
}
});

addResizeListeners(image, id, 'image');
}

function handleExistingImages() {
document.querySelectorAll('.image').forEach(image => {
const id = image.dataset.id;
const url = image.querySelector('img').src;
const x = image.offsetLeft;
const y = image.offsetTop;
const width = image.offsetWidth;
const height = image.offsetHeight;


image.addEventListener('dblclick', (e) => {
    e.preventDefault();
    e.stopPropagation();
    showContextMenu(image, id, e.clientX, e.clientY);
});

addImageEventListeners(image, id);
});
}

#notes.js
// notes.js

// Assumes uploadFile, showContextMenu, addResizeListeners are available globally

socket.on('new_note', (data) => {
const note = createNoteElement(data);
document.getElementById('board').appendChild(note);
});

socket.on('updated_note', (data) => {
const note = document.querySelector(.note[data-id="${data.id}"]);
if (note) {
note.style.left = ${data.x}px;
note.style.top = ${data.y}px;
note.style.width = ${data.width}px;
note.style.height = ${data.height}px;
note.querySelector('textarea').value = data.text;
}
});

socket.on('element_deleted', (data) => {
if (data.type === 'note') {
const element = document.querySelector(.note[data-id="${data.id}"]);
if (element) {
element.remove();
}
}
});

function createNoteElement(data) {
const note = document.createElement('div');
note.className = 'note';
note.dataset.id = data.id;
note.style.left = ${data.x}px;
note.style.top = ${data.y}px;
note.style.width = ${data.width}px;
note.style.height = ${data.height}px;

const textarea = document.createElement('textarea');
textarea.value = data.text;
textarea.addEventListener('input', () => {
const x = note.offsetLeft;
const y = note.offsetTop;
const width = note.offsetWidth;
const height = note.offsetHeight;
socket.emit('update_note', { id: data.id, text: textarea.value, x, y, width, height });
});

textarea.addEventListener('mousedown', (e) => {
e.stopPropagation();
});

note.appendChild(textarea);

addNoteEventListeners(note, data.id);

return note;
}

function addNoteEventListeners(note, id) {
note.addEventListener('mousedown', (e) => {
if (e.button !== 0) return; // Left mouse button
e.preventDefault();
e.stopPropagation();
const startX = e.clientX;
const startY = e.clientY;
const startLeft = parseFloat(note.style.left) || 0;
const startTop = parseFloat(note.style.top) || 0;


function moveNote(e) {
    const deltaX = (e.clientX - startX) / scale;
    const deltaY = (e.clientY - startY) / scale;
    note.style.left = `${startLeft + deltaX}px`;
    note.style.top = `${startTop + deltaY}px`;
    const x = parseFloat(note.style.left) || 0;
    const y = parseFloat(note.style.top) || 0;
    const width = note.offsetWidth;
    const height = note.offsetHeight;
    socket.emit('update_note', { id, text: note.querySelector('textarea').value, x, y, width, height });
}

document.addEventListener('mousemove', moveNote);

document.addEventListener('mouseup', () => {
    document.removeEventListener('mousemove', moveNote);
}, { once: true });
});

note.addEventListener('touchstart', (e) => {
e.preventDefault();
e.stopPropagation();
const startX = e.touches[0].clientX;
const startY = e.touches[0].clientY;
const startLeft = parseFloat(note.style.left) || 0;
const startTop = parseFloat(note.style.top) || 0;


function moveNote(e) {
    const deltaX = (e.touches[0].clientX - startX) / scale;
    const deltaY = (e.touches[0].clientY - startY) / scale;
    note.style.left = `${startLeft + deltaX}px`;
    note.style.top = `${startTop + deltaY}px`;
    const x = parseFloat(note.style.left) || 0;
    const y = parseFloat(note.style.top) || 0;
    const width = note.offsetWidth;
    const height = note.offsetHeight;
    socket.emit('update_note', { id, text: note.querySelector('textarea').value, x, y, width, height });
}

document.addEventListener('touchmove', moveNote);

document.addEventListener('touchend', () => {
    document.removeEventListener('touchmove', moveNote);
}, { once: true });
});

note.addEventListener('dblclick', (e) => {
e.preventDefault();
e.stopPropagation();
showContextMenu(note, id, e.clientX, e.clientY);
});

note.addEventListener('touchstart', (e) => {
if (e.touches.length === 2) {
e.preventDefault();
e.stopPropagation();
showContextMenu(note, id, e.touches[0].clientX, e.touches[0].clientY);
}
});

addResizeListeners(note, id, 'note');
}

function handleExistingNotes() {
document.querySelectorAll('.note').forEach(note => {
const id = note.dataset.id;
const text = note.querySelector('textarea').value;
const x = note.offsetLeft;
const y = note.offsetTop;
const width = note.offsetWidth;
const height = note.offsetHeight;


note.querySelector('textarea').addEventListener('input', () => {
    const x = note.offsetLeft;
    const y = note.offsetTop;
    const width = note.offsetWidth;
    const height = note.offsetHeight;
    socket.emit('update_note', { id, text: note.querySelector('textarea').value, x, y, width, height });
});

note.querySelector('textarea').addEventListener('mousedown', (e) => {
    e.stopPropagation();
});

note.addEventListener('dblclick', (e) => {
    e.preventDefault();
    e.stopPropagation();
    showContextMenu(note, id, e.clientX, e.clientY);
});

addNoteEventListeners(note, id);
});
}

Как мне сделать чтобы перемещать элемент с помощью тачпада я мог только при двойном нажатии. Тоесть первое нажатие короткое, а второе зажимаю и перетаскиваю. Управление мышью не должно быть нарушено