Please bookmark this page to avoid losing your image tool!

Mystery Disappearance Photo Editor

(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, direction = 'right', intensity = 50, blockSize = 4, tintColor = '100,200,255') {
    // Parameter validation and parsing
    direction = String(direction).toLowerCase();
    if (!['right', 'left', 'top', 'bottom'].includes(direction)) direction = 'right';
    intensity = Math.max(0, Math.min(100, Number(intensity) || 50));
    blockSize = Math.max(1, Number(blockSize) || 4);

    let [tR, tG, tB] = String(tintColor).split(',').map(n => Number(n) || 0);

    const canvas = document.createElement('canvas');
    const w = originalImg.width;
    const h = originalImg.height;
    canvas.width = w;
    canvas.height = h;
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Draw the original image to extract its pixel data
    ctx.drawImage(originalImg, 0, 0);
    const srcData = ctx.getImageData(0, 0, w, h);
    const s = srcData.data;

    // Create an empty, transparent ImageData for the output
    const outData = ctx.createImageData(w, h);
    const d = outData.data;

    // The sweep variable controls the progression of the "disappearance"
    // intensity 0: sweep = 1.2 (fully visible)
    // intensity 100: sweep = -0.2 (fully disappeared)
    const sweep = 1.2 - (intensity / 100) * 1.4;

    // Set wind vectors based on the selected direction
    let windX = 0, windY = 0, perpX = 0, perpY = 0;
    if (direction === 'right') { windX = 1; perpY = 1; }
    else if (direction === 'left') { windX = -1; perpY = 1; }
    else if (direction === 'bottom') { windY = 1; perpX = 1; }
    else if (direction === 'top') { windY = -1; perpX = 1; }

    // Loop through the image in chunks (particles)
    for (let y = 0; y < h; y += blockSize) {
        for (let x = 0; x < w; x += blockSize) {
            
            // Normalized position and a subtle sine wave distortion for organic edge
            let p = 0;
            let waveOffset = 0;

            if (direction === 'right') {
                p = x / w;
                waveOffset = Math.sin((y / h) * 30) * 0.05 + Math.sin((y / h) * 13) * 0.05;
            } else if (direction === 'left') {
                p = 1 - (x / w);
                waveOffset = Math.sin((y / h) * 30) * 0.05 + Math.sin((y / h) * 13) * 0.05;
            } else if (direction === 'bottom') {
                p = y / h;
                waveOffset = Math.sin((x / w) * 30) * 0.05 + Math.sin((x / w) * 13) * 0.05;
            } else if (direction === 'top') {
                p = 1 - (y / h);
                waveOffset = Math.sin((x / w) * 30) * 0.05 + Math.sin((x / w) * 13) * 0.05;
            }

            p += waveOffset;
            
            // Determine how far this block is into the "gone" sector
            let diff = p - sweep;
            let tStart = -0.15;
            let tEnd = 0.15;
            let probGone = (diff - tStart) / (tEnd - tStart);

            // Clamp probability map
            if (probGone < 0) probGone = 0;
            if (probGone > 1) probGone = 1;

            if (probGone >= 1) continue; // Completely evaporated chunk
            if (probGone > 0 && Math.random() < probGone) continue; // Destroyed chunk

            let displacement = 0;
            let drift = 0;
            let alphaMult = 1.0;
            
            // Maximum 60% mysterious glow tint added to the particles as they disappear
            let tintAmount = probGone * 0.6; 

            if (probGone > 0) {
                // Determine wind scatter effects for the remaining chunk
                let windFactor = Math.pow(probGone, 0.8);
                displacement = Math.random() * (Math.max(w, h) * 0.2) * windFactor;
                drift = (Math.random() - 0.5) * (Math.max(w, h) * 0.05) * windFactor;
                alphaMult = 1.0 - probGone;
            }

            // Target destination
            let tx = Math.floor(x + windX * displacement + perpX * drift);
            let ty = Math.floor(y + windY * displacement + perpY * drift);

            // Blit the block to the output buffer
            for (let by = 0; by < blockSize; by++) {
                for (let bx = 0; bx < blockSize; bx++) {
                    let sx = x + bx;
                    let sy = y + by;
                    let dx = tx + bx;
                    let dy = ty + by;

                    // Bounds check
                    if (sx < w && sy < h && dx >= 0 && dx < w && dy >= 0 && dy < h) {
                        let sIdx = (sy * w + sx) * 4;
                        let dIdx = (dy * w + dx) * 4;

                        let R = s[sIdx];
                        let G = s[sIdx + 1];
                        let B = s[sIdx + 2];
                        let A = s[sIdx + 3];
                        
                        if (A === 0) continue; // Ignore transparent sources

                        // Apply ghost/mysterious tint
                        if (tintAmount > 0) {
                            R = R * (1 - tintAmount) + tR * tintAmount;
                            G = G * (1 - tintAmount) + tG * tintAmount;
                            B = B * (1 - tintAmount) + tB * tintAmount;
                        }

                        let dIdx3 = d[dIdx + 3];
                        // If spot falls on an empty pixel, write directly
                        if (dIdx3 === 0) {
                            d[dIdx]     = R;
                            d[dIdx + 1] = G;
                            d[dIdx + 2] = B;
                            d[dIdx + 3] = A * alphaMult;
                        } else {
                            // Otherwise compute standard Alpha Composition
                            let sA = (A * alphaMult) / 255;
                            let dA = dIdx3 / 255;
                            let outA = sA + dA * (1 - sA);
                            if (outA > 0) {
                                d[dIdx]     = (R * sA + d[dIdx] * dA * (1 - sA)) / outA;
                                d[dIdx + 1] = (G * sA + d[dIdx + 1] * dA * (1 - sA)) / outA;
                                d[dIdx + 2] = (B * sA + d[dIdx + 2] * dA * (1 - sA)) / outA;
                                d[dIdx + 3] = outA * 255;
                            }
                        }
                    }
                }
            }
        }
    }

    ctx.putImageData(outData, 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 Mystery Disappearance Photo Editor is an image manipulation tool designed to create a dramatic ‘evaporation’ or ‘vanishing’ effect. It breaks an image into small blocks and applies a directional sweep—such as top, bottom, left, or right—to make parts of the image appear to scatter and disappear. Users can customize the intensity of the effect, the size of the disappearing blocks, and add a colored mysterious tint to the particles as they fade away. This tool is ideal for creating artistic social media graphics, dramatic visual storytelling for concept art, or unique transitions for digital content.

Leave a Reply

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