You can edit the below JavaScript code to customize the image tool.
/**
* Creates a Fibonacci tiling pattern from a source image.
* The function arranges portions of the source image into squares whose
* side lengths correspond to numbers in the Fibonacci sequence,
* arranged in a spiral pattern. An optional spiral line can be drawn over the tiles.
*
* @param {Image} originalImg The source HTML Image object.
* @param {number} [maxIterations=9] The number of Fibonacci squares to generate. Controls the complexity.
* @param {number} [scale=15] The scale factor. This determines the size of the smallest squares in pixels.
* @param {number} [drawSpiralLine=1] Set to 1 to draw the spiral overlay, 0 to hide it.
* @param {string} [lineColor='rgba(255, 255, 255, 0.75)'] The color of the spiral line.
* @param {number} [lineWidth=4] The width of the spiral line in pixels.
* @returns {HTMLCanvasElement} A canvas element displaying the Fibonacci pattern.
*/
async function processImage(originalImg, maxIterations = 9, scale = 15, drawSpiralLine = 1, lineColor = 'rgba(255, 255, 255, 0.75)', lineWidth = 4) {
// 1. Generate the Fibonacci sequence for the side lengths of the squares.
const fibSequence = [1];
if (maxIterations > 1) {
fibSequence.push(1);
}
for (let i = 2; i < maxIterations; i++) {
fibSequence.push(fibSequence[i - 1] + fibSequence[i - 2]);
}
// 2. Pre-calculate the position and size of each square tile.
// This pass determines the final dimensions of the canvas without drawing anything yet.
const squares = [];
let composite = {
x: 0,
y: 0,
width: 0,
height: 0
}; // Tracks the bounding box of the entire pattern.
for (let i = 0; i < maxIterations; i++) {
const side = fibSequence[i] * scale;
// The direction of placement rotates through a 4-cycle sequence.
const direction = i % 4; // 0: Right, 1: Up, 2: Left, 3: Down
let squareX, squareY;
// Determine the position of the new square based on the current composite bounding box.
switch (direction) {
case 0: // Add to the Right
squareX = composite.x + composite.width;
squareY = composite.y;
composite.width += side;
composite.height = Math.max(composite.height, side);
break;
case 1: // Add to the Top (Up)
squareX = composite.x;
squareY = composite.y - side;
composite.y -= side;
composite.height += side;
break;
case 2: // Add to the Left
squareX = composite.x - side;
squareY = composite.y;
composite.x -= side;
composite.width += side;
break;
case 3: // Add to the Down
squareX = composite.x;
squareY = composite.y + composite.height;
composite.height += side;
break;
}
squares.push({
x: squareX,
y: squareY,
size: side,
dir: direction
});
}
// 3. Create the canvas and get its 2D context.
const canvas = document.createElement('canvas');
canvas.width = composite.width;
canvas.height = composite.height;
const ctx = canvas.getContext('2d');
// Since the spiral can grow into negative coordinates, calculate the offset
// to translate the entire drawing into the positive coordinates of the canvas.
const offsetX = -composite.x;
const offsetY = -composite.y;
// 4. Draw the image tiles onto the canvas.
for (const square of squares) {
// Final destination coordinates on the canvas.
const destX = square.x + offsetX;
const destY = square.y + offsetY;
const destSize = square.size;
// Corresponding source coordinates from the original image.
// This maps the square's position in the final pattern back to the original image.
const sourceX = (destX / canvas.width) * originalImg.naturalWidth;
const sourceY = (destY / canvas.height) * originalImg.naturalHeight;
const sourceW = (destSize / canvas.width) * originalImg.naturalWidth;
const sourceH = (destSize / canvas.height) * originalImg.naturalHeight;
ctx.drawImage(originalImg, sourceX, sourceY, sourceW, sourceH, destX, destY, destSize, destSize);
}
// 5. Optionally, draw the spiral line over the tiles.
if (Number(drawSpiralLine) === 1) {
ctx.strokeStyle = lineColor;
ctx.lineWidth = Number(lineWidth);
ctx.beginPath();
for (const square of squares) {
const destX = square.x + offsetX;
const destY = square.y + offsetY;
const destSize = square.size;
let cx, cy, startAngle, endAngle;
// Determine the arc's center and angles based on the square's placement direction.
switch (square.dir) {
case 0: // Right: arc in bottom-left corner
cx = destX;
cy = destY + destSize;
startAngle = 1.5 * Math.PI;
endAngle = 2 * Math.PI;
break;
case 1: // Up: arc in bottom-right corner
cx = destX + destSize;
cy = destY + destSize;
startAngle = Math.PI;
endAngle = 1.5 * Math.PI;
break;
case 2: // Left: arc in top-right corner
cx = destX + destSize;
cy = destY;
startAngle = 0.5 * Math.PI;
endAngle = Math.PI;
break;
case 3: // Down: arc in top-left corner
cx = destX;
cy = destY;
startAngle = 0;
endAngle = 0.5 * Math.PI;
break;
}
ctx.arc(cx, cy, destSize, startAngle, endAngle);
}
ctx.stroke();
}
// 6. Return the final canvas element.
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 Pattern Generator allows users to create unique visual patterns by arranging portions of a source image into squares that follow the Fibonacci sequence. This tool can generate artistic designs featuring a spiral layout, making it ideal for creative projects such as graphic design, digital art, or educational materials explaining Fibonacci concepts in a visually engaging way. Users can customize the number of squares, their size, and the inclusion of a spiral overlay, catering to various artistic preferences and project requirements.