Please bookmark this page to avoid losing your image tool!

Moiré Pattern Image Generator With Shapes And Decorative Elements

(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,
    patternType = 'lines',        // 'lines', 'circles', 'grid'
    spacing = '6',               // Distance between lines/circles
    lineThickness = '2',         // Thickness of the lines
    angle1 = '0',                // Rotation angle of first pattern layer
    angle2 = '5',                // Difference in rotation/shift for the second layer (Creates Moiré)
    color1 = 'rgba(0,0,0,0.8)',  // Color of first layer
    color2 = 'rgba(0,0,0,0.8)',  // Color of second layer
    blendMode = 'source-over',   // Composite operation, e.g., 'difference', 'multiply', 'overlay'
    addDecorations = 'yes',      // 'yes' or 'no'
    decorationType = 'mixed'     // 'stars', 'circles', 'polygons', 'mixed'
) {
    // Parse numeric string parameters
    const parsedSpacing = Math.max(1, Number(spacing));
    const parsedThickness = Math.max(0.1, Number(lineThickness));
    const parsedAngle1 = Number(angle1);
    const parsedAngle2 = Number(angle2);

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

    // 1. Draw base original image
    ctx.drawImage(originalImg, 0, 0);

    // 2. Add decorative background/foreground shapes if requested
    if (String(addDecorations).toLowerCase() === 'yes') {
        // Base number of shapes on image size to look proportionate 
        const numShapes = Math.floor((width * height) / 50000); 
        const colors = ['#FF4B4B', '#4BFF75', '#4B75FF', '#FF4BF5', '#F5FF4B', '#4BFFFF', '#FFFFFF'];

        for (let i = 0; i < Math.max(5, numShapes); i++) {
            const x = Math.random() * width;
            const y = Math.random() * height;
            const size = Math.random() * 40 + 20;
            const color = colors[Math.floor(Math.random() * colors.length)];

            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(Math.random() * Math.PI * 2);
            ctx.globalAlpha = 0.5;
            ctx.fillStyle = color;
            ctx.shadowColor = color;
            ctx.shadowBlur = 10;

            let type = decorationType.toLowerCase();
            if (type === 'mixed') {
                const types = ['stars', 'circles', 'polygons'];
                type = types[Math.floor(Math.random() * types.length)];
            }

            ctx.beginPath();
            if (type === 'stars') {
                for (let j = 0; j < 5; j++) {
                    ctx.lineTo(Math.cos((18 + j * 72) * Math.PI / 180) * size,
                               -Math.sin((18 + j * 72) * Math.PI / 180) * size);
                    ctx.lineTo(Math.cos((54 + j * 72) * Math.PI / 180) * (size / 2),
                               -Math.sin((54 + j * 72) * Math.PI / 180) * (size / 2));
                }
            } else if (type === 'circles') {
                ctx.arc(0, 0, size / 2, 0, Math.PI * 2);
            } else { // polygons (hexagons)
                for (let j = 0; j < 6; j++) {
                    ctx.lineTo((size * 0.8) * Math.cos(j * 2 * Math.PI / 6), 
                               (size * 0.8) * Math.sin(j * 2 * Math.PI / 6));
                }
            }
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        }
    }

    // 3. Setup Moiré generator bounds
    const maxDist = Math.sqrt(width * width + height * height) / 2 + 100; // Extend beyond corners

    function drawPattern(mode, color, rotationAngle, dx = 0, dy = 0) {
        ctx.save();
        ctx.translate(width / 2 + dx, height / 2 + dy);
        ctx.rotate(rotationAngle * Math.PI / 180);
        
        const validCompositeTypes = ['source-over', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'];
        ctx.globalCompositeOperation = validCompositeTypes.includes(blendMode) ? blendMode : 'source-over';
        
        ctx.strokeStyle = color;
        ctx.lineWidth = parsedThickness;
        ctx.beginPath();

        if (mode === 'lines') {
            for (let i = -maxDist; i <= maxDist; i += parsedSpacing) {
                ctx.moveTo(-maxDist, i);
                ctx.lineTo(maxDist, i);
            }
        } else if (mode === 'circles') {
            for (let i = parsedSpacing; i <= maxDist; i += parsedSpacing) {
                ctx.moveTo(i, 0); 
                ctx.arc(0, 0, i, 0, Math.PI * 2);
            }
        } else if (mode === 'grid') {
            for (let i = -maxDist; i <= maxDist; i += parsedSpacing) {
                // Horizontal
                ctx.moveTo(-maxDist, i);
                ctx.lineTo(maxDist, i);
                // Vertical
                ctx.moveTo(i, -maxDist);
                ctx.lineTo(i, maxDist);
            }
        }

        ctx.stroke();
        ctx.restore();
    }

    // 4. Draw Layer 1
    drawPattern(patternType.toLowerCase(), color1, parsedAngle1);

    // 5. Draw Layer 2 with an offset to create the Moiré effect
    // Note: Concentric circles need translation (shifting center) rather than just rotation to show moiré
    let dx2 = 0;
    let dy2 = 0;
    let finalAngle2 = parsedAngle1 + parsedAngle2;
    
    if (patternType.toLowerCase() === 'circles') {
        // Shift context by angle amount so moiré pattern forms dynamically for circles
        dx2 = parsedAngle2;
        dy2 = parsedAngle2 / 2;
        // Rotation doesn't affect identical concentric circles, so we rely on dx/dy
    }

    drawPattern(patternType.toLowerCase(), color2, finalAngle2, dx2, dy2);

    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

This tool allows you to overlay intricate Moiré patterns onto your images to create hypnotic, rhythmic visual effects. Users can choose from various pattern types such as lines, circles, or grids, and customize settings like spacing, line thickness, rotation angles, and colors. The generator also includes an option to add decorative elements like stars, circles, or polygons to enhance the aesthetic. This tool is ideal for graphic designers, digital artists, and creators looking to produce psychedelic art, unique textures for backgrounds, or experimental visual content for social media and print media.

Leave a Reply

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