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!
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.