Please bookmark this page to avoid losing your image tool!

Image Fibonacci Spiral 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, numTerms = 10, scaleFactor = 1.0, lineWidth = 2, lineColor = "rgba(255, 255, 255, 0.8)", startAngleDeg = 0, rotationDirection = "clockwise") {
    const canvas = document.createElement('canvas');
    // Ensure canvas dimensions are positive, otherwise drawing context might error or behave unexpectedly.
    canvas.width = Math.max(1, originalImg.width);
    canvas.height = Math.max(1, originalImg.height);
    const ctx = canvas.getContext('2d');

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

    // Set line properties for the spiral
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = lineColor;

    // Calculate the center of the spiral
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;

    // Save the current canvas state
    ctx.save();

    // Translate to the center and apply global rotation for the spiral
    ctx.translate(centerX, centerY);
    ctx.rotate(startAngleDeg * Math.PI / 180);

    ctx.beginPath();

    // penX, penY are the coordinates of the current tip of the spiral, relative to the translated/rotated center
    let penX = 0;
    let penY = 0;

    // Initialize Fibonacci sequence values for calculating radii
    // fibPrev = F_(n-1) * scaleFactor, fibCurr = F_n * scaleFactor
    // We use the sequence 1, 1, 2, 3, 5... for F_n, scaled by scaleFactor
    let fibPrev = 0; // Conceptually F_0 * scaleFactor
    let fibCurr = 1 * scaleFactor; // F_1 * scaleFactor. This will be the radius of the first arc.

    // Determine if arcs should be drawn counter-clockwise based on rotationDirection
    // This flag is passed to ctx.arc()
    const drawArcAnticlockwise = (rotationDirection === 'counter-clockwise');

    // Move to the starting point of the first arc segment
    // This is (0,0) in the transformed coordinate system
    ctx.moveTo(penX, penY);

    for (let i = 0; i < numTerms; i++) {
        const radius = fibCurr;

        // Stop if radius is not a usable positive finite number (e.g., Infinity, NaN, or negative)
        if (!isFinite(radius) || radius < 0) {
            break;
        }
        // If scaleFactor is 0, radius will be 0.
        // Drawing an arc with 0 radius is a no-op after moveTo, so the path won't change.
        // This is acceptable. The loop will continue, but no visible spiral will be drawn.

        let arcCenterX, arcCenterY, arcStartAngle, arcEndAngle;
        let nextPenX, nextPenY; // Stores the end point of the current arc

        // k determines the quadrant/direction of growth for the current arc segment
        // This cycle of 4 directions creates the spiral turns.
        const k = i % 4;

        if (rotationDirection === 'clockwise') {
            // Clockwise spiral: arcs make right turns, angles sweep clockwise.
            switch (k) {
                case 0: // Arc segment starts from penX,penY, effectively grows "East", turns downwards.
                    arcCenterX = penX;          // Center is directly "South" of penX by radius
                    arcCenterY = penY + radius;
                    arcStartAngle = -Math.PI / 2; // Angle for North (from center's perspective)
                    arcEndAngle = 0;              // Angle for East (from center's perspective)
                    nextPenX = penX + radius;   // Arc ends here
                    nextPenY = penY;
                    break;
                case 1: // Grows "South", turns leftwards.
                    arcCenterX = penX - radius; // Center is "West" of penX
                    arcCenterY = penY;
                    arcStartAngle = 0;              // Angle for East
                    arcEndAngle = Math.PI / 2;      // Angle for South
                    nextPenX = penX;
                    nextPenY = penY + radius;
                    break;
                case 2: // Grows "West", turns upwards.
                    arcCenterX = penX;          // Center is "North" of penX
                    arcCenterY = penY - radius;
                    arcStartAngle = Math.PI / 2;      // Angle for South
                    arcEndAngle = Math.PI;            // Angle for West
                    nextPenX = penX - radius;
                    nextPenY = penY;
                    break;
                case 3: // Grows "North", turns rightwards.
                    arcCenterX = penX + radius; // Center is "East" of penX
                    arcCenterY = penY;
                    arcStartAngle = Math.PI;            // Angle for West
                    arcEndAngle = Math.PI * 1.5;    // Angle for North
                    nextPenX = penX;
                    nextPenY = penY - radius;
                    break;
            }
        } else { // counter-clockwise spiral: arcs make left turns, angles sweep counter-clockwise.
            switch (k) {
                case 0: // Grows "East", turns upwards.
                    arcCenterX = penX;          // Center is "North" of penX
                    arcCenterY = penY - radius;
                    arcStartAngle = 0;    // For CCW arc: Start angle from center's perspective for (penX+radius, penY)
                    arcEndAngle = Math.PI / 2;    // End angle for (penX, penY)
                                                // Note: Canvas `arc` with CCW true expects startAngle < endAngle for CCW sweep.
                                                // The (cx,cy) is (penX, penY-R). Arc from (penX+R, penY) to (penX, penY) is CCW.
                                                // Start of arc is (penX, penY). End of arc is (penX+radius, penY).
                                                // Point (penX,penY) is at angle PI/2 relative to center (penX, penY-radius).
                                                // Point (penX+radius,penY) is at angle 0 relative to center (penX, penY-radius).
                                                // So for CCW drawing logic: startAngle=0, endAngle=PI/2 defines this segment path from (penX+R, penY-R) to (penX, penY-R)
                                                // For drawing from (penX, penY):
                    nextPenX = penX + radius;
                    nextPenY = penY;
                    break;
                case 1: // Grows "South", turns rightwards.
                    arcCenterX = penX + radius; // Center is "East" of penX
                    arcCenterY = penY;
                    arcStartAngle = Math.PI / 2;
                    arcEndAngle = Math.PI;
                    nextPenX = penX;
                    nextPenY = penY + radius;
                    break;
                case 2: // Grows "West", turns downwards.
                    arcCenterX = penX;          // Center is "South" of penX
                    arcCenterY = penY + radius;
                    arcStartAngle = Math.PI;
                    arcEndAngle = Math.PI * 1.5;
                    nextPenX = penX - radius;
                    nextPenY = penY;
                    break;
                case 3: // Grows "North", turns leftwards.
                    arcCenterX = penX - radius; // Center is "West" of penX
                    arcCenterY = penY;
                    arcStartAngle = Math.PI * 1.5;
                    arcEndAngle = Math.PI * 2; // or 0
                    nextPenX = penX;
                    nextPenY = penY - radius;
                    break;
            }
        }
        
        // Only draw if radius is positive. Arc with 0 radius draws nothing/dot.
        if (radius > 0) {
           ctx.arc(arcCenterX, arcCenterY, radius, arcStartAngle, arcEndAngle, drawArcAnticlockwise);
        }

        penX = nextPenX;
        penY = nextPenY;

        // Update Fibonacci numbers for the next iteration
        const tempFib = fibPrev + fibCurr;
        fibPrev = fibCurr;
        fibCurr = tempFib;
    }

    ctx.stroke(); // Apply the drawing path
    ctx.restore(); // Restore the canvas state to before transformations

    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 Fibonacci Spiral Filter Effect Tool allows users to apply a visually striking Fibonacci spiral filter effect to their images. By using this tool, you can enhance your photos with a unique design that incorporates the Fibonacci sequence, creating aesthetically pleasing spirals that can be customized in terms of scale, color, and direction of rotation. This tool is ideal for artists, graphic designers, and anyone looking to add a creative twist to their images for social media, digital artwork, or personal projects.

Leave a Reply

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