Please bookmark this page to avoid losing your image tool!

Image Theater Seating Filter Effect

(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, seatColor = 'rgba(20,20,20,0.8)', numRows = 7, initialSeatHeightRatio = 0.3, perspectiveFactor = 0.85, seatsPerRow = 5, seatHorizontalFillRatio = 0.8, headrestCurvatureRatio = 0.4, rowVerticalSpacingRatio = 0.15) {
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    const ctx = canvas.getContext('2d');

    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, originalImg.width, originalImg.height);

    // Validate and normalize parameters
    numRows = Number(numRows);
    initialSeatHeightRatio = Number(initialSeatHeightRatio);
    perspectiveFactor = Number(perspectiveFactor); // e.g., 0.85 means each row is 85% height of previous
    seatsPerRow = Math.max(1, Number(seatsPerRow)); // Must have at least one seat
    seatHorizontalFillRatio = Math.max(0.01, Math.min(1, Number(seatHorizontalFillRatio))); // Range [0.01, 1]
    headrestCurvatureRatio = Math.max(0, Math.min(1, Number(headrestCurvatureRatio))); // Range [0, 1]
    rowVerticalSpacingRatio = Number(rowVerticalSpacingRatio); // Typically positive

    ctx.fillStyle = seatColor;

    const imgH = canvas.height;
    const imgW = canvas.width;

    // Initialize variables for the first (frontmost) row of seats
    let currentSeatH = imgH * initialSeatHeightRatio;
    let currentSeatBottomY = imgH; // Y-coordinate for the bottom edge of seats in the current row

    for (let row = 0; row < numRows; row++) {
        // Stop if seats become too small or are completely off-screen (above canvas)
        if (currentSeatH < 1) {
            break;
        }
        if (currentSeatBottomY < 0) { // If the bottom of the seat row is above the canvas view
            break;
        }

        const seatTopY = currentSeatBottomY - currentSeatH;
        
        // Calculate width properties for seats in this row
        // unitWidth is the total horizontal space allocated for one seat plus its surrounding gaps
        const unitWidth = imgW / seatsPerRow;
        // actualSeatWidth is the visible width of the seat polygon
        const actualSeatWidth = unitWidth * seatHorizontalFillRatio;
        // gapWidthTotal is the sum of gaps around one seat within its unitWidth
        const gapWidthTotal = unitWidth - actualSeatWidth; // This gap is split on both sides of the seat

        for (let s = 0; s < seatsPerRow; s++) {
            // Calculate the starting X-coordinate for the current seat
            // This distributes the gap equally on the left and right of the seat within its allocated unitWidth
            const seatStartX = s * unitWidth + gapWidthTotal / 2;

            // Calculate dimensions for the seat parts (rectangular base and curved headrest)
            const headrestH = currentSeatH * headrestCurvatureRatio;
            const rectPartH = currentSeatH * (1 - headrestCurvatureRatio);
            
            // Y-coordinate for the top of the rectangular part, which is also the base of the semi-ellipse headrest
            const rectY = seatTopY + headrestH; 

            // Draw the rectangular part of the seat
            if (rectPartH > 0.5) { // Only draw if it has a visible height
                ctx.fillRect(seatStartX, rectY, actualSeatWidth, rectPartH);
            }

            // Draw the curved headrest part (as a semi-ellipse)
            if (headrestH > 0.5 && actualSeatWidth > 0.5) { // Only draw if it has visible dimensions
                const ellipseCenterX = seatStartX + actualSeatWidth / 2;
                const ellipseCenterY = rectY; // The center of the generating ellipse is on the join line
                const radiusX = actualSeatWidth / 2;
                const radiusY = headrestH;
                
                ctx.beginPath();
                // Draws the top half of an ellipse (like a hill, with its flat base at ellipseCenterY)
                // Angles: Math.PI (left) to 0 (right), clockwise direction
                ctx.ellipse(ellipseCenterX, ellipseCenterY, radiusX, radiusY, 0, Math.PI, 0, false); 
                ctx.fill();
            }
        }

        // Update variables for the next row (further back, so higher up and smaller)
        const spacingToNextRow = currentSeatH * rowVerticalSpacingRatio;
        currentSeatBottomY = seatTopY - spacingToNextRow; // Move up for the next row's bottom
        currentSeatH *= perspectiveFactor; // Apply perspective shrinkage to seat height
    }

    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 Theater Seating Filter Effect tool allows users to apply a creative filter to their images, simulating a theater seating arrangement. Users can customize the appearance of the seats, including their color, number of rows, and dimensions, creating a visually engaging image that can be used for various purposes such as promotional materials for events, movie nights, or artistic projects. This tool leverages a perspective effect to enhance the depth of the seating, making it suitable for enhancing photographs, theater designs, or any image that could benefit from a unique layout.

Leave a Reply

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