Please bookmark this page to avoid losing your image tool!

Image Drag And Drop With Textbox Overlay Tool

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, defaultText = "Название", textColor = "#FFFFFF", boxBgColor = "rgba(0, 0, 0, 0.6)", fontSize = 20) {
    // Determine dimensions from the loaded image
    const width = originalImg.naturalWidth || originalImg.width || 800;
    const height = originalImg.naturalHeight || originalImg.height || 600;

    // Create the main container div
    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.display = 'inline-block';
    container.style.width = width + 'px';
    container.style.height = height + 'px';
    container.style.overflow = 'hidden';
    container.style.userSelect = 'none';

    // Add the image to the background
    const bgImg = new Image();
    bgImg.src = originalImg.src;
    bgImg.style.width = '100%';
    bgImg.style.height = '100%';
    bgImg.style.display = 'block';
    bgImg.style.pointerEvents = 'none';
    container.appendChild(bgImg);

    // Create the draggable overlay wrapper
    const overlay = document.createElement('div');
    overlay.style.position = 'absolute';
    overlay.style.left = '50%';
    overlay.style.top = '50%';
    overlay.style.transform = 'translate(-50%, -50%)';
    overlay.style.backgroundColor = boxBgColor;
    overlay.style.border = '1px solid #ccc';
    overlay.style.borderRadius = '6px';
    overlay.style.boxShadow = '0 4px 12px rgba(0,0,0,0.5)';
    overlay.style.display = 'flex';
    overlay.style.flexDirection = 'column';
    overlay.style.minWidth = '200px';
    overlay.style.fontFamily = 'Arial, sans-serif';

    // Create the drag handle
    const handle = document.createElement('div');
    handle.style.width = '100%';
    handle.style.height = '24px';
    handle.style.backgroundColor = 'rgba(255, 255, 255, 0.2)';
    handle.style.borderTopLeftRadius = '5px';
    handle.style.borderTopRightRadius = '5px';
    handle.style.cursor = 'move';
    handle.title = 'Drag to move';
    
    // Aesthetic dots for the handle
    handle.innerHTML = '<div style="display:flex; justify-content:center; align-items:center; height:100%; gap:4px;">' +
                       '<span style="width:4px; height:4px; background:#fff; border-radius:50%;"></span>' +
                       '<span style="width:4px; height:4px; background:#fff; border-radius:50%;"></span>' +
                       '<span style="width:4px; height:4px; background:#fff; border-radius:50%;"></span>' +
                       '</div>';

    // Create the editable text area
    const textArea = document.createElement('div');
    textArea.contentEditable = 'true';
    textArea.innerText = defaultText;
    textArea.style.color = textColor;
    textArea.style.fontSize = fontSize + 'px';
    textArea.style.padding = '12px 16px';
    textArea.style.outline = 'none';
    textArea.style.minHeight = '40px';
    textArea.style.cursor = 'text';
    textArea.style.userSelect = 'text';
    textArea.style.pointerEvents = 'auto';
    textArea.style.wordWrap = 'break-word';

    overlay.appendChild(handle);
    overlay.appendChild(textArea);
    container.appendChild(overlay);

    // Variables for drag-and-drop logic
    let isDragging = false;
    let startX = 0, startY = 0;
    let initialLeft = 0, initialTop = 0;

    const startDrag = (e) => {
        isDragging = true;
        
        const clientX = e.touches ? e.touches[0].clientX : e.clientX;
        const clientY = e.touches ? e.touches[0].clientY : e.clientY;

        const rect = overlay.getBoundingClientRect();
        const containerRect = container.getBoundingClientRect();

        // Convert centered transform coordinates to hard pixel offsets
        initialLeft = rect.left - containerRect.left;
        initialTop = rect.top - containerRect.top;

        overlay.style.transform = 'none';
        overlay.style.left = initialLeft + 'px';
        overlay.style.top = initialTop + 'px';

        startX = clientX;
        startY = clientY;
        
        if (!e.touches) e.preventDefault();
    };

    const moveDrag = (e) => {
        if (!isDragging) return;
        
        const clientX = e.touches ? e.touches[0].clientX : e.clientX;
        const clientY = e.touches ? e.touches[0].clientY : e.clientY;

        const dx = clientX - startX;
        const dy = clientY - startY;

        let newLeft = initialLeft + dx;
        let newTop = initialTop + dy;

        const containerRect = container.getBoundingClientRect();
        
        // Define bounding boxes to keep the overlay within the image
        const maxLeft = containerRect.width - overlay.offsetWidth;
        const maxTop = containerRect.height - overlay.offsetHeight;

        newLeft = Math.max(0, Math.min(newLeft, maxLeft));
        newTop = Math.max(0, Math.min(newTop, maxTop));

        overlay.style.left = newLeft + 'px';
        overlay.style.top = newTop + 'px';
    };

    const endDrag = () => {
        isDragging = false;
    };

    // Attach event listeners for mouse and touch interactions
    handle.addEventListener('mousedown', startDrag);
    handle.addEventListener('touchstart', startDrag, { passive: false });

    window.addEventListener('mousemove', moveDrag);
    window.addEventListener('touchmove', moveDrag, { passive: false });

    window.addEventListener('mouseup', endDrag);
    window.addEventListener('touchend', endDrag);

    // Clean up window event listeners once container is removed from the DOM
    const observer = new MutationObserver(() => {
        if (!document.body.contains(container)) {
            window.removeEventListener('mousemove', moveDrag);
            window.removeEventListener('touchmove', moveDrag);
            window.removeEventListener('mouseup', endDrag);
            window.removeEventListener('touchend', endDrag);
            observer.disconnect();
        }
    });

    observer.observe(document.body, { childList: true, subtree: true });

    return container;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

This tool allows you to overlay an editable text box onto any image. It features a draggable interface that lets you position the text box anywhere within the image boundaries, making it easy to add titles, labels, or captions. This is useful for creating quick social media graphics, adding watermarks, or labeling photos for presentations and documentation.

Leave a Reply

Your email address will not be published. Required fields are marked *