Please bookmark this page to avoid losing your image tool!

Image Lost Petanque Ball Notice Creator

(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.
async function processImage(
    originalImg,
    brand = 'MS',
    dateLost = 'dimanche 17 août',
    address = '1111 Chem. du Mont de Lanaudière, Saint-Gabriel-de-Brandon, QC J0K 2N0',
    locationDetails = 'Club-école Les Boulistes',
    inscription = '685 3 MS 23B X38',
    contactMethod = 'Facebook Messenger',
    backgroundColor = '#f0f2f5',
    textColor = '#050505',
    accentColor = '#1877f2'
) {
    // Dynamically load a Google Font for better appearance
    const fontName = 'Roboto';
    try {
        const font = new FontFace(fontName, `url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2)`);
        await font.load();
        document.fonts.add(font);
    } catch (e) {
        console.error("Font could not be loaded. Using system default.", e);
        // The function will continue with a system default font like 'sans-serif'
    }


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

    // Helper function for wrapping text
    function wrapText(context, text, x, y, maxWidth, lineHeight) {
        const words = text.split(' ');
        let line = '';
        let currentY = y;
        context.textAlign = 'left';
        context.textBaseline = 'top';

        for (let i = 0; i < words.length; i++) {
            const testLine = line + words[i] + ' ';
            const metrics = context.measureText(testLine);
            const testWidth = metrics.width;
            if (testWidth > maxWidth && i > 0) {
                context.fillText(line, x, currentY);
                line = words[i] + ' ';
                currentY += lineHeight;
            } else {
                line = testLine;
            }
        }
        context.fillText(line, x, currentY);
        return currentY + lineHeight;
    }

    // 1. Draw Background
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, width, height);

    // Layout variables
    const margin = 80;
    const contentWidth = width - 2 * margin;
    let currentY = margin;

    // 2. Draw Title
    ctx.fillStyle = textColor;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';
    ctx.font = `bold 64px ${fontName}, sans-serif`;
    ctx.fillText('📣 AVIS DE PERTE 📣', width / 2, currentY);
    currentY += 75;

    ctx.font = `48px ${fontName}, sans-serif`;
    ctx.fillText('Boule de Pétanque', width / 2, currentY);
    currentY += 80;

    // 3. Draw the Image of the petanque ball
    const imgSize = 400;
    const imgX = (width - imgSize) / 2;
    const imgY = currentY;
    
    // Draw a nice circular frame for the image
    ctx.save();
    ctx.beginPath();
    ctx.arc(imgX + imgSize / 2, imgY + imgSize / 2, imgSize / 2, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.clip();
    
    // Draw the image clipped to the circle
    ctx.drawImage(originalImg, imgX, imgY, imgSize, imgSize);
    
    ctx.restore();

    // Draw a border around the clipped image
    ctx.beginPath();
    ctx.arc(imgX + imgSize / 2, imgY + imgSize / 2, imgSize / 2, 0, Math.PI * 2, true);
    ctx.strokeStyle = '#cccccc';
    ctx.lineWidth = 8;
    ctx.stroke();

    currentY += imgSize + 60;

    // 4. Draw Details
    const textX = margin;
    const lineHeight = 48;
    const regularFont = `32px ${fontName}, sans-serif`;
    const boldFont = `bold 32px ${fontName}, sans-serif`;

    ctx.fillStyle = textColor;
    ctx.font = regularFont;
    
    const line1 = `Bonjour à tous, j’ai perdu ma boule de pétanque (marque: ${brand}) le ${dateLost} à l'adresse suivante :`;
    currentY = wrapText(ctx, line1, textX, currentY, contentWidth, lineHeight);
    currentY += 20;

    ctx.font = boldFont;
    const fullAddress = `📍 ${address} (${locationDetails})`;
    currentY = wrapText(ctx, fullAddress, textX, currentY, contentWidth, lineHeight);
    currentY += 30;

    ctx.font = regularFont;
    currentY = wrapText(ctx, 'La boule est identifiable par l’inscription :', textX, currentY, contentWidth, lineHeight);
    
    ctx.font = boldFont;
    ctx.fillStyle = accentColor;
    currentY = wrapText(ctx, `🔍 ${inscription}`, textX, currentY, contentWidth, lineHeight);
    currentY += 30;

    ctx.fillStyle = textColor;
    ctx.font = regularFont;
    const contactLine = `Si quelqu’un l’a retrouvée, merci de me contacter via ${contactMethod}.`;
    currentY = wrapText(ctx, contactLine, textX, currentY, contentWidth, lineHeight);
    
    // 5. Draw Closing
    ctx.font = `italic 36px ${fontName}, sans-serif`;
    ctx.textAlign = 'center';
    ctx.fillText('Toute aide serait grandement appréciée. Merci !', width / 2, height - margin);

    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 Lost Petanque Ball Notice Creator is a web-based tool designed to help users create visually appealing notices for lost petanque balls. Users can upload an image of their petanque ball and input relevant details such as the brand, date lost, address, and contact method. The tool generates a notice with clear formatting and a customized design that can be easily printed or shared online. This tool is particularly useful for petanque enthusiasts looking to recover lost equipment, as it allows for effective communication with the community.

Leave a Reply

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