Please bookmark this page to avoid losing your image tool!

Image Drag And Drop Website Interface Builder

(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, sidebarWidth = "250px", defaultBgColor = "#ffffff") {
    // Main Container setup
    const container = document.createElement('div');
    container.style.display = 'flex';
    container.style.width = '100%';
    container.style.height = '80vh'; 
    container.style.minHeight = '600px';
    container.style.fontFamily = 'Segoe UI, Tahoma, Geneva, Verdana, sans-serif';
    container.style.border = '1px solid #ced4da';
    container.style.boxSizing = 'border-box';
    container.style.color = '#333';
    container.style.backgroundColor = defaultBgColor;

    // Sidebar setup
    const sidebar = document.createElement('div');
    sidebar.style.width = sidebarWidth;
    sidebar.style.minWidth = sidebarWidth;
    sidebar.style.backgroundColor = '#f8f9fa';
    sidebar.style.borderRight = '1px solid #dee2e6';
    sidebar.style.padding = '15px';
    sidebar.style.boxSizing = 'border-box';
    sidebar.style.display = 'flex';
    sidebar.style.flexDirection = 'column';
    sidebar.style.overflowY = 'auto';
    sidebar.style.zIndex = '10';

    const title = document.createElement('h3');
    title.textContent = 'Website Elements';
    title.style.margin = '0 0 15px 0';
    title.style.fontSize = '18px';
    title.style.fontWeight = '600';
    sidebar.appendChild(title);

    // Draggable Component Library
    const components = [
        { 
          name: 'Header Navbar', 
          type: 'container', 
          html: '<div style="width: 100%; height: 100%; background-color: #343a40; color: white; display: flex; align-items: center; padding: 0 20px; box-sizing: border-box; font-family: sans-serif; font-size: 18px; font-weight: bold;">Navigation Bar</div>',
          width: '100%', height: '60px', resize: true
        },
        { 
          name: 'Primary Button', 
          type: 'button', 
          html: '<button style="width: 100%; height: 100%; cursor: pointer; border: none; background-color: #0d6efd; color: white; border-radius: 6px; font-size: 16px; font-weight: 500; font-family: sans-serif;">Submit</button>',
          width: '120px', height: '45px', resize: true
        },
        { 
          name: 'Editable Text Area', 
          type: 'text', 
          html: '<div contenteditable="true" style="width: 100%; height: 100%; padding: 10px; box-sizing: border-box; cursor: text; font-family: sans-serif; overflow: hidden; font-size: 16px; border: 1px dashed transparent; line-height: 1.5; color: #495057;">Click here to edit this paragraph text...</div>',
          width: '250px', height: '100px', resize: true
        },
        { 
          name: 'Title Heading', 
          type: 'header', 
          html: '<h1 contenteditable="true" style="margin: 0; width: 100%; height: 100%; cursor: text; font-family: sans-serif; overflow: hidden; font-size: 36px; font-weight: 700; color: #212529;">Heading Title</h1>',
          width: '250px', height: '50px', resize: true
        },
        { 
          name: 'Original Extracted Image', 
          type: 'image', 
          html: `<img src="${originalImg.src}" style="width: 100%; height: 100%; object-fit: contain; pointer-events: none;" draggable="false" alt="Tool Image"/>`,
          width: '200px', height: '200px', resize: true
        },
        { 
          name: 'Text Input Field', 
          type: 'input', 
          html: '<input type="text" placeholder="Type input here..." style="width: 100%; height: 100%; box-sizing: border-box; border: 1px solid #ced4da; border-radius: 4px; padding: 0 12px; font-size: 16px; font-family: sans-serif; outline: none;"/>',
          width: '200px', height: '40px', resize: true
        },
        {
          name: 'Structure Block',
          type: 'container',
          html: '<div style="width: 100%; height: 100%; border: 2px dashed #adb5bd; background: rgba(0, 0, 0, 0.03); box-sizing: border-box; border-radius: 8px;"></div>',
          width: '300px', height: '200px', resize: true
        }
    ];

    let draggedComponent = null;

    // Render Component Buttons in Sidebar
    components.forEach(comp => {
        const el = document.createElement('div');
        el.textContent = comp.name;
        el.style.padding = '12px 10px';
        el.style.marginBottom = '12px';
        el.style.backgroundColor = '#ffffff';
        el.style.border = '1px solid #ced4da';
        el.style.color = '#495057';
        el.style.cursor = 'grab';
        el.style.textAlign = 'center';
        el.style.borderRadius = '6px';
        el.style.boxShadow = '0 1px 3px rgba(0,0,0,0.05)';
        el.style.transition = 'all 0.2s';
        
        el.onmouseenter = () => { el.style.backgroundColor = '#e9ecef'; el.style.borderColor = '#adb5bd'; };
        el.onmouseleave = () => { el.style.backgroundColor = '#ffffff'; el.style.borderColor = '#ced4da'; };

        el.setAttribute('draggable', 'true');
        
        el.addEventListener('dragstart', (e) => {
            draggedComponent = comp;
            e.dataTransfer.effectAllowed = 'copy';
            e.dataTransfer.setData('text/plain', comp.type);
        });

        el.addEventListener('dragend', () => {
            setTimeout(() => draggedComponent = null, 100);
        });

        sidebar.appendChild(el);
    });

    // Sidebar Controls Area
    const controlsTitle = document.createElement('h3');
    controlsTitle.textContent = 'Controls';
    controlsTitle.style.marginTop = 'auto'; 
    controlsTitle.style.paddingTop = '20px';
    controlsTitle.style.fontSize = '16px';
    controlsTitle.style.fontWeight = '600';
    sidebar.appendChild(controlsTitle);

    const bgBtn = document.createElement('button');
    bgBtn.textContent = 'Set Image as BG';
    bgBtn.style.padding = '10px';
    bgBtn.style.width = '100%';
    bgBtn.style.marginBottom = '10px';
    bgBtn.style.cursor = 'pointer';
    bgBtn.style.backgroundColor = '#198754';
    bgBtn.style.color = '#fff';
    bgBtn.style.border = 'none';
    bgBtn.style.borderRadius = '6px';
    bgBtn.onclick = () => {
        workspace.style.backgroundImage = `url(${originalImg.src})`;
        workspace.style.backgroundSize = 'contain';
        workspace.style.backgroundRepeat = 'no-repeat';
        workspace.style.backgroundPosition = 'center';
    };
    bgBtn.onmouseenter = () => bgBtn.style.backgroundColor = '#157347';
    bgBtn.onmouseleave = () => bgBtn.style.backgroundColor = '#198754';
    sidebar.appendChild(bgBtn);

    const gridBtn = document.createElement('button');
    gridBtn.textContent = 'Blueprint Grid Mode';
    gridBtn.style.padding = '10px';
    gridBtn.style.width = '100%';
    gridBtn.style.marginBottom = '10px';
    gridBtn.style.cursor = 'pointer';
    gridBtn.style.backgroundColor = '#6c757d';
    gridBtn.style.color = '#fff';
    gridBtn.style.border = 'none';
    gridBtn.style.borderRadius = '6px';
    gridBtn.onclick = () => {
        workspace.style.backgroundImage = 'radial-gradient(#adb5bd 1px, transparent 1px)';
        workspace.style.backgroundSize = '20px 20px';
        workspace.style.backgroundPosition = '0 0';
    };
    gridBtn.onmouseenter = () => gridBtn.style.backgroundColor = '#5a6268';
    gridBtn.onmouseleave = () => gridBtn.style.backgroundColor = '#6c757d';
    sidebar.appendChild(gridBtn);

    const clearBtn = document.createElement('button');
    clearBtn.textContent = 'Clear All Elements';
    clearBtn.style.padding = '10px';
    clearBtn.style.width = '100%';
    clearBtn.style.cursor = 'pointer';
    clearBtn.style.backgroundColor = '#dc3545';
    clearBtn.style.color = '#fff';
    clearBtn.style.border = 'none';
    clearBtn.style.borderRadius = '6px';
    clearBtn.onclick = () => {
        workspace.innerHTML = '';
        workspace.appendChild(instructions); 
    };
    clearBtn.onmouseenter = () => clearBtn.style.backgroundColor = '#c82333';
    clearBtn.onmouseleave = () => clearBtn.style.backgroundColor = '#dc3545';
    sidebar.appendChild(clearBtn);

    // Main Workspace Environment setup
    const workspace = document.createElement('div');
    workspace.style.flex = '1';
    workspace.style.position = 'relative';
    workspace.style.overflow = 'hidden';
    workspace.style.backgroundColor = defaultBgColor;
    workspace.style.backgroundImage = 'radial-gradient(#adb5bd 1px, transparent 1px)';
    workspace.style.backgroundSize = '20px 20px';

    const instructions = document.createElement('div');
    instructions.style.position = 'absolute';
    instructions.style.top = '20px';
    instructions.style.left = '50%';
    instructions.style.transform = 'translateX(-50%)';
    instructions.style.backgroundColor = 'rgba(33, 37, 41, 0.8)';
    instructions.style.color = '#fff';
    instructions.style.padding = '10px 20px';
    instructions.style.borderRadius = '30px';
    instructions.style.fontSize = '14px';
    instructions.style.pointerEvents = 'none';
    instructions.style.zIndex = '999';
    instructions.style.fontFamily = 'sans-serif';
    instructions.style.whiteSpace = 'nowrap';
    instructions.innerHTML = '✨ Drag widgets here gracefully. Edit text directly. Move via dragging and resize via bottom-right area. ✨';
    workspace.appendChild(instructions);

    // Global Drag Variables (Kept closely restricted within the module limits)
    let currentDraggingElement = null;
    let dragStartX = 0;
    let dragStartY = 0;
    let dragInitialLeft = 0;
    let dragInitialTop = 0;

    const onGlobalMouseMove = (e) => {
        if (currentDraggingElement) {
            const dx = e.clientX - dragStartX;
            const dy = e.clientY - dragStartY;
            currentDraggingElement.style.left = `${dragInitialLeft + dx}px`;
            currentDraggingElement.style.top = `${dragInitialTop + dy}px`;
        }
    };

    const onGlobalMouseUp = () => {
        if (currentDraggingElement) {
            currentDraggingElement.style.zIndex = ''; 
            currentDraggingElement = null;
            document.body.style.userSelect = '';
            
            document.removeEventListener('mousemove', onGlobalMouseMove);
            document.removeEventListener('mouseup', onGlobalMouseUp);
        }
    };

    // External to Workspace Drop handling
    workspace.addEventListener('dragover', (e) => {
        if (draggedComponent) {
            e.preventDefault(); 
            e.dataTransfer.dropEffect = 'copy';
        }
    });

    workspace.addEventListener('drop', (e) => {
        if (draggedComponent) {
            e.preventDefault();
            e.stopPropagation();

            if (instructions.parentNode) workspace.removeChild(instructions);

            const isResizable = draggedComponent.resize;
            const rect = workspace.getBoundingClientRect();
            let posX = e.clientX - rect.left - 20; 
            let posY = e.clientY - rect.top - 20;

            // Safe positional boundary clamping
            if (posX < 0) posX = 0;
            if (posY < 0) posY = 0;

            const wrapper = document.createElement('div');
            wrapper.style.position = 'absolute';
            wrapper.style.left = `${posX}px`;
            wrapper.style.top = `${posY}px`;
            wrapper.style.width = draggedComponent.width;
            wrapper.style.height = draggedComponent.height;
            wrapper.style.cursor = 'move';
            wrapper.style.boxSizing = 'border-box';
            
            if (isResizable) {
                wrapper.style.resize = 'both';
                wrapper.style.overflow = 'hidden';
            }

            const content = document.createElement('div');
            content.style.width = '100%';
            content.style.height = '100%';
            content.style.pointerEvents = 'auto'; 
            content.style.overflow = 'hidden';
            content.innerHTML = draggedComponent.html;
            wrapper.appendChild(content);

            const closeBtn = document.createElement('div');
            closeBtn.innerHTML = '×';
            closeBtn.style.position = 'absolute';
            closeBtn.style.top = '0px';
            closeBtn.style.right = '0px';
            closeBtn.style.width = '24px';
            closeBtn.style.height = '24px';
            closeBtn.style.backgroundColor = '#dc3545';
            closeBtn.style.color = 'white';
            closeBtn.style.lineHeight = '24px';
            closeBtn.style.textAlign = 'center';
            closeBtn.style.fontSize = '18px';
            closeBtn.style.fontWeight = 'bold';
            closeBtn.style.fontFamily = 'Arial, sans-serif';
            closeBtn.style.cursor = 'pointer';
            closeBtn.style.display = 'none';
            closeBtn.style.zIndex = '1001';
            closeBtn.style.borderBottomLeftRadius = '6px';
            
            wrapper.addEventListener('mouseenter', () => {
                closeBtn.style.display = 'block';
                wrapper.style.outline = '1px dashed #0d6efd';
            });
            
            wrapper.addEventListener('mouseleave', () => {
                closeBtn.style.display = 'none';
                wrapper.style.outline = 'none';
            });

            closeBtn.addEventListener('click', (e) => {
                workspace.removeChild(wrapper);
                e.stopPropagation();
            });

            wrapper.appendChild(closeBtn);

            wrapper.addEventListener('mousedown', (e) => {
                const innerRect = wrapper.getBoundingClientRect();
                
                // Allow native resize handle to absorb input rather than drag mechanism
                const isBottomRight = (e.clientX - innerRect.left) > (innerRect.width - 25) && 
                                      (e.clientY - innerRect.top) > (innerRect.height - 25);
                                      
                if (isBottomRight && isResizable) return;

                // Restrict intercept for forms and contentEditables giving user text control
                if (e.target === closeBtn || e.target.closest('[contenteditable="true"]') || 
                    e.target.tagName === 'INPUT' || e.target.tagName === 'BUTTON') {
                    return;
                }

                currentDraggingElement = wrapper;
                dragStartX = e.clientX;
                dragStartY = e.clientY;
                dragInitialLeft = parseInt(wrapper.style.left, 10) || 0;
                dragInitialTop = parseInt(wrapper.style.top, 10) || 0;
                wrapper.style.zIndex = Math.floor(Date.now() % 1000000); 
                document.body.style.userSelect = 'none'; 
                
                document.addEventListener('mousemove', onGlobalMouseMove);
                document.addEventListener('mouseup', onGlobalMouseUp);
                
                e.stopPropagation();
            });

            workspace.appendChild(wrapper);
        }
        draggedComponent = null;
    });

    container.appendChild(sidebar);
    container.appendChild(workspace);

    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 provides an interactive drag-and-drop interface for designing website layouts. Users can build visual mockups by dragging various UI components—such as navigation bars, buttons, text areas, headings, and input fields—onto a customizable workspace. The tool features a blueprint grid mode for precise alignment and allows users to set an uploaded image as a background to simulate real-world website environments. It is ideal for web designers, developers, or marketers who need to quickly prototype website structures and user interfaces without writing code.

Leave a Reply

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