Please bookmark this page to avoid losing your image tool!

Image Drawing Game Generator

(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, defaultMode = 'trace', gridSize = 0, penColor = '#ff0000', defaultPenSize = 5) {
    // Main container
    const container = document.createElement('div');
    container.style.display = 'flex';
    container.style.flexDirection = 'column';
    container.style.alignItems = 'center';
    container.style.fontFamily = 'Arial, sans-serif';
    container.style.width = '100%';
    
    // Toolbar for game settings
    const toolbar = document.createElement('div');
    toolbar.style.marginBottom = '15px';
    toolbar.style.display = 'flex';
    toolbar.style.flexWrap = 'wrap';
    toolbar.style.gap = '15px';
    toolbar.style.justifyContent = 'center';
    toolbar.style.alignItems = 'center';
    
    const colorLabel = document.createElement('label');
    colorLabel.innerText = 'Color: ';
    colorLabel.style.display = 'flex';
    colorLabel.style.alignItems = 'center';
    const colorPicker = document.createElement('input');
    colorPicker.type = 'color';
    colorPicker.value = penColor;
    colorPicker.style.marginLeft = '5px';
    colorPicker.style.cursor = 'pointer';
    colorLabel.appendChild(colorPicker);
    
    const sizeLabel = document.createElement('label');
    sizeLabel.innerText = 'Thickness: ';
    sizeLabel.style.display = 'flex';
    sizeLabel.style.alignItems = 'center';
    const penSize = document.createElement('input');
    penSize.type = 'range';
    penSize.min = '1';
    penSize.max = '50';
    penSize.value = defaultPenSize.toString();
    penSize.style.marginLeft = '5px';
    penSize.style.cursor = 'pointer';
    sizeLabel.appendChild(penSize);
    
    const btnStyle = "padding: 6px 15px; border: 1px solid #aaa; border-radius: 4px; background: #f0f0f0; cursor: pointer; font-size: 14px; transition: background 0.2s;";
    
    const toggleBgBtn = document.createElement('button');
    toggleBgBtn.innerText = 'Toggle Image';
    toggleBgBtn.style.cssText = btnStyle;
    
    const toggleGridBtn = document.createElement('button');
    toggleGridBtn.innerText = 'Toggle Grid';
    toggleGridBtn.style.cssText = btnStyle;
    
    const clearBtn = document.createElement('button');
    clearBtn.innerText = 'Clear Drawing';
    clearBtn.style.cssText = btnStyle;
    
    toolbar.appendChild(colorLabel);
    toolbar.appendChild(sizeLabel);
    toolbar.appendChild(toggleBgBtn);
    toolbar.appendChild(toggleGridBtn);
    toolbar.appendChild(clearBtn);
    container.appendChild(toolbar);
    
    // Wrapper for both layered canvases
    const canvasContainer = document.createElement('div');
    canvasContainer.style.position = 'relative';
    canvasContainer.style.width = '100%';
    canvasContainer.style.maxWidth = originalImg.width + 'px';
    canvasContainer.style.display = 'inline-block';
    canvasContainer.style.border = '1px solid #ccc';
    canvasContainer.style.boxSizing = 'border-box';
    canvasContainer.style.backgroundColor = '#ffffff';
    
    // Background Canvas (for Image and Grid)
    const bgCanvas = document.createElement('canvas');
    bgCanvas.width = originalImg.width;
    bgCanvas.height = originalImg.height;
    bgCanvas.style.width = '100%';
    bgCanvas.style.height = '100%';
    bgCanvas.style.position = 'absolute';
    bgCanvas.style.top = '0';
    bgCanvas.style.left = '0';
    bgCanvas.style.pointerEvents = 'none'; // So drawing events pass to the interactive canvas below
    
    const bgCtx = bgCanvas.getContext('2d');
    
    function drawBackground(showImage, showGrid) {
        bgCtx.clearRect(0, 0, bgCanvas.width, bgCanvas.height);
        
        if (showImage) {
            bgCtx.globalAlpha = 0.35; // Faint background for tracing
            bgCtx.drawImage(originalImg, 0, 0);
            bgCtx.globalAlpha = 1.0;
        }
        
        if (showGrid) {
            // Calculate an even grid size relative to the canvas if none was explicitly configured
            let parsedGridSize = parseInt(gridSize, 10);
            const size = parsedGridSize > 0 ? parsedGridSize : Math.max(20, Math.floor(Math.min(bgCanvas.width, bgCanvas.height) / 10));
            
            bgCtx.beginPath();
            for (let x = 0; x <= bgCanvas.width; x += size) {
                bgCtx.moveTo(x, 0);
                bgCtx.lineTo(x, bgCanvas.height);
            }
            for (let y = 0; y <= bgCanvas.height; y += size) {
                bgCtx.moveTo(0, y);
                bgCtx.lineTo(bgCanvas.width, y);
            }
            bgCtx.strokeStyle = 'rgba(0, 0, 0, 0.4)';
            bgCtx.lineWidth = 1;
            bgCtx.stroke();
            
            // Helpful coordinates for "Draw by grid" mode
            bgCtx.fillStyle = 'rgba(0, 0, 0, 0.6)';
            bgCtx.font = '12px Arial';
            for (let x = 0; x < bgCanvas.width; x += size) {
                for (let y = 0; y < bgCanvas.height; y += size) {
                    bgCtx.fillText(`${x/size},${y/size}`, x + 3, y + 13);
                }
            }
        }
    }
    
    let isImageVisible = true;
    let isGridVisible = defaultMode === 'grid';
    drawBackground(isImageVisible, isGridVisible);
    
    // Interactive Foreground Canvas
    const drawCanvas = document.createElement('canvas');
    drawCanvas.width = originalImg.width;
    drawCanvas.height = originalImg.height;
    drawCanvas.style.width = '100%';
    drawCanvas.style.height = 'auto'; // Scales relative to wrapper dynamically
    drawCanvas.style.display = 'block';
    drawCanvas.style.cursor = 'crosshair';
    drawCanvas.style.touchAction = 'none'; // Prevent swiping-to-scroll to allow clean drawing
    
    const drawCtx = drawCanvas.getContext('2d');
    drawCtx.lineCap = 'round';
    drawCtx.lineJoin = 'round';
    
    canvasContainer.appendChild(bgCanvas);
    canvasContainer.appendChild(drawCanvas);
    container.appendChild(canvasContainer);
    
    // Core drawing logic
    let isDrawing = false;
    let lastX = 0;
    let lastY = 0;
    
    function getMousePos(e) {
        const rect = drawCanvas.getBoundingClientRect();
        const scaleX = drawCanvas.width / rect.width;
        const scaleY = drawCanvas.height / rect.height;
        
        let clientX = e.clientX;
        let clientY = e.clientY;
        
        if (e.touches && e.touches.length > 0) {
            clientX = e.touches[0].clientX;
            clientY = e.touches[0].clientY;
        }
        
        return {
            x: (clientX - rect.left) * scaleX,
            y: (clientY - rect.top) * scaleY
        };
    }
    
    function startDrawing(e) {
        e.preventDefault();
        isDrawing = true;
        const pos = getMousePos(e);
        lastX = pos.x;
        lastY = pos.y;
    }
    
    function draw(e) {
        if (!isDrawing) return;
        e.preventDefault();
        const pos = getMousePos(e);
        
        drawCtx.strokeStyle = colorPicker.value;
        drawCtx.lineWidth = parseInt(penSize.value, 10);
        
        drawCtx.beginPath();
        drawCtx.moveTo(lastX, lastY);
        drawCtx.lineTo(pos.x, pos.y);
        drawCtx.stroke();
        
        lastX = pos.x;
        lastY = pos.y;
    }
    
    function stopDrawing(e) {
        if (e) e.preventDefault();
        isDrawing = false;
    }
    
    // Events mapping
    drawCanvas.addEventListener('mousedown', startDrawing);
    drawCanvas.addEventListener('mousemove', draw);
    drawCanvas.addEventListener('mouseup', stopDrawing);
    drawCanvas.addEventListener('mouseout', stopDrawing);
    
    drawCanvas.addEventListener('touchstart', startDrawing, { passive: false });
    drawCanvas.addEventListener('touchmove', draw, { passive: false });
    drawCanvas.addEventListener('touchend', stopDrawing, { passive: false });
    drawCanvas.addEventListener('touchcancel', stopDrawing, { passive: false });
    
    toggleBgBtn.addEventListener('click', () => {
        isImageVisible = !isImageVisible;
        drawBackground(isImageVisible, isGridVisible);
    });
    
    toggleGridBtn.addEventListener('click', () => {
        isGridVisible = !isGridVisible;
        drawBackground(isImageVisible, isGridVisible);
    });
    
    clearBtn.addEventListener('click', () => {
        drawCtx.clearRect(0, 0, drawCanvas.width, drawCanvas.height);
    });
    
    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

The Image Drawing Game Generator is an interactive tool designed to transform any uploaded image into a customizable drawing activity. It allows users to practice tracing or grid-based drawing by providing a transparent overlay of the original image and a coordinate grid. Users can customize their drawing experience with various pen colors, adjustable line thicknesses, and the ability to toggle the background image or grid on and off. This tool is ideal for educational settings, art practice, or creating engaging digital activities for children to improve fine motor skills and spatial awareness.

Leave a Reply

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

Other Image Tools:

No valid description provided for an image utility tool

Unrecognized Description

Image Search Tool for Cookies Cartoons and Medicinal Mud

Image Text Label Adder

Image Bouquet and Calm Theme Creator

Image From Text Prompt Generator

Image Gingerbread/Wish/Spoon Sticker Adder

Big Hero 6 The Series AU Image Replacer

Image Big Hero 6 To Big Hero 6 The Series AU Replacer

Audio and Video Big Hero 6 Series Alternate Universe Replacement Tool

Big Hero 6 The Series Alternate Universe Audio and Video Replacer Tool

Audio and Video Big Hero 6 Alternate Universe Replacement Tool

Ice Age 2002 Nogai Dub Cast Information Tool

Audio File of Universal Pictures David Newman Fanfare

Audio to Image Fanfare Generator

Audio File Not Supported

Universal Pictures David Newman Fanfare Image

The Walt Disney Company Sound Effects Library

Photo I Killed X Losky Effect Applicator

Image I Killed X Losky Effect Hue Tool

Image Hue Adjustment Tool for I Killed Losky Effect

I Killed Losky Image Effect Generator

Big Hero 6 To Big Hero 6 The Series AU Image Replacer

Big Hero 6 The Series AU Image Generator

Website Favicon and Logo PNG Generator Tool

Image PNG Logo Studio And Website Icon Text Finder

Website Icon and Logo Image Studio Maker

Image To Gold Effect Filter

Roblox Army RP Document Image ID Finder

Game Image ID Finder

Image To Paint By Number Converter

Image To Website Interface Finder

Image To Movie Description Text Generator

Movie Scene Text Extractor from Image

Image Based Movie Identifier From Text Picker

Image To Movie Search Tool

See All →