Please bookmark this page to avoid losing your image tool!

Image Rocket Launch 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, glowIntensity = 0.8, glowColorStr = "255,165,0", smokeAmount = 0.6, darkenSky = 0.7) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Ensure image is loaded and dimensions are available
    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;

    // Helper to parse color string "r,g,b" into numbers
    const parseColor = (colorStr) => {
        try {
            return colorStr.split(',').map(s => parseInt(s.trim(), 10));
        } catch (e) {
            // Default to white if parsing fails
            return [255, 255, 255];
        }
    };

    // Clamp input parameters to sensible ranges
    const effectiveGlowIntensity = Math.max(0, Math.min(1.5, Number(glowIntensity) || 0));
    const [r_glow, g_glow, b_glow] = parseColor(glowColorStr);
    const effectiveSmokeAmount = Math.max(0, Math.min(1.0, Number(smokeAmount) || 0));
    const effectiveDarkenSky = Math.max(0, Math.min(1.0, Number(darkenSky) || 0));


    // ORDER OF DRAWING:
    // 1. Original Image
    // 2. Sky Darkening (Vignette)
    // 3. Smoke
    // 4. Glow (Engine Flame + Plume)

    // 1. Draw Original Image
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    const canvasWidth = canvas.width;
    const canvasHeight = canvas.height;

    // Central point for the effect (bottom-center of the image, roughly where rocket engine would be)
    const effectCenterX = canvasWidth / 2;
    // Main glow position (Y-coordinate, e.g., 0.9 means 90% down from top)
    const mainGlowY = canvasHeight * 0.9; 

    // 2. Sky Darkening / Vignette
    if (effectiveDarkenSky > 0) {
        ctx.save();
        const vignetteCenterX = effectCenterX;
        const vignetteCenterY = mainGlowY; 
        
        const dx1 = vignetteCenterX;
        const dy1 = vignetteCenterY;
        const dx2 = canvasWidth - vignetteCenterX;
        const dy2 = canvasHeight - vignetteCenterY;
        //Ensure maxDist is positive
        const maxDist = Math.max(1, Math.sqrt(Math.max(dx1*dx1, dx2*dx2) + Math.max(dy1*dy1, dy2*dy2)));

        const innerRadius = Math.max(1, canvasHeight * 0.20);

        let gradVignette = ctx.createRadialGradient(
            vignetteCenterX, vignetteCenterY, innerRadius,
            vignetteCenterX, vignetteCenterY, maxDist
        );
        
        gradVignette.addColorStop(0, `rgba(0,0,0,0)`);
        gradVignette.addColorStop(0.3, `rgba(0,0,0, ${effectiveDarkenSky * 0.15})`);
        gradVignette.addColorStop(0.7, `rgba(0,0,0, ${effectiveDarkenSky * 0.75})`);
        gradVignette.addColorStop(1, `rgba(0,0,0, ${effectiveDarkenSky * 0.95})`);

        ctx.fillStyle = gradVignette;
        ctx.fillRect(0, 0, canvasWidth, canvasHeight);
        ctx.restore();
    }

    // 3. Smoke
    const smokeOriginY = mainGlowY + canvasHeight * 0.03;
    if (effectiveSmokeAmount > 0) {
        ctx.save();
        const maxSmokeParticles = 30 + Math.floor(150 * effectiveSmokeAmount);

        for (let i = 0; i < maxSmokeParticles; i++) {
            const particleLife = Math.random(); // 0 (new) to 1 (old/dissipated)
            
            const horizontalSpreadFactor = 0.3 + particleLife * 0.4;
            const horizontalSpread = canvasWidth * horizontalSpreadFactor * (0.8 + effectiveSmokeAmount * 0.4);
            const particleX = effectCenterX + (Math.random() - 0.5) * horizontalSpread;
            
            const verticalDistanceFactor = particleLife * (0.7 + effectiveSmokeAmount * 0.6);
            const verticalDistance = canvasHeight * 0.35 * verticalDistanceFactor;
            const particleY = smokeOriginY - verticalDistance * (0.6 + Math.random() * 0.8);
            
            const baseRadiusFactor = (1 - particleLife * 0.5) * (0.5 + effectiveSmokeAmount * 0.5);
            const baseRadius = Math.max(1, canvasHeight * 0.08 * baseRadiusFactor);
            const particleRadiusX = Math.max(1, baseRadius * (0.5 + Math.random() * 0.8));
            const particleRadiusY = Math.max(1, baseRadius * (0.5 + Math.random() * 0.8));
            
            const opacityFactor = (1 - particleLife * 0.6) * effectiveSmokeAmount;
            const opacity = Math.max(0, (0.1 + 0.5 * Math.random()) * opacityFactor);
            
            const smokeColorVal = 170 + Math.floor(Math.random() * 65);
            ctx.fillStyle = `rgba(${smokeColorVal}, ${smokeColorVal}, ${smokeColorVal + 5}, ${opacity})`;
            
            const blurSize = Math.max(0, canvasHeight * 0.01 * (1 + particleLife * 3 + effectiveSmokeAmount * 2));
            if (blurSize > 0) { // Avoid filter="blur(0px)" which can be slow or buggy
                 ctx.filter = `blur(${blurSize}px)`;
            }
           
            ctx.beginPath();
            ctx.ellipse(particleX, particleY, particleRadiusX, particleRadiusY, Math.random() * Math.PI, 0, Math.PI * 2);
            ctx.fill();
            if (blurSize > 0) {
                ctx.filter = 'none'; // Reset if applied, better to set globally once but this ensures it resets if particles is low
            }
        }
        if (maxSmokeParticles > 0) ctx.filter = 'none'; // Final reset
        ctx.restore();
    }

    // 4. Glow (Engine Flame + Plume)
    if (effectiveGlowIntensity > 0) {
        ctx.save();
        ctx.globalCompositeOperation = 'lighter';

        const mainGlowOuterRadius = Math.max(1, canvasHeight * 0.18 * effectiveGlowIntensity);
        const mainGlowInnerRadius = Math.max(1, mainGlowOuterRadius * 0.25);
        let gradMainGlow = ctx.createRadialGradient(effectCenterX, mainGlowY, mainGlowInnerRadius, effectCenterX, mainGlowY, mainGlowOuterRadius);
        gradMainGlow.addColorStop(0, `rgba(${r_glow}, ${g_glow}, ${b_glow}, ${0.7 * effectiveGlowIntensity})`);
        gradMainGlow.addColorStop(0.5, `rgba(${r_glow}, ${g_glow}, ${b_glow}, ${0.35 * effectiveGlowIntensity})`);
        gradMainGlow.addColorStop(1, `rgba(${r_glow}, ${g_glow}, ${b_glow}, 0)`);
        ctx.fillStyle = gradMainGlow;
        ctx.beginPath();
        ctx.arc(effectCenterX, mainGlowY, mainGlowOuterRadius, 0, Math.PI * 2);
        ctx.fill();

        const coreRadius = Math.max(1, canvasHeight * 0.05 * effectiveGlowIntensity);
        let gradCore = ctx.createRadialGradient(effectCenterX, mainGlowY, coreRadius * 0.05, effectCenterX, mainGlowY, coreRadius);
        gradCore.addColorStop(0, `rgba(255, 255, 255, ${0.9 * effectiveGlowIntensity})`);
        gradCore.addColorStop(0.3, `rgba(255, 255, 230, ${0.7 * effectiveGlowIntensity})`);
        gradCore.addColorStop(1, `rgba(${r_glow},${g_glow},${b_glow}, ${0.2 * effectiveGlowIntensity})`);
        ctx.fillStyle = gradCore;
        ctx.beginPath();
        ctx.arc(effectCenterX, mainGlowY, coreRadius, 0, Math.PI * 2);
        ctx.fill();

        const plumeY = mainGlowY + canvasHeight * 0.015;
        const plumeLength = Math.max(1, canvasHeight * 0.22 * effectiveGlowIntensity);
        const plumeWidth = Math.max(1, canvasWidth * 0.10 * effectiveGlowIntensity);
        
        const plumeBlurSize = Math.max(0, canvasHeight * 0.012 * effectiveGlowIntensity);
        if (plumeBlurSize > 0) {
            ctx.filter = `blur(${plumeBlurSize}px)`;
        }

        ctx.fillStyle = `rgba(${r_glow}, ${g_glow}, ${b_glow}, ${0.45 * effectiveGlowIntensity})`;
        ctx.beginPath();
        ctx.ellipse(effectCenterX, plumeY + plumeLength * 0.25, Math.max(1, plumeWidth * 0.6), Math.max(1, plumeLength * 0.5), 0, 0, Math.PI * 2);
        ctx.fill();

        ctx.fillStyle = `rgba(${r_glow}, ${g_glow}, ${b_glow}, ${0.25 * effectiveGlowIntensity})`;
        ctx.beginPath();
        ctx.ellipse(effectCenterX, plumeY + plumeLength * 0.45, Math.max(1, plumeWidth * 0.9), Math.max(1, plumeLength * 0.9), 0, 0, Math.PI * 2);
        ctx.fill();
        
        if (plumeBlurSize > 0) {
            ctx.filter = 'none';
        }
        ctx.restore();
    }

    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 Rocket Launch Filter Effect Tool allows users to enhance their images by adding dramatic rocket launch effects. This tool applies glow effects, simulating engine flames and plumes, while also incorporating smoke and sky darkening features. Ideal for artists, graphic designers, or anyone looking to create eye-catching imagery, this tool brings a dynamic flair to images, making it perfect for creating promotional materials, social media posts, or personalized artwork that needs an energetic boost.

Leave a Reply

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