Please bookmark this page to avoid losing your image tool!

Image Player Search Topic Identifier Picker

(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, topicTitle = "Epic Narrative Climax", currentTime = "1:24", totalTime = "4:56", progress = "30", themeColor = "#FF0000") {
    const canvas = document.createElement('canvas');
    const width = originalImg.width;
    const height = originalImg.height;
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // 1. Draw base image
    ctx.drawImage(originalImg, 0, 0);

    // 2. Responsive UI Scaling
    // Ensures that the UI components scale cleanly regardless of input image resolution
    const scale = Math.max(0.3, Math.min(width, height) / 800);

    // Base structural metrics
    const padX = 25 * scale;
    const barY = height - 30 * scale;
    const barHeight = 6 * scale;
    const barWidth = width - (padX * 2);

    // Calculate progress (scrubber location)
    let prog = parseFloat(progress);
    if (isNaN(prog) || prog < 0) prog = 0;
    if (prog > 100) prog = 100;
    const activeWidth = barWidth * (prog / 100);

    // 3. Draw Dark Gradient bottom shadow (better contrast for UI)
    const shadowH = 200 * scale;
    const grad = ctx.createLinearGradient(0, height - shadowH, 0, height);
    grad.addColorStop(0, 'rgba(0, 0, 0, 0)');
    grad.addColorStop(0.5, 'rgba(0, 0, 0, 0.6)');
    grad.addColorStop(1, 'rgba(0, 0, 0, 0.95)');
    ctx.fillStyle = grad;
    ctx.fillRect(0, height - shadowH, width, shadowH);

    // 4. Center Play Button
    const cx = width / 2;
    const cy = height / 2;
    const radius = 55 * scale;
    
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, Math.PI * 2);
    ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
    ctx.fill();
    ctx.lineWidth = 3 * scale;
    ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)';
    ctx.stroke();

    const pSize = 18 * scale;
    ctx.beginPath();
    ctx.moveTo(cx - pSize * 0.7, cy - pSize);
    ctx.lineTo(cx + pSize * 1.4, cy);
    ctx.lineTo(cx - pSize * 0.7, cy + pSize);
    ctx.closePath();
    ctx.lineJoin = 'round';
    ctx.fillStyle = 'white';
    ctx.fill();

    // 5. Basic Control Texts (Timestamp Display)
    const controlY = height - 55 * scale;
    const fontSize = Math.max(12, Math.round(18 * scale));
    ctx.font = `bold ${fontSize}px "Segoe UI", Roboto, Helvetica, Arial, sans-serif`;
    ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillText(`${currentTime} / ${totalTime}`, padX, controlY);

    // 6. Search Topic Identifier Picker (Tooltip Miniature Thumbnail)
    const maxTipW = 240 * scale;
    const maxTipH = 135 * scale;
    const aspect = width / height;
    
    // Maintain image aspect ratio in tooltip
    let tipW = maxTipW;
    let tipH = tipW / aspect;
    if (tipH > maxTipH) {
        tipH = maxTipH;
        tipW = tipH * aspect;
    }
    
    const tipGap = 20 * scale;
    let tipBaseX = padX + activeWidth;
    let tipRectX = tipBaseX - tipW / 2;
    
    // Clamp Tooltip box to screen edges
    if (tipRectX < padX) tipRectX = padX;
    if (tipRectX + tipW > width - padX) tipRectX = width - padX - tipW;
    const tipRectY = barY - tipGap - tipH;

    // Draw the miniature hover thumbnail with a drop shadow
    ctx.save();
    ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
    ctx.shadowBlur = 20 * scale;
    ctx.shadowOffsetY = 5 * scale;
    ctx.drawImage(originalImg, tipRectX, tipRectY, tipW, tipH);
    ctx.restore(); // reset shadow

    // Picker border highlighting the exact frame selection
    ctx.lineWidth = 3 * scale;
    ctx.strokeStyle = themeColor;
    ctx.strokeRect(tipRectX, tipRectY, tipW, tipH);

    // 7. Topic Title Overlay inside the Picker Thumbnail
    const barLabelH = 32 * scale;
    ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';
    ctx.fillRect(tipRectX, tipRectY + tipH - barLabelH, tipW, barLabelH);
    
    ctx.fillStyle = 'white';
    ctx.font = `bold ${Math.max(10, Math.round(15 * scale))}px Arial, sans-serif`;
    ctx.textAlign = 'center';
    
    // Fill text, clipped to the miniature box width
    ctx.fillText(topicTitle, tipRectX + tipW / 2, tipRectY + tipH - barLabelH / 2, tipW - 16 * scale);

    // Tooltip scrub time floating above the thumbnail
    ctx.fillStyle = 'rgba(0, 0, 0, 0.75)';
    ctx.font = `bold ${Math.max(10, Math.round(14 * scale))}px Arial, sans-serif`;
    const tWidth = ctx.measureText(currentTime).width + 24 * scale;
    const scrubTimeY = tipRectY - 30 * scale;
    const scrubTimeH = 22 * scale;
    ctx.fillRect(tipRectX + tipW / 2 - tWidth / 2, scrubTimeY, tWidth, scrubTimeH);
    
    ctx.fillStyle = 'white';
    ctx.fillText(currentTime, tipRectX + tipW / 2, scrubTimeY + scrubTimeH / 2);

    // 8. Progress Bar Lines
    // Background Line
    ctx.fillStyle = 'rgba(255, 255, 255, 0.25)';
    ctx.fillRect(padX, barY - barHeight / 2, barWidth, barHeight);

    // Simulated buffered line
    ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
    ctx.fillRect(padX, barY - barHeight / 2, barWidth * (Math.min(100, prog + 15) / 100), barHeight);

    // Active Theme Current Time Line
    ctx.fillStyle = themeColor;
    ctx.fillRect(padX, barY - barHeight / 2, activeWidth, barHeight);

    // Chapter Identifiers on the Progress bar (evenly spread marks to signify distinct topics)
    const numChapters = 6;
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    for(let i = 1; i < numChapters; i++) {
        let chX = padX + (barWidth * (i / numChapters));
        ctx.fillRect(chX - 1.5 * scale, barY - barHeight, 3 * scale, barHeight * 2);
    }

    // 9. Identifier Scrub Cursor/Thumb
    ctx.beginPath();
    ctx.arc(tipBaseX, barY, 9 * scale, 0, Math.PI * 2);
    ctx.fillStyle = themeColor;
    ctx.fill();
    ctx.lineWidth = 2 * scale;
    ctx.strokeStyle = 'white';
    ctx.stroke();

    // Context down-chevron mapping the tooltip to the active bar position
    ctx.beginPath();
    ctx.moveTo(tipBaseX - 6 * scale, barY - 14 * scale);
    ctx.lineTo(tipBaseX + 6 * scale, barY - 14 * scale);
    ctx.lineTo(tipBaseX, barY - 7 * scale);
    ctx.closePath();
    ctx.fillStyle = themeColor;
    ctx.fill();

    return canvas;
}

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 users to overlay a stylized video player interface onto a static image. It adds interactive-looking elements such as a playback progress bar, a central play button, timestamps, and a ‘topic identifier’ tooltip that features a miniature thumbnail and a descriptive title. This can be used by content creators and designers to create realistic mockups for video streaming interfaces, presentation slides, or social media assets that simulate a video playback moment.

Leave a Reply

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