Please bookmark this page to avoid losing your image tool!

Image 3D Art Creator For Walmart Sidewalk

(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.
/**
 * Creates a 3D perspective art effect of an image on a sidewalk,
 * themed like a Walmart parking lot.
 *
 * @param {Image} originalImg The original javascript Image object.
 * @param {number} [perspective=0.7] Controls the depth of the perspective. A value between 0 (no perspective) and 1 (maximum perspective).
 * @param {number} [angle=0] Skews the image horizontally. Positive values skew the top to the left, negative to the right. Value is in pixels of horizontal offset.
 * @param {string} [sidewalkColor='909090'] The hex color of the sidewalk (e.g., '909090' for gray), without the '#'.
 * @param {string} [lineColor='f0e54d'] The hex color of the parking lot lines (e.g., 'f0e54d' for yellow), without the '#'.
 * @returns {HTMLCanvasElement} A canvas element with the final 3D art.
 */
function processImage(originalImg, perspective = 0.7, angle = 0, sidewalkColor = '909090', lineColor = 'f0e54d') {

    const CANVAS_WIDTH = 800;
    const CANVAS_HEIGHT = 600;

    /**
     * Helper function to draw the sidewalk background with texture, lines, and cracks.
     * @param {CanvasRenderingContext2D} ctx The canvas context to draw on.
     * @param {number} width The width of the canvas.
     * @param {number} height The height of the canvas.
     * @param {string} sColor The hex string for the sidewalk color.
     * @param {string} lColor The hex string for the line color.
     */
    const drawSidewalk = (ctx, width, height, sColor, lColor) => {
        // 1. Create a base concrete texture with noise
        const imageData = ctx.createImageData(width, height);
        const data = imageData.data;
        const r_base = parseInt(sColor.substring(0, 2), 16);
        const g_base = parseInt(sColor.substring(2, 4), 16);
        const b_base = parseInt(sColor.substring(4, 6), 16);

        for (let i = 0; i < data.length; i += 4) {
            const noise = (Math.random() - 0.5) * 40;
            data[i] = r_base + noise;
            data[i + 1] = g_base + noise;
            data[i + 2] = b_base + noise;
            data[i + 3] = 255;
        }
        ctx.putImageData(imageData, 0, 0);

        // 2. Draw perspectived parking lines
        ctx.save();
        ctx.strokeStyle = `#${lColor}`;
        ctx.lineWidth = 15;
        ctx.globalAlpha = 0.7;
        ctx.beginPath();
        ctx.moveTo(width * 0.1, height);
        ctx.lineTo(width * 0.35, height * 0.4);
        ctx.moveTo(width * 0.9, height);
        ctx.lineTo(width * 0.65, height * 0.4);
        ctx.stroke();
        ctx.restore();

        // 3. Draw a few cracks for realism
        ctx.save();
        ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)';
        ctx.lineWidth = 1.5;
        for (let i = 0; i < 3; i++) {
            ctx.beginPath();
            let currentX = Math.random() * width;
            let currentY = height;
            ctx.moveTo(currentX, currentY);
            for (let j = 0; j < 5; j++) {
                currentX += (Math.random() - 0.5) * 150;
                currentY -= (Math.random() * 100 + 20);
                if (currentY < height * 0.4) break;
                ctx.lineTo(currentX, currentY);
            }
            ctx.stroke();
        }
        ctx.restore();
    };

    // --- Main canvas setup ---
    const canvas = document.createElement('canvas');
    canvas.width = CANVAS_WIDTH;
    canvas.height = CANVAS_HEIGHT;
    const ctx = canvas.getContext('2d');

    // 1. Draw the sidewalk background first
    drawSidewalk(ctx, CANVAS_WIDTH, CANVAS_HEIGHT, sidewalkColor, lineColor);

    // --- 2. Pre-process the source image to add a chalk/paint texture ---
    const texturedImgCanvas = document.createElement('canvas');
    const texCtx = texturedImgCanvas.getContext('2d', { willReadFrequently: true });
    const imgWidth = originalImg.width;
    const imgHeight = originalImg.height;
    texturedImgCanvas.width = imgWidth;
    texturedImgCanvas.height = imgHeight;

    // Draw the image onto the temporary canvas
    texCtx.drawImage(originalImg, 0, 0);

    // Apply a subtle noise overlay to make it look less perfect like worn paint
    const noiseData = texCtx.getImageData(0, 0, imgWidth, imgHeight);
    const noisePixels = noiseData.data;
    for (let i = 0; i < noisePixels.length; i += 4) {
        // Only apply noise to non-transparent pixels
        if (noisePixels[i + 3] > 0) {
            const noise = (Math.random() - 0.5) * 50;
            noisePixels[i] = Math.max(0, Math.min(255, noisePixels[i] + noise));
            noisePixels[i + 1] = Math.max(0, Math.min(255, noisePixels[i + 1] + noise));
            noisePixels[i + 2] = Math.max(0, Math.min(255, noisePixels[i + 2] + noise));
        }
    }
    texCtx.putImageData(noiseData, 0, 0);

    // --- 3. Draw the textured image with perspective onto the main canvas ---

    // Define the trapezoid for the perspective transformation
    const topY = CANVAS_HEIGHT * 0.4;
    const bottomY = CANVAS_HEIGHT * 0.95;
    const bottomWidth = imgWidth * 1.5; // Make the base appear wider and closer
    const safePerspective = Math.max(0.01, Math.min(0.9, perspective));
    const topWidth = bottomWidth * (1 - safePerspective);

    // Set alpha for a semi-transparent "painted on" look
    ctx.globalAlpha = 0.9;

    // Iterate through each horizontal scanline of the source image
    for (let y = 0; y < imgHeight; y++) {
        // Calculate the ratio of the current line's position (0 at top, 1 at bottom)
        const ratio = y / (imgHeight - 1);

        // Interpolate the width and y-position on the destination canvas
        const destY = topY + (bottomY - topY) * ratio;
        const destWidth = topWidth + (bottomWidth - topWidth) * ratio;
        let destX = (CANVAS_WIDTH - destWidth) / 2;

        // Apply horizontal skew based on the 'angle' parameter
        const skewAmount = (ratio - 0.5) * -angle;
        destX += skewAmount;

        // Overlap strips slightly to avoid anti-aliasing gaps
        const destHeight = ((bottomY - topY) / imgHeight) * 1.5;

        ctx.drawImage(
            texturedImgCanvas,
            0, y, imgWidth, 1, // Source: 1-pixel high slice
            destX, destY, destWidth, destHeight // Destination: stretched and positioned slice
        );
    }

    // Reset global alpha
    ctx.globalAlpha = 1.0;

    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 3D Art Creator for Walmart Sidewalk allows users to transform a standard image into a visually intriguing 3D perspective artwork that simulates the appearance of being painted on a sidewalk, specifically designed to resemble a Walmart parking lot. Users can customize the depth of perspective, the skew angle of the image, as well as the colors of the sidewalk and the parking lot lines. This tool is perfect for creating engaging visuals for marketing materials, social media posts, or personal projects where a unique artistic effect is desired.

Leave a Reply

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