Please bookmark this page to avoid losing your image tool!

Image Clock Display Tool

(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, clockScale = 0.7, themeColor = '#ffffff', faceOpacity = 0.4) {
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    const ctx = canvas.getContext('2d');

    // A flag to allow stopping the animation if the caller needs to clear memory
    let isRunning = true;
    canvas.stopClockAnimation = () => { isRunning = false; };

    function drawHand(position, length, width, color) {
        ctx.beginPath();
        ctx.lineWidth = width;
        ctx.lineCap = "round";
        ctx.strokeStyle = color;
        ctx.moveTo(canvas.width / 2, canvas.height / 2);
        ctx.lineTo(
            canvas.width / 2 + Math.cos(position) * length,
            canvas.height / 2 + Math.sin(position) * length
        );
        ctx.stroke();
    }

    function drawClock() {
        if (!isRunning) return;

        // Reset shadows for background rendering to avoid performance hit and visual bugs
        ctx.shadowColor = 'transparent';
        ctx.shadowBlur = 0;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 0;

        // Draw the original image as the background
        ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

        // Determine base scaling relative to image dimensions
        const minDim = Math.min(canvas.width, canvas.height);
        const radius = (minDim / 2) * clockScale;
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;

        // Setup shadows to give the clock depth against the image
        ctx.shadowColor = 'rgba(0, 0, 0, 0.6)';
        ctx.shadowBlur = Math.max(2, radius * 0.05);
        ctx.shadowOffsetX = Math.max(1, radius * 0.01);
        ctx.shadowOffsetY = Math.max(1, radius * 0.01);

        // Draw clock face background (Dark semi-transparent circle)
        ctx.beginPath();
        ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
        ctx.fillStyle = `rgba(0, 0, 0, ${faceOpacity})`;
        ctx.fill();

        // Draw outer ring
        ctx.lineWidth = Math.max(2, radius * 0.02);
        ctx.strokeStyle = themeColor;
        ctx.stroke();

        // Draw Minute & Hour Ticks
        for (let i = 0; i < 60; i++) {
            const angle = (i * Math.PI) / 30;
            const isHourTick = i % 5 === 0;
            const tickLength = isHourTick ? radius * 0.1 : radius * 0.05;
            const tickWidth = isHourTick ? radius * 0.03 : radius * 0.015;

            ctx.beginPath();
            ctx.lineWidth = Math.max(1, tickWidth);
            ctx.strokeStyle = themeColor;
            ctx.moveTo(
                centerX + Math.cos(angle) * (radius - tickLength),
                centerY + Math.sin(angle) * (radius - tickLength)
            );
            ctx.lineTo(
                centerX + Math.cos(angle) * radius,
                centerY + Math.sin(angle) * radius
            );
            ctx.stroke();
        }

        // Draw hour numbers (12, 3, 6, 9)
        ctx.font = `bold ${radius * 0.25}px Arial`;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillStyle = themeColor;
        
        const textOffset = radius * 0.68;
        // Text requires slight position tweaking since y is inverted on canvas compared to typical cartesian mapping
        ctx.fillText("12", centerX, centerY - textOffset);
        ctx.fillText("3", centerX + textOffset, centerY);
        ctx.fillText("6", centerX, centerY + textOffset);
        ctx.fillText("9", centerX - textOffset, centerY);

        // Fetch current localized time
        const now = new Date();
        const hour = now.getHours();
        const minute = now.getMinutes();
        const second = now.getSeconds();
        const ms = now.getMilliseconds();

        // Calculate mapped angles (Subtract PI / 2 to shift the 0-degree point from 3 o'clock to 12 o'clock)
        const secPos = ((second + (ms / 1000)) * Math.PI) / 30 - Math.PI / 2; // Smooth second hand
        const minPos = ((minute + (second / 60)) * Math.PI) / 30 - Math.PI / 2; 
        const hrPos = (((hour % 12) + (minute / 60)) * Math.PI) / 6 - Math.PI / 2;

        // Draw Hour Hand
        drawHand(hrPos, radius * 0.45, Math.max(2, radius * 0.05), themeColor);
        // Draw Minute Hand
        drawHand(minPos, radius * 0.65, Math.max(1.5, radius * 0.035), themeColor);
        // Draw Second Hand (Red for high visibility)
        drawHand(secPos, radius * 0.8, Math.max(1, radius * 0.015), '#ff4444');
        // Draw tail of Second Hand wrapping backwards slightly
        drawHand(secPos + Math.PI, radius * 0.15, Math.max(1, radius * 0.015), '#ff4444');

        // Draw Center Pin
        ctx.beginPath();
        ctx.arc(centerX, centerY, radius * 0.04, 0, 2 * Math.PI);
        ctx.fillStyle = '#ff4444';
        ctx.fill();

        // Loop animation matching the screen's refresh rate
        requestAnimationFrame(drawClock);
    }

    // Start the clock animation loop
    drawClock();

    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 Clock Display Tool allows you to overlay a functional, animated analog clock onto any uploaded image. Users can customize the clock’s appearance, including the size of the clock face, the color of the hands and markings, and the transparency of the clock background. This tool is useful for creating dynamic digital wallpapers, designing unique social media assets, or generating stylized time-themed graphic content for presentations and websites.

Leave a Reply

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