Please bookmark this page to avoid losing your image tool!

Random Kaleidoscope Image Generator

(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, segmentsInput = "random", zoomInput = "random") {
    // Determine the number of slices for the kaleidoscope
    let segments;
    if (segmentsInput !== "random" && !isNaN(parseInt(segmentsInput))) {
        segments = Math.max(2, parseInt(segmentsInput));
        // Force an even number of segments for perfect mirroring symmetry
        if (segments % 2 !== 0) segments += 1;
    } else {
        // Random even number of slices between 6 and 20
        segments = Math.floor(Math.random() * 8 + 3) * 2; 
    }

    // Determine the scaling (zoom) factor
    let zoom;
    if (zoomInput !== "random" && !isNaN(parseFloat(zoomInput))) {
        zoom = parseFloat(zoomInput);
    } else {
        // Random zoom level mapping from 0.5x to 2.0x
        zoom = Math.random() * 1.5 + 0.5;
    }

    // Determine resolution. Bound it to keep execution fast while ensuring high quality.
    const baseSize = Math.max(originalImg.width, originalImg.height);
    const canvasSize = Math.min(2000, Math.max(800, baseSize)); 

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

    const cx = canvasSize / 2;
    const cy = canvasSize / 2;

    // Generate random transformations to make the design unique every time
    const randomRot = Math.random() * Math.PI * 2;
    const focusX = (Math.random() * 2 - 1) * originalImg.width / 2;
    const focusY = (Math.random() * 2 - 1) * originalImg.height / 2;

    const angle = (Math.PI * 2) / segments;
    // Calculate the diagonal distance from center to corner to ensure fill covers the whole square canvas
    const radius = Math.sqrt(canvasSize * canvasSize * 2) / 2;

    // Fill background with black
    ctx.fillStyle = '#000000';
    ctx.fillRect(0, 0, canvasSize, canvasSize);
    ctx.imageSmoothingEnabled = true;
    ctx.imageSmoothingQuality = 'high';

    // Scale up rendering loops if the provided image is too small to avoid freezing the browser
    let drawW = originalImg.width;
    let drawH = originalImg.height;
    if (drawW > 0 && drawH > 0) {
        while (drawW < 100) drawW *= 2;
        while (drawH < 100) drawH *= 2;
    }

    // Compute exactly how many bounds to tile seamless images
    const reqRadius = (radius / zoom) + Math.max(Math.abs(focusX), Math.abs(focusY));
    const tilesX = Math.min(20, Math.ceil(reqRadius / drawW));
    const tilesY = Math.min(20, Math.ceil(reqRadius / drawH));

    // Construct the kaleidoscope by rendering each angular segment
    for (let i = 0; i < segments; i++) {
        ctx.save();
        ctx.translate(cx, cy);

        // Every odd-numbered segment is mirrored, completing the typical symmetrical kaleidoscope optical illusion
        if (i % 2 === 0) {
            ctx.rotate(i * angle);
        } else {
            ctx.rotate((i + 1) * angle);
            ctx.scale(1, -1);
        }

        // Draw and cut out the wedge sector
        ctx.beginPath();
        ctx.moveTo(0, 0);
        const overlap = 0.005; // tiny overlap to prevent hairline anti-aliasing seams
        ctx.arc(0, 0, radius + 10, -overlap, angle + overlap);
        ctx.closePath();
        ctx.clip();

        // Apply transformations globally to the slice
        ctx.rotate(randomRot);
        ctx.scale(zoom, zoom);
        ctx.translate(focusX, focusY);
        ctx.translate(-drawW / 2, -drawH / 2); // Center the base block

        // Draw multiple repeating seamless tiles to make sure empty space never creeps into the viewer's view
        for (let dx = -tilesX; dx <= tilesX; dx++) {
            for (let dy = -tilesY; dy <= tilesY; dy++) {
                ctx.save();
                ctx.translate(dx * drawW, dy * drawH);

                // Alternate adjacent repeating tiles are internally inverted to tile seamlessly
                if (Math.abs(dx) % 2 === 1) {
                    ctx.translate(drawW, 0);
                    ctx.scale(-1, 1);
                }
                if (Math.abs(dy) % 2 === 1) {
                    ctx.translate(0, drawH);
                    ctx.scale(1, -1);
                }

                // Add a small 0.5px sub-pixel boundary to cleanly fix edge anti-aliasing bleeding
                ctx.drawImage(originalImg, -0.5, -0.5, drawW + 1, drawH + 1);
                ctx.restore();
            }
        }
        
        ctx.restore();
    }

    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 Random Kaleidoscope Image Generator transforms your uploaded images into intricate, symmetrical kaleidoscope patterns. By applying various geometric transformations, mirroring, and tiling, the tool creates visually striking kaleidoscopic effects from any photo. Users can either let the tool automatically generate random patterns with varying segments and zoom levels or specify their own settings for more control. This tool is ideal for creating unique digital art, textures, abstract backgrounds, or decorative design elements for creative projects.

Leave a Reply

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