Please bookmark this page to avoid losing your image tool!

Image Meteor Shower 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.
function processImage(originalImg, numberOfMeteors = 50, meteorColor = "rgba(255, 255, 220, 0.9)", minLength = 30, maxLength = 120, minThickness = 1, maxThickness = 3, mainAngleDeg = 100, spreadAngleDeg = 40) {

    /**
     * Helper function to get R,G,B components as a string "R,G,B"
     * from any valid CSS color string (e.g., "yellow", "#FF0", "rgb(255,0,0)", "rgba(0,255,0,0.5)").
     * This is used to create a fully transparent version of the meteorColor for the gradient tail.
     * @param {string} colorStr - The CSS color string.
     * @returns {string} A string in the format "R,G,B".
     */
    function colorToRGBTripletString(colorStr) {
        // Create a temporary 1x1 canvas to draw the color and extract its RGB values.
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = 1;
        tempCanvas.height = 1;
        // Add { willReadFrequently: true } for potential performance optimization if supported.
        const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
        
        // Fill with a white opaque background first. This ensures that the color drawn
        // on top will be sampled correctly, regardless of its own alpha channel.
        tempCtx.fillStyle = '#FFFFFF'; 
        tempCtx.fillRect(0, 0, 1, 1);
        
        // Then draw the specified color on top of the white background.
        tempCtx.fillStyle = colorStr;
        tempCtx.fillRect(0, 0, 1, 1);
        
        // Get the RGBA data of the single pixel. We only need R, G, B.
        const [r, g, b] = tempCtx.getImageData(0, 0, 1, 1).data;
        return `${r},${g},${b}`;
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Use naturalWidth/Height if available for original image dimensions, otherwise fallback to width/height properties.
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

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

    // Draw the original image onto the canvas as the background.
    ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    // Prepare color strings for the meteor gradient.
    // The user-provided meteorColor defines the bright head of the meteor.
    // The tail will fade to a version of this color with alpha 0.
    const rgbTriplet = colorToRGBTripletString(meteorColor);
    const transparentMeteorColor = `rgba(${rgbTriplet},0)`;
    
    // Define the proportion of the meteor's length that constitutes its "solid" head.
    const headRatio = 0.05; // e.g., 5% of the length.

    for (let i = 0; i < numberOfMeteors; i++) {
        // Random starting position for the meteor's head.
        // Meteors will originate from anywhere on the image.
        const startX = Math.random() * imgWidth;
        const startY = Math.random() * imgHeight;

        // Random length and thickness for variety.
        const length = minLength + Math.random() * (maxLength - minLength);
        const thickness = minThickness + Math.random() * (maxThickness - minThickness);

        // Random angle for the meteor's path.
        // mainAngleDeg: 0 is horizontal to the right, 90 is vertical downwards.
        // spreadAngleDeg: defines the range of deviation from the mainAngleDeg.
        const angleOffset = (Math.random() - 0.5) * spreadAngleDeg; // Random offset within [-spread/2, +spread/2]
        const currentAngleRad = (mainAngleDeg + angleOffset) * Math.PI / 180; // Convert to radians.

        // Calculate the end position of the meteor based on start, length, and angle.
        const endX = startX + Math.cos(currentAngleRad) * length;
        const endY = startY + Math.sin(currentAngleRad) * length;

        // Create a linear gradient for the meteor streak.
        // The gradient goes from the meteor's head (startX, startY) to its tail tip (endX, endY).
        const gradient = ctx.createLinearGradient(startX, startY, endX, endY);
        gradient.addColorStop(0, meteorColor);                 // Start of the head (brightest, full user-defined color)
        gradient.addColorStop(headRatio, meteorColor);         // End of the "solid" head part
        gradient.addColorStop(1, transparentMeteorColor);      // End of the tail (fades to fully transparent)

        // Draw the meteor path.
        ctx.beginPath();
        ctx.moveTo(startX, startY);
        ctx.lineTo(endX, endY);
        ctx.strokeStyle = gradient;    // Apply the gradient as the stroke style.
        ctx.lineWidth = thickness;     // Set the meteor's thickness.
        ctx.lineCap = 'round';         // Makes the ends of the meteor trail (head and tail tip) rounded and softer.
        ctx.stroke();
    }

    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 Meteor Shower Filter Effect Tool allows users to enhance their images by adding simulated meteor shower effects. Users can specify various parameters such as the number of meteors, their color, length, and thickness to create visually striking meteor trails across their images. This tool is ideal for artists, photographers, and social media enthusiasts looking to creatively edit their visuals, adding an atmospheric touch or thematic elements to enhance storytelling in their images.

Leave a Reply

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