Você já se perguntou como sites criam aquelas imagens personalizadas a partir de textos que você digita? Hoje no Geek Codes, vamos abrir o capô desse código e ensinar você a criar um Emoji Status Creator.

Além de bonito, ele é funcional: você digita, escolhe o tema e baixa a imagem pronta para postar!

🧱 A Estrutura (HTML)

O HTML usa uma técnica interessante de contenteditable. Diferente de um campo de formulário comum (input), o contenteditable permite que qualquer div se torne editável, mantendo a estilização do CSS.

  • .content: É o nosso canvas. Tudo o que estiver dentro dela será capturado como imagem.
  • .emojis: Uma coleção de divs vazias que serão preenchidas via JavaScript.

🎨 O Design (CSS)

Aqui entra a mágica visual. Usamos Filtros de Desfoque (Blur) e Opacidade para criar profundidade.

  • Blur & Opacidade: Os emojis de fundo têm filter: blur(10px) e opacity: 0.2. Isso faz com que pareçam estar “longe” da câmera, focando o olhar do usuário no texto central.
  • Pseudo-elemento :before: Usado para criar um “Placeholder” em elementos editáveis. Quando a div está vazia, o CSS injeta o texto “Escreva algo…”.

⚙️ A Lógica (JavaScript & jQuery)

Usamos o jQuery para facilitar a manipulação do DOM e a biblioteca html2canvas para a parte pesada.

  1. Troca Dinâmica: Quando você clica em um emoji da lista, o script percorre todas as 19 divs .emoji e muda o conteúdo interno delas instantaneamente usando .html().
  2. Captura de Tela: O html2canvas lê o código HTML da sua div, entende o posicionamento do CSS e desenha tudo em um <canvas> do navegador, que depois exportamos como .png.

O Código Completo para Estudo

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <title>Emoji Status Creator</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    
    <style>
        body {
            display: flex;
            flex-direction: column;
            background-color: #f0f2f5;
            min-height: 100vh;
            justify-content: center;
            align-items: center;
            margin: 0;
            font-family: "Helvetica", Arial, sans-serif;
        }

        /* Container Principal do Status */
        .content {
            background: #FFFCF9;
            width: 550px;
            height: 412px;
            border-radius: 10px;
            overflow: hidden;
            position: relative;
            box-shadow: 0 10px 25px rgba(0,0,0,0.1);
            margin: 20px auto;
        }

        .content .emojis {
            position: relative;
            pointer-events: none;
            z-index: 1;
        }

        .content .emojis .emoji {
            font-size: 4rem;
            position: absolute;
            left: -4rem;
        }

        /* Posicionamento dos Emojis (Mantido do original) */
        .content .emojis .emoji:nth-child(1) { left: 150px; top: -28px; font-size: 3rem; filter: blur(10px); }
        .content .emojis .emoji:nth-child(2) { left: 380px; top: -15px; font-size: 4.75rem; filter: blur(10px); opacity: 0.5; transform: rotate(10deg); }
        .content .emojis .emoji:nth-child(3) { left: -20px; top: 100px; font-size: 3rem; filter: blur(10px); }
        .content .emojis .emoji:nth-child(4) { left: 140px; top: 80px; font-size: 3.5rem; filter: blur(10px); opacity: 0.2; }
        .content .emojis .emoji:nth-child(5) { left: 340px; top: 150px; font-size: 3.5rem; filter: blur(10px); opacity: 0.4; }
        .content .emojis .emoji:nth-child(6) { left: 140px; top: 190px; font-size: 4rem; filter: blur(10px); opacity: 0.4; transform: rotate(20deg); }
        .content .emojis .emoji:nth-child(7) { left: 390px; top: 280px; font-size: 3rem; filter: blur(10px); opacity: 0.6; }
        .content .emojis .emoji:nth-child(8) { left: 30px; top: 330px; font-size: 4.5rem; filter: blur(10px); opacity: 0.4; transform: rotate(30deg); }
        .content .emojis .emoji:nth-child(9) { left: 230px; top: 350px; font-size: 5rem; filter: blur(10px); opacity: 0.35; }
        .content .emojis .emoji:nth-child(10) { left: 500px; top: 350px; font-size: 4rem; filter: blur(4px); transform: rotate(-20deg); opacity: 0.6; }
        .content .emojis .emoji:nth-child(11) { left: 40px; top: 30px; font-size: 5rem; transform: rotate(-40deg); }
        .content .emojis .emoji:nth-child(12) { left: 240px; top: 0; font-size: 5rem; }
        .content .emojis .emoji:nth-child(13) { left: 505px; top: -5px; font-size: 3rem; transform: rotate(-10deg); }
        .content .emojis .emoji:nth-child(14) { left: 440px; top: 120px; font-size: 3rem; transform: rotate(10deg); }
        .content .emojis .emoji:nth-child(15) { left: -10px; top: 200px; font-size: 5rem; transform: rotate(10deg); }
        .content .emojis .emoji:nth-child(16) { left: 460px; top: 240px; font-size: 4rem; transform: rotate(10deg); }
        .content .emojis .emoji:nth-child(17) { left: 210px; top: 330px; font-size: 3rem; transform: rotate(-30deg); }
        .content .emojis .emoji:nth-child(18) { left: 80px; top: 360px; font-size: 4rem; transform: rotate(-10deg); }
        .content .emojis .emoji:nth-child(19) { left: 350px; top: 370px; font-size: 3rem; transform: rotate(10deg); }

        .content .editor {
            position: absolute;
            text-align: center;
            font-size: 2.2rem;
            font-weight: 600;
            width: 80%;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            z-index: 10;
            outline: none;
            color: #333;
        }

        [contenteditable=true]:empty:before {
            content: attr(placeholder);
            color: rgba(0, 0, 0, 0.2);
        }

        /* Seletor de Emojis */
        .change {
            display: flex;
            justify-content: center;
            font-size: 2.5rem;
            margin-bottom: 10px;
        }

        .change .option {
            margin: 0 10px;
            cursor: pointer;
            transition: transform 0.2s;
            filter: grayscale(100%);
            opacity: 0.5;
        }

        .change .option.active {
            transform: scale(1.3);
            filter: grayscale(0%);
            opacity: 1;
        }

        /* Botão de Download */
        .download-btn {
            background-color: #007bff;
            color: white;
            border: none;
            padding: 12px 30px;
            border-radius: 25px;
            font-size: 1rem;
            font-weight: bold;
            cursor: pointer;
            transition: background 0.3s;
            margin-top: 10px;
            box-shadow: 0 4px 10px rgba(0,123,255,0.3);
        }

        .download-btn:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>

<div class="change">
    <div data-emoji="😍" class="option">😍</div>
    <div data-emoji="😜" class="option">😜</div>
    <div data-emoji="🤔" class="option">🤔</div>
    <div data-emoji="💩" class="option">💩</div>
    <div data-emoji="💣" class="option">💣</div>
    <div data-emoji="🍕" class="option">🍕</div>
</div>

<div class="content" id="capture">
    <div class="emojis">
        <div class="emoji"></div><div class="emoji"></div><div class="emoji"></div>
        <div class="emoji"></div><div class="emoji"></div><div class="emoji"></div>
        <div class="emoji"></div><div class="emoji"></div><div class="emoji"></div>
        <div class="emoji"></div><div class="emoji"></div><div class="emoji"></div>
        <div class="emoji"></div><div class="emoji"></div><div class="emoji"></div>
        <div class="emoji"></div><div class="emoji"></div><div class="emoji"></div>
        <div class="emoji"></div>
    </div>
    <div class="editor" contenteditable="true" placeholder="Escreva algo..."></div>
</div>

<button class="download-btn" id="download">Baixar Status</button>

<script>
    $(document).ready(function () {
        // Seleção de Emoji
        $('[data-emoji]').click(function () {
            $("[data-emoji]").removeClass("active");
            $(this).addClass("active");
            $(".emoji").html($(this).data("emoji"));
        });

        // Trigger inicial aleatório
        const options = $('[data-emoji]');
        $(options[Math.floor(Math.random() * options.length)]).trigger("click");

        // Função de Download
        $('#download').click(function() {
            const btn = $(this);
            btn.text('Gerando...');

            // Captura a div .content como imagem
            html2canvas(document.querySelector("#capture"), {
                backgroundColor: null,
                scale: 2 // Melhora a qualidade da imagem
            }).then(canvas => {
                const link = document.createElement('a');
                link.download = 'meu-status.png';
                link.href = canvas.toDataURL("image/png");
                link.click();
                btn.text('Baixar Status');
            });
        });
    });
</script>

</body>
</html>

Deve ficar assim!