Please bookmark this page to avoid losing your image tool!

Image Plasma Ball 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, plasmaScale = 0.05, timeOffset = 1.0, ballRadius = 0.4, ballCenterX = 0.5, ballCenterY = 0.5, intensity = 0.7, color1Str = "255,0,255", color2Str = "0,255,255", color3Str = "255,255,0", blendMode = "overlay") {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); // Optimization hint for frequent getImageData
    
    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;
    canvas.width = width;
    canvas.height = height;

    if (width === 0 || height === 0) {
        // Return an empty canvas if image dimensions are zero
        return canvas;
    }

    ctx.drawImage(originalImg, 0, 0, width, height);
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, width, height);
    } catch (e) {
        console.error("Error getting image data: ", e);
        // This can happen due to a tainted canvas (cross-origin image without CORS)
        // Fallback: return the canvas with the original image drawn (without the effect).
        return canvas; 
    }
    
    const data = imageData.data;

    // Helper to parse and validate color strings (e.g., "255,0,128")
    const parseColor = (str) => {
        const arr = str.split(',').map(val => parseFloat(val.trim())); // Use parseFloat for robustness
        return [
            Math.max(0, Math.min(255, arr[0] || 0)), // Default to 0 if NaN, clamp to 0-255
            Math.max(0, Math.min(255, arr[1] || 0)),
            Math.max(0, Math.min(255, arr[2] || 0))
        ];
    };
    const c1 = parseColor(color1Str); // First plasma color
    const c2 = parseColor(color2Str); // Second plasma color
    const c3 = parseColor(color3Str); // Third plasma color

    // Ball effect parameters
    const ballEffectCenterX = ballCenterX * width;
    const ballEffectCenterY = ballCenterY * height;
    // Calculate actual radius: ballRadius is a factor of the smaller image dimension
    const effectRadius = ballRadius > 0 ? ballRadius * Math.min(width, height) : 0;

    // Plasma function component parameters
    const freqFactor1 = 1.0, freqFactor2 = 1.0, freqFactor3 = 0.5, freqFactor4 = 1.0;
    const timeMod1 = 1.0, timeMod2 = 1.5, timeMod3 = 2.0, timeMod4 = 2.5;

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const idx = (y * width + x) * 4;
            const origR_norm = data[idx] / 255;
            const origG_norm = data[idx + 1] / 255;
            const origB_norm = data[idx + 2] / 255;

            // 1. Calculate plasma value (normalized to 0-1)
            const scaledX = x * plasmaScale;
            const scaledY = y * plasmaScale;
            const scaledCenterX = (x - width / 2) * plasmaScale;
            const scaledCenterY = (y - height / 2) * plasmaScale;

            const tOff1 = timeOffset * timeMod1;
            const tOff2 = timeOffset * timeMod2;
            const tOff3 = timeOffset * timeMod3;
            const tOff4 = timeOffset * timeMod4;

            const pVal1 = Math.sin(scaledX * freqFactor1 + tOff1);
            const pVal2 = Math.sin(scaledY * freqFactor2 + tOff2);
            const pVal3 = Math.sin((scaledX * freqFactor3 + scaledY * freqFactor3) + tOff3); // Diagonal waves
            const pVal4 = Math.sin(Math.sqrt(scaledCenterX * scaledCenterX + scaledCenterY * scaledCenterY) * freqFactor4 + tOff4); // Radial waves from image center

            // Sum of 4 sine waves is in range [-4, 4]. Normalize to [0, 1].
            let plasmaValue = (pVal1 + pVal2 + pVal3 + pVal4 + 4) / 8;
            
            // 2. Determine plasma color based on plasmaValue (colors normalized 0-1)
            let plasmaR_norm, plasmaG_norm, plasmaB_norm;
            if (plasmaValue < 0.5) {
                const t = plasmaValue * 2; // Interpolation factor for c1 to c2
                plasmaR_norm = (c1[0] * (1 - t) + c2[0] * t) / 255;
                plasmaG_norm = (c1[1] * (1 - t) + c2[1] * t) / 255;
                plasmaB_norm = (c1[2] * (1 - t) + c2[2] * t) / 255;
            } else {
                const t = (plasmaValue - 0.5) * 2; // Interpolation factor for c2 to c3
                plasmaR_norm = (c2[0] * (1 - t) + c3[0] * t) / 255;
                plasmaG_norm = (c2[1] * (1 - t) + c3[1] * t) / 255;
                plasmaB_norm = (c2[2] * (1 - t) + c3[2] * t) / 255;
            }

            // 3. Calculate "ball" mask alpha (0-1)
            let ballMaskAlpha;
            if (ballRadius <= 0 || effectRadius <= 0) { // Apply effect to the whole image if radius is zero/negative
                ballMaskAlpha = 1.0;
            } else {
                const distToBallEffectCenter = Math.sqrt(Math.pow(x - ballEffectCenterX, 2) + Math.pow(y - ballEffectCenterY, 2));
                ballMaskAlpha = 1.0 - Math.min(1.0, distToBallEffectCenter / effectRadius);
                ballMaskAlpha = Math.pow(ballMaskAlpha, 1.5); // Adjust falloff curve (1.0 linear, >1.0 sharper center)
            }
            
            // 4. Calculate effective intensity for blending (0-1)
            const effectiveIntensity = Math.max(0, Math.min(1, intensity * ballMaskAlpha));

            // 5. Blend plasma color with original pixel color
            const blendFunctions = {
                screen:   (b, l) => 1 - (1 - b) * (1 - l),
                multiply: (b, l) => b * l,
                additive: (b, l) => Math.min(1, b + l),
                overlay:  (b, l) => b <= 0.5 ? (2 * b * l) : (1 - 2 * (1 - b) * (1 - l)),
                difference:(b, l) => Math.abs(b - l),
                // 'alpha' blend mode: standard alpha compositing with plasma as foreground
                alpha:    (b, l, a) => b * (1 - a) + l * a 
            };
            
            const selectedBlendFn = blendFunctions[blendMode] || blendFunctions.overlay; // Default to overlay
            
            let finalR_norm, finalG_norm, finalB_norm;
            if (blendMode === 'alpha') {
                finalR_norm = selectedBlendFn(origR_norm, plasmaR_norm, effectiveIntensity);
                finalG_norm = selectedBlendFn(origG_norm, plasmaG_norm, effectiveIntensity);
                finalB_norm = selectedBlendFn(origB_norm, plasmaB_norm, effectiveIntensity);
            } else {
                 // For other modes, calculate the fully blended color, then mix with original by effectiveIntensity
                 const blendedR = selectedBlendFn(origR_norm, plasmaR_norm);
                 const blendedG = selectedBlendFn(origG_norm, plasmaG_norm);
                 const blendedB = selectedBlendFn(origB_norm, plasmaB_norm);

                 finalR_norm = origR_norm * (1 - effectiveIntensity) + blendedR * effectiveIntensity;
                 finalG_norm = origG_norm * (1 - effectiveIntensity) + blendedG * effectiveIntensity;
                 finalB_norm = origB_norm * (1 - effectiveIntensity) + blendedB * effectiveIntensity;
            }

            data[idx]     = finalR_norm * 255;
            data[idx + 1] = finalG_norm * 255;
            data[idx + 2] = finalB_norm * 255;
            // Alpha channel (data[idx + 3]) remains unchanged
        }
    }

    ctx.putImageData(imageData, 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 Plasma Ball Filter Effect Tool allows users to apply a dynamic and colorful plasma ball effect to images. This tool enables customization of several parameters, including the scale of the plasma effect, ball radius, and colors used in the effect. It is ideal for artists, graphic designers, and hobbyists looking to create visually stunning imagery for social media, digital art projects, or personal use. By blending the original image with a vibrant plasma effect, users can easily enhance photos or create unique backgrounds.

Leave a Reply

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