Please bookmark this page to avoid losing your image tool!

Image Tennis Round Visualizer

(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.
async function processImage(originalImg, playerNames = "Player 1,Player 2,Player 3,Player 4,Player 5", backgroundColor = "#1a1a1a", lineColor = "#ffffff", textColor = "#ffffff", font = "18px Arial", centralImageScale = 0.6, playerCircleSize = 35, circleRadius = 280) {

    const players = playerNames.split(',').map(name => name.trim()).filter(name => name);
    if (players.length === 0) {
        players.push("No Players");
    }
    const numPlayers = players.length;

    // Calculate canvas size based on radius and padding
    const padding = playerCircleSize + 80; // Extra space for names and aesthetics
    const canvasSize = (circleRadius + padding) * 2;
    const canvas = document.createElement('canvas');
    canvas.width = canvasSize;
    canvas.height = canvasSize;
    const ctx = canvas.getContext('2d');
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;

    // --- 1. Draw Background ---
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // --- 2. Draw Central Image ---
    const maxImgSize = circleRadius * 2 * centralImageScale;
    let imgWidth = originalImg.width;
    let imgHeight = originalImg.height;

    // Scale image to fit within the designated central area
    if (imgWidth > maxImgSize || imgHeight > maxImgSize) {
        const ratio = Math.min(maxImgSize / imgWidth, maxImgSize / imgHeight);
        imgWidth *= ratio;
        imgHeight *= ratio;
    }
    ctx.drawImage(originalImg, centerX - imgWidth / 2, centerY - imgHeight / 2, imgWidth, imgHeight);

    // --- 3. Calculate Player Positions ---
    const playerPositions = [];
    const angleStep = (2 * Math.PI) / numPlayers;
    const startAngle = -Math.PI / 2; // Start at the 12 o'clock position

    for (let i = 0; i < numPlayers; i++) {
        const angle = startAngle + i * angleStep;
        const x = centerX + circleRadius * Math.cos(angle);
        const y = centerY + circleRadius * Math.sin(angle);
        playerPositions.push({
            x,
            y,
            name: players[i]
        });
    }

    // --- 4. Draw Connecting Lines with Arrows ---
    const drawArrow = (fromX, fromY, toX, toY, headLength) => {
        const dx = toX - fromX;
        const dy = toY - fromY;
        const angle = Math.atan2(dy, dx);
        const distance = Math.sqrt(dx * dx + dy * dy);

        // Shorten the line so it ends at the circle's edge, not its center
        const endX = toX - playerCircleSize * Math.cos(angle);
        const endY = toY - playerCircleSize * Math.sin(angle);

        ctx.beginPath();
        ctx.moveTo(fromX, fromY);
        ctx.lineTo(endX, endY);
        
        // Draw the arrowhead
        ctx.moveTo(endX, endY);
        ctx.lineTo(endX - headLength * Math.cos(angle - Math.PI / 6), endY - headLength * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(endX, endY);
        ctx.lineTo(endX - headLength * Math.cos(angle + Math.PI / 6), endY - headLength * Math.sin(angle + Math.PI / 6));
        
        ctx.stroke();
    };
    
    if (numPlayers > 1) {
        ctx.strokeStyle = lineColor;
        ctx.lineWidth = 2;
        for (let i = 0; i < numPlayers; i++) {
            const p1 = playerPositions[i];
            const p2 = playerPositions[(i + 1) % numPlayers];
            drawArrow(p1.x, p1.y, p2.x, p2.y, 15);
        }
    }

    // --- 5. Draw Player Circles and Names ---
    ctx.font = font;
    playerPositions.forEach(player => {
        // Draw player circle marker
        ctx.fillStyle = backgroundColor;
        ctx.strokeStyle = lineColor;
        ctx.lineWidth = 3;
        ctx.beginPath();
        ctx.arc(player.x, player.y, playerCircleSize, 0, 2 * Math.PI);
        ctx.fill();
        ctx.stroke();

        // Draw Player Name with smart text alignment
        ctx.fillStyle = textColor;
        ctx.lineWidth = 1;
        const textOffset = playerCircleSize + 12;
        const xAlignmentThreshold = 20;

        if (player.x > centerX + xAlignmentThreshold) { // Right side
            ctx.textAlign = 'left';
            ctx.textBaseline = 'middle';
            ctx.fillText(player.name, player.x + textOffset, player.y);
        } else if (player.x < centerX - xAlignmentThreshold) { // Left side
            ctx.textAlign = 'right';
            ctx.textBaseline = 'middle';
            ctx.fillText(player.name, player.x - textOffset, player.y);
        } else { // Top or Bottom
            ctx.textAlign = 'center';
            if (player.y < centerY) { // Top
                ctx.textBaseline = 'bottom';
                ctx.fillText(player.name, player.x, player.y - textOffset);
            } else { // Bottom
                ctx.textBaseline = 'top';
                ctx.fillText(player.name, player.x, player.y + textOffset);
            }
        }
    });

    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

The Image Tennis Round Visualizer is a tool designed to create a dynamic visual representation centered around a given image, with player names positioned in a circular layout. This tool can be utilized for various applications such as visualizing player matchups in a tennis tournament, creating engaging graphics for sports events, or enhancing presentations during athlete showcases. Users can customize aspects such as background colors, text styles, and the arrangement of player circles, making it suitable for both casual and professional contexts.

Leave a Reply

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