#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);
    });
}

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