Please bookmark this page to avoid losing your image tool!

Image Rain Effect Filter

(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,
    numberOfDrops = 500,
    paramDropLengthMin = 5,
    paramDropLengthMax = 20,
    paramDropThicknessMin = 1,
    paramDropThicknessMax = 2,
    dropColor = "rgba(200, 200, 230, 0.6)", // A light grey-blue, semi-transparent
    angleDegrees = 10 // Degrees from vertical. Positive = slanting to the right.
) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Use naturalWidth/Height for intrinsic image dimensions.
    // These are more reliable than .width/.height if the image element's display size is altered by CSS or attributes.
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    // Handle cases where image dimensions are not available (e.g., image not loaded or src is invalid)
    if (imgWidth === 0 || imgHeight === 0) {
        console.warn("Image Rain Effect: Original image has zero width or height. Returning an empty canvas.");
        // The canvas will have default dimensions (e.g., 300x150 or 0x0) or what was set before this check.
        // To be explicit for 0x0 image:
        canvas.width = 0;
        canvas.height = 0;
        return canvas;
    }

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

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

    // Sanitize min/max parameters to ensure min <= max, and calculate range
    const dropLengthMin = Math.min(paramDropLengthMin, paramDropLengthMax);
    const dropLengthMax = Math.max(paramDropLengthMin, paramDropLengthMax);
    const dropLengthRange = dropLengthMax - dropLengthMin;

    const dropThicknessMin = Math.min(paramDropThicknessMin, paramDropThicknessMax);
    const dropThicknessMax = Math.max(paramDropThicknessMin, paramDropThicknessMax);
    const dropThicknessRange = dropThicknessMax - dropThicknessMin;

    // Convert angle to radians for Math functions
    // angleDegrees = 0 means vertical rain.
    // Positive angleDegrees means rain slants to the right (from top-left to bottom-right).
    // Negative angleDegrees means rain slants to the left.
    const angleRad = angleDegrees * (Math.PI / 180);

    ctx.strokeStyle = dropColor;
    ctx.lineCap = 'round'; // Makes the ends of the lines smoother, looking more like streaks

    for (let i = 0; i < numberOfDrops; i++) {
        // Determine random length and thickness for the current raindrop
        const currentLength = dropLengthMin + Math.random() * dropLengthRange;
        let currentThickness = dropThicknessMin + Math.random() * dropThicknessRange;
        
        // Ensure thickness is at least a very small positive number if min/max allows zero or less
        currentThickness = Math.max(0.1, currentThickness); // Avoid zero-width lines if not intended
        ctx.lineWidth = currentThickness;

        // Calculate the horizontal (dx) and vertical (dy) components of the raindrop
        // based on its length and angle.
        // For typical rain angles (-90 to 90 deg from vertical), dy (using cos) will be positive (downward).
        const dx = currentLength * Math.sin(angleRad);
        const dy = currentLength * Math.cos(angleRad);

        // Determine the starting point (x1, y1) of the raindrop's line segment.
        // The spawn area is calculated to allow raindrops to naturally enter the visible canvas area
        // from outside, based on their angle and length.

        // For Y-coordinate (y1 is the top of the drop):
        // Raindrops should appear to fall from above.
        // Spawn range for y1: [-abs(dy), imgHeight]. Width of spawn range: imgHeight + abs(dy).
        // This means y1 can start up to 'abs(dy)' pixels above the canvas.
        const ySpawnAbsDy = Math.abs(dy); // Use abs in case of unusual angles where dy might be non-positive
        const y1_spawn_range = imgHeight + ySpawnAbsDy;
        const y1_offset = ySpawnAbsDy;
        const y1 = (Math.random() * y1_spawn_range) - y1_offset;

        // For X-coordinate (x1 is the starting horizontal point):
        // Spawn logic depends on the horizontal direction of rain (dx).
        let x1;
        if (dx >= 0) { // Rain is vertical or slanting to the right
            // Spawn range for x1: [-dx, imgWidth]. Width: imgWidth + dx.
            // x1 can start up to 'dx' pixels to the left of canvas.
            const x1_spawn_range = imgWidth + dx; // dx is positive or zero
            x1 = (Math.random() * x1_spawn_range) - dx;
        } else { // Rain is slanting to the left (dx < 0)
            // Spawn range for x1: [0, imgWidth - dx]. Width: imgWidth - dx (which is imgWidth + abs(dx)).
            // x1 can start from canvas left edge (0) up to 'abs(dx)' pixels to the right of canvas right edge.
            // (meaning the line starts at x1 and ends at x1+dx, which could be on canvas).
            const x1_spawn_range = imgWidth - dx; // dx is negative
            x1 = Math.random() * x1_spawn_range;
        }

        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x1 + dx, y1 + dy);
        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 Rain Effect Filter is a tool that simulates the appearance of rain on an image by adding stylized raindrops. Users can customize various parameters such as the number of raindrops, their lengths, thickness, color, and the angle of fall. This tool can be used for artistic purposes, such as enhancing photos with a rainy effect for mood or thematic relevance, creating unique visuals for designs and social media, or simply for fun effects in digital photography. It’s a straightforward way to transform standard images into evocative, rain-soaked scenes.

Leave a Reply

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