Please bookmark this page to avoid losing your image tool!

Image Infinite Mirror Filter

(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, iterations = 10, scale = 0.75, centerX = 0.5, centerY = 0.5) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Use naturalWidth/Height for the intrinsic dimensions of the image
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    // Handle cases where the image might not be loaded or has no dimensions
    if (imgWidth === 0 || imgHeight === 0) {
        console.error("Image has zero dimensions. Ensure it is loaded before processing.");
        // Return a minimal canvas to avoid further errors downstream
        canvas.width = 1;
        canvas.height = 1;
        ctx.fillStyle = 'red'; // Indicate error
        ctx.fillRect(0, 0, 1, 1);
        return canvas;
    }

    canvas.width = imgWidth;
    canvas.height = imgHeight;

    // Validate and normalize parameters
    // Parameters from function arguments can be strings if passed from HTML attributes etc.
    let numIterations = Number(iterations);
    let numScale = Number(scale);
    let numCenterX = Number(centerX);
    let numCenterY = Number(centerY);

    // Iterations should be at least 1 to draw the base image
    if (isNaN(numIterations) || numIterations < 1) {
        numIterations = 10; // Default iterations
    }

    // Scale factor must be between 0 (exclusive) and 1 (exclusive) for a shrinking effect
    // scale = 1 would redraw in the same spot; scale > 1 would enlarge.
    if (isNaN(numScale) || numScale <= 0 || numScale >= 1) {
        numScale = 0.75; // Default scale
    }

    // Center X and Y should be within the 0.0 to 1.0 range (normalized coordinates)
    if (isNaN(numCenterX) || numCenterX < 0 || numCenterX > 1) {
        numCenterX = 0.5; // Default centerX
    }
    if (isNaN(numCenterY) || numCenterY < 0 || numCenterY > 1) {
        numCenterY = 0.5; // Default centerY
    }

    // Initialize the first frame to be the full canvas
    let currentFrameX = 0;
    let currentFrameY = 0;
    let currentFrameWidth = canvas.width;
    let currentFrameHeight = canvas.height;

    // Loop to draw the image multiple times, each smaller than the last.
    // The largest image (the first iteration) is drawn first, then subsequent
    // smaller images are drawn on top, creating the "infinite mirror" effect.
    for (let i = 0; i < numIterations; i++) {
        // Stop if the frame becomes too small to be practically visible or draw
        if (currentFrameWidth < 0.5 || currentFrameHeight < 0.5) {
            break;
        }

        // Draw the original image, scaled to fit the current frame
        ctx.drawImage(originalImg, currentFrameX, currentFrameY, currentFrameWidth, currentFrameHeight);

        // Calculate the dimensions of the next, smaller frame
        const nextFrameWidth = currentFrameWidth * numScale;
        const nextFrameHeight = currentFrameHeight * numScale;

        // Calculate the top-left position (X, Y) of the next frame.
        // This ensures that the focal point (numCenterX, numCenterY) within the
        // current frame aligns with the same focal point within the next frame.
        //
        // The focal point in the current frame is at:
        // focusPxX = currentFrameX + numCenterX * currentFrameWidth
        // focusPxY = currentFrameY + numCenterY * currentFrameHeight
        //
        // The new frame's origin (currentFrameX_new, currentFrameY_new) should be such that:
        // focusPxX = currentFrameX_new + numCenterX * nextFrameWidth
        // focusPxY = currentFrameY_new + numCenterY * nextFrameHeight
        //
        // Solving for currentFrameX_new and currentFrameY_new:
        // currentFrameX_new = currentFrameX + numCenterX * currentFrameWidth - numCenterX * nextFrameWidth
        //                   = currentFrameX + numCenterX * (currentFrameWidth - nextFrameWidth)
        // currentFrameY_new = currentFrameY + numCenterY * currentFrameHeight - numCenterY * nextFrameHeight
        //                   = currentFrameY + numCenterY * (currentFrameHeight - nextFrameHeight)

        currentFrameX += numCenterX * (currentFrameWidth - nextFrameWidth);
        currentFrameY += numCenterY * (currentFrameHeight - nextFrameHeight);
        
        currentFrameWidth = nextFrameWidth;
        currentFrameHeight = nextFrameHeight;
    }

    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 Infinite Mirror Filter tool creates a visually captivating effect by rendering an image in a series of progressively smaller iterations, producing an infinite mirror illusion. Users can customize the number of iterations, scale, and centering of the effect to achieve different artistic outcomes. This tool is suitable for graphic designers, artists, or anyone looking to enhance their images with unique visual effects for presentations, social media posts, or creative projects.

Leave a Reply

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