Please bookmark this page to avoid losing your image tool!

Image Time Dilation Filter Effect Tool

(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, centerXRatioInput = "0.5", centerYRatioInput = "0.5", strengthInput = "0.5", radiusRatioInput = "0.25") {

    // Parse and validate parameters
    let centerXRatio = parseFloat(centerXRatioInput);
    if (isNaN(centerXRatio)) centerXRatio = 0.5;

    let centerYRatio = parseFloat(centerYRatioInput);
    if (isNaN(centerYRatio)) centerYRatio = 0.5;

    let strength = parseFloat(strengthInput);
    if (isNaN(strength)) strength = 0.5;
    
    let radiusRatio = parseFloat(radiusRatioInput);
    if (isNaN(radiusRatio)) radiusRatio = 0.25;

    // Clamp strength: (1 + strength) must be > 0. Positive for bulge, negative for pinch.
    // Strength > -1 is required for the Math.pow logic.
    if (strength <= -1.0) strength = -0.99; // Max pinch, keeps power > 0
    // Cap bulge strength to a practical maximum if desired, e.g., 5.0
    if (strength > 5.0) strength = 5.0; 

    const canvas = document.createElement('canvas');
    // Use willReadFrequently for potential performance gain when using getImageData repeatedly.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;
    canvas.width = width;
    canvas.height = height;

    ctx.drawImage(originalImg, 0, 0, width, height);
    
    const imageData = ctx.getImageData(0, 0, width, height);
    const outputImageData = ctx.createImageData(width, height);
    const outputData = outputImageData.data;
    
    const actualCenterX = width * centerXRatio;
    const actualCenterY = height * centerYRatio;
    
    // Base radius for the effect, relative to the smaller dimension of the image
    const baseRadius = Math.min(width, height) * radiusRatio;

    // Helper function to get a single pixel's color array [R, G, B, A] from image data
    // Handles boundary clamping.
    function getPixel(sourceImageData, x, y) {
        const ix = Math.max(0, Math.min(sourceImageData.width - 1, Math.floor(x)));
        const iy = Math.max(0, Math.min(sourceImageData.height - 1, Math.floor(y)));
        const k = (iy * sourceImageData.width + ix) * 4;
        return [
            sourceImageData.data[k],
            sourceImageData.data[k + 1],
            sourceImageData.data[k + 2],
            sourceImageData.data[k + 3]
        ];
    }

    // Helper function for bilinear interpolation
    function getPixelBilinear(sourceImageData, x, y) {
        const x_floor = Math.floor(x);
        const y_floor = Math.floor(y);
        const x_frac = x - x_floor;
        const y_frac = y - y_floor;

        const p00 = getPixel(sourceImageData, x_floor, y_floor);
        const p10 = getPixel(sourceImageData, x_floor + 1, y_floor);
        const p01 = getPixel(sourceImageData, x_floor, y_floor + 1);
        const p11 = getPixel(sourceImageData, x_floor + 1, y_floor + 1);

        const interpolatedPixel = [0, 0, 0, 0];
        for (let i = 0; i < 4; i++) { // R, G, B, A channels
            const c0 = p00[i] * (1 - x_frac) + p10[i] * x_frac; // Interpolate top row
            const c1 = p01[i] * (1 - x_frac) + p11[i] * x_frac; // Interpolate bottom row
            interpolatedPixel[i] = Math.round(c0 * (1 - y_frac) + c1 * y_frac); // Interpolate vertically
        }
        return interpolatedPixel;
    }

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const dx = x - actualCenterX;
            const dy = y - actualCenterY;
            const distanceSquared = dx * dx + dy * dy;

            let srcX = x;
            let srcY = y;

            // Apply effect only if baseRadius > 0, strength is non-zero, and pixel is within effect radius
            if (baseRadius > 0 && strength !== 0 && distanceSquared < baseRadius * baseRadius) {
                const distance = Math.sqrt(distanceSquared);

                if (distance > 0) { // Avoid division by zero for center pixel
                    const r_dest_norm = distance / baseRadius; // Normalized distance (0 to 1)
                    
                    // Power for distortion: (1 + strength). strength > 0 means bulge, strength < 0 means pinch.
                    const power_val = 1.0 + strength;
                    
                    const r_src_norm = Math.pow(r_dest_norm, power_val);
                    const new_dist = r_src_norm * baseRadius;
                    
                    // Calculate source coordinates by scaling along the vector from center
                    srcX = actualCenterX + (dx / distance) * new_dist;
                    srcY = actualCenterY + (dy / distance) * new_dist;
                }
                // If distance is 0 (center pixel), srcX/srcY remain x/y, so it maps to itself.
            }
            // If outside effect radius or no effect conditions, srcX/srcY remain x/y (original pixel).

            const [r, g, b, a] = getPixelBilinear(imageData, srcX, srcY);
            const destIndex = (y * width + x) * 4;
            outputData[destIndex]     = r;
            outputData[destIndex + 1] = g;
            outputData[destIndex + 2] = b;
            outputData[destIndex + 3] = a;
        }
    }

    ctx.putImageData(outputImageData, 0, 0);
    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 Time Dilation Filter Effect Tool allows users to apply a unique distortion effect to images, simulating a time dilation visual. Users can customize the effect by selecting the center point, strength, and radius of the distortion. This tool can be particularly useful for artists and designers looking to create visually striking images for digital art, graphics, social media, or any creative project that requires an imaginative twist on traditional photography. Whether you want to bulge or pinch specific areas of an image, this tool provides an easy and effective way to enhance your visual content.

Leave a Reply

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