自訂貼紙

在WhatsApp Web中建立自訂貼紙。

// ==UserScript==
// @name         WhatsApp Sticker Creator with Custom Maker Enhanced
// @version      1.2
// @name:af Persoonlike Stickertjies
// @description:af Skep persoonlike stickertjies in WhatsApp Web.
// @name:ar ملصقات مخصصة
// @description:ar إنشاء ملصقات مخصصة في WhatsApp Web.
// @name:az Fərdi stikerlər
// @description:az WhatsApp Web-də fərdi stikerlər yaradın.
// @name:bg Персонализирани стикери
// @description:bg Създаване на персонализирани стикери в WhatsApp Web.
// @name:bn কাস্টম স্টিকার
// @description:bn WhatsApp Web-এ কাস্টম স্টিকার তৈরি করুন।
// @name:bs Prilagođene naljepnice
// @description:bs Kreirajte prilagođene naljepnice u WhatsApp Webu.
// @name:ca Gomets personalitzats
// @description:ca Crea gomets personalitzats a WhatsApp Web.
// @name:cs Vlastní nálepky
// @description:cs Vytvářejte vlastní nálepky ve WhatsApp Webu.
// @name:cy Stickeriaid addasedig
// @description:cy Creu stickeriaid addasedig yn WhatsApp Web.
// @name:da Brugerdefinerede stickers
// @description:da Opret brugerdefinerede stickers i WhatsApp Web.
// @name:de Benutzerdefinierte Aufkleber
// @description:de Erstellen Sie benutzerdefinierte Aufkleber in WhatsApp Web.
// @name:el Προσαρμοσμένα αυτοκόλλητα
// @description:el Δημιουργήστε προσαρμοσμένα αυτοκόλλητα στο WhatsApp Web.
// @name:en Custom Stickers
// @description:en Create custom stickers in WhatsApp Web.
// @name:eo Propraj glumarkoj
// @description:eo Kreu proprajn glumarkojn en WhatsApp Web.
// @name:es Stickers personalizados
// @description:es Crear stickers personalizados en WhatsApp Web.
// @name:et Kohandatud kleepsud
// @description:et Looge WhatsApp Web-is kohandatud kleepsud.
// @name:eu Pertsonalizatutako itsaskiak
// @description:eu Sortu pertsonalizatutako itsaskiak WhatsApp Web-en.
// @name:fa برچسب‌های سفارشی
// @description:fa ایجاد برچسب‌های سفارشی در WhatsApp Web.
// @name:fi Mukautetut tarrat
// @description:fi Luo mukautettuja tarranauhoja WhatsApp Webiin.
// @name:fr Autocollants personnalisés
// @description:fr Créer des autocollants personnalisés dans WhatsApp Web.
// @name:gl Adhesivos personalizados
// @description:gl Crea adhesivos personalizados en WhatsApp Web.
// @name:gu કસ્ટમ સ્ટિકર્સ
// @description:gu WhatsApp Web માં કસ્ટમ સ્ટિકર્સ બનાવો.
// @name:he מדבקות מותאמות אישית
// @description:he צור מדבקות מותאמות אישית ב-WhatsApp Web.
// @name:hi कस्टम स्टिकर
// @description:hi WhatsApp Web में कस्टम स्टिकर बनाएं।
// @name:hr Prilagođene naljepnice
// @description:hr Stvorite prilagođene naljepnice u WhatsApp Webu.
// @name:hu Egyéni matricák
// @description:hu Hozzon létre egyéni matricákat a WhatsApp Webben.
// @name:id Stiker kustom
// @description:id Buat stiker kustom di WhatsApp Web.
// @name:it Sticker personalizzati
// @description:it Crea sticker personalizzati su WhatsApp Web.
// @name:ja カスタムステッカー
// @description:ja WhatsApp Webでカスタムステッカーを作成します。
// @name:ka მორგებული სტიკერები
// @description:ka შექმენით მორგებული სტიკერები WhatsApp Web-ში.
// @name:kk Таңбалар
// @description:kk WhatsApp Web-де тұтынушыға сәйкес таңбалар жасаңыз.
// @name:km ស្លាកតាមតម្រូវការ
// @description:km បង្កើតស្លាកតាមតម្រូវការនៅលើ WhatsApp Web។
// @name:kn ಅನುಗುಣವಾದ ಸ್ಟಿಕರ್‌ಗಳು
// @description:kn WhatsApp Web ನಲ್ಲಿ ಅನುಗುಣವಾದ ಸ್ಟಿಕರ್‌ಗಳನ್ನು ರಚಿಸಿ.
// @name:ko 사용자 정의 스티커
// @description:ko WhatsApp 웹에서 사용자 정의 스티커를 만듭니다.
// @name:ku Stikerên xwerû
// @description:ku Di WhatsApp Web de stikerên xwerû biafirîne.
// @name:ky Көнүлгө ылайыктуу стикерлер
// @description:ky WhatsApp Web'de кардардын көңүлүнө ылайыктуу стикерлерди түзгүлө.
// @name:lt Pasirinktini lipdukai
// @description:lt Sukurkite pasirinktinius lipdukus „WhatsApp Web“.
// @name:lv Pielāgotas uzlīmes
// @description:lv Izveidojiet pielāgotas uzlīmes WhatsApp tīmeklī.
// @name:mk Прилагодени стикери
// @description:mk Креирајте прилагодени стикери во WhatsApp Web.
// @name:ml ആവശ്യമനുസരിച്ച് സ്റ്റിക്കർ
// @description:ml WhatsApp വെബിൽ ആവശ്യമനുസരിച്ച് സ്റ്റിക്കർ സൃഷ്ടിക്കുക.
// @name:mn Өөрийн хүссэн шошго
// @description:mn WhatsApp Web дээр өөрийн хүссэн шошго үүсгэх.
// @name:mr कस्टम स्टिकर
// @description:mr WhatsApp Web मध्ये कस्टम स्टिकर तयार करा.
// @name:ms Pelekat tersuai
// @description:ms Cipta pelekat tersuai di WhatsApp Web.
// @name:my စိတ်ကြိုက်နှိပ်ပုံများ
// @description:my WhatsApp Web တွင်စိတ်ကြိုက်သတ်မှတ်ထားသော နှိပ်ပုံများဖန်တီးပါ။
// @name:nb Egne klistremerker
// @description:nb Lag egne klistremerker i WhatsApp Web.
// @name:ne अनुकूलित स्टिकरहरू
// @description:ne WhatsApp वेबमा अनुकूलित स्टिकरहरू सिर्जना गर्नुहोस्।
// @name:nl Aangepaste stickers
// @description:nl Maak aangepaste stickers in WhatsApp Web.
// @name:nn Tilpassa klistremerke
// @description:nn Lag tilpassa klistremerke i WhatsApp Web.
// @name:no Egne klistremerker
// @description:no Lag egne klistremerker i WhatsApp Web.
// @name:pa ਕਸਟਮ ਸਟਿੱਕਰ
// @description:pa WhatsApp ਵੈਬ ਵਿੱਚ ਕਸਟਮ ਸਟਿੱਕਰ ਬਣਾਓ।
// @name:pl Niestandardowe naklejki
// @description:pl Twórz niestandardowe naklejki w WhatsApp Web.
// @name:pt Adesivos personalizados
// @description:pt Criar adesivos personalizados no WhatsApp Web.
// @name:ro Autocolante personalizate
// @description:ro Creați autocolante personalizate în WhatsApp Web.
// @name:ru Стикеры
// @description:ru Создавайте собственные стикеры в WhatsApp Web.
// @name:si විශේෂිත සටිකර
// @description:si WhatsApp Web හි විශේෂිත සටිකර සාදන්න.
// @name:sk Vlastné nálepky
// @description:sk Vytvorte vlastné nálepky v službe WhatsApp Web.
// @name:sl Prilagojene nalepke
// @description:sl Ustvarite prilagojene nalepke v WhatsApp Spletu.
// @name:sq Ngjitës të personalizuar
// @description:sq Krijoni ngjitës të personalizuar në WhatsApp Web.
// @name:sr Прилагодљиве налепнице
// @description:sr Направите прилагодљиве налепнице у ВхатсАпп Вебу.
// @name:sv Anpassade klistermärken
// @description:sv Skapa anpassade klistermärken i WhatsApp Web.
// @name:sw Lebo maalum
// @description:sw Tengeneza lebo maalum katika WhatsApp Web.
// @name:ta தனிப்பயனாக அட்டைகள்
// @description:ta WhatsApp வலைதளத்தில் தனிப்பயனாக அட்டைகள் உருவாக்கவும்.
// @name:te అనుకూలిత స్టికర్లు
// @description:te WhatsApp వెబ్‌లో అనుకూలిత స్టికర్లు సృష్టించండి.
// @name:th สติกเกอร์แบบกำหนดเอง
// @description:th สร้างสติกเกอร์แบบกำหนดเองใน WhatsApp Web
// @name:tr Özel etiketler
// @description:tr WhatsApp Web'de özel etiketler oluşturun.
// @name:uk Власні наклейки
// @description:uk Створюйте власні наклейки в WhatsApp Web.
// @name:ur کسٹم اسٹکر
// @description:ur WhatsApp ویب میں کسٹم اسٹکر بنائیں۔
// @name:uz Maxsus stikerlar
// @description:uz WhatsApp Web-da maxsus stikerlar yarating.
// @name:vi Nhãn dán tùy chỉnh
// @description:vi Tạo nhãn dán tùy chỉnh trong WhatsApp Web.
// @name:zh 自定义贴纸
// @description:zh 在WhatsApp Web中创建自定义贴纸。
// @name:zh-CN 自定义贴纸
// @description:zh-CN 在WhatsApp Web中创建自定义贴纸。
// @name:zh-TW 自訂貼紙
// @description:zh-TW 在WhatsApp Web中建立自訂貼紙。
// @author       DeveloperMDCM
// @match        https://web.whatsapp.com/
// @icon         https://static-00.iconduck.com/assets.00/whatsapp-icon-1020x1024-iykox85t.png
// @grant        GM_addStyle
// @run-at       document-end
// @compatible chrome
// @compatible firefox
// @compatible opera
// @compatible safari
// @compatible edge
// @license MIT
// @namespace https://github.com/DeveloperMDCM/
// @homepage     https://github.com/DeveloperMDCM/
// @description Create custom stickers in WhatsApp Web.
// ==/UserScript==

(function () {
    'use strict';
    console.log('Script en ejecución by: DeveloperMDCM');
    const HEADER_STYLE = 'color: #F00; font-size: 24px; font-family: sans-serif;';
    const MESSAGE_STYLE = 'color: #00aaff; font-size: 16px; font-family: sans-serif;';
    const CODE_STYLE = 'font-size: 14px; font-family: monospace;';
  
    console.log(
      '%cStiker Maker for Whatsapp Web\n' +
        '%cRun %c(v1.0)\n' +
        'By: DeveloperMDCM.',
      HEADER_STYLE,
      CODE_STYLE,
      MESSAGE_STYLE
    );
  
    // Variables globales para rotación y hover
    let isRotating = false;
    let initialRotateAngle = 0;
    let initialElementRotation = 0;
    let hoveredElement = null;
    let currentMousePos = { x: 0, y: 0 };
    const colorsText = ["#000000", "#ff0000", "#00ff00", "#0000ff", "#ffff00", "#00ffff", "#ff00ff", "#ffffff", "#ff000000"];

    GM_addStyle(`
        /* Panel principal */
        #stickerPanel {
            position: fixed;
            top: 0;
            right: 0;
            width: 580px;
            height: auto;
            max-height: 90vh;
            overflow-y: auto;
            background-color: #111b21;
            border: 1px solid #202c33;
            padding: 10px;
            z-index: 10000;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }
        /* Pestañas */
        .tabsContainer {
            display: flex;
            justify-content: space-around;
            margin-bottom: 10px;
        }
        .tabsContainer button {
            flex: 1;
            padding: 8px;
            border: none;
            cursor: pointer;
            background-color: #005c4b;
            color: #fff;
            font-weight: bold;
        }
        .tabsContainer button:first-child { margin-right: 5px; }
        .tabsContainer button:last-child { margin-left: 5px; }
        /* Sección Clásica */
        .dropZone {
            border: 2px dashed #ccc;
            padding: 20px;
            text-align: center;
            margin-bottom: 10px;
            cursor: pointer;
            background-color: #111b21;
        }
        input[type="file"] { display: none; }
        #createSticker, #createCustomSticker {
            width: 100%;
            padding: 8px;
            margin-top: 5px;
            background-color: #005c4b;
            border: none;
            color: #fff;
            font-weight: bold;
            border-radius: 3px;
        }
        #status, #customStatus {
            font-size: 12px;
            color: #555;
            text-align: center;
            margin-top: 5px;
        }
        #previewCanvas { display: none; }
        /* Sección Personalizada */
        #customSection { display: none; }
        /* Toolbar y menús emergentes */
        #customToolbar {
            display: flex;
            flex-wrap: wrap;
            gap: 5px;
            margin-bottom: 5px;
            align-items: center;
        }
        #customToolbar button {
            padding: 5px 8px;
            cursor: pointer;
            border: none;
            background-color: #005c4b;
            color: #fff;
            border-radius: 3px;
        }
        #customToolbar select { padding: 4px; }
        /* Panel de opciones del lápiz y de formas */
        #pencilOptionsPanel, #shapeOptionsPanel {
            display: none;
            margin: 5px 0;
            padding: 5px;
            border: 1px solid #ddd;
            background-color: #005c4b;
            font-size: 12px;
            border-radius: 3px;
        }
        /* Botones de color y tamaño */
        .colorButton, .sizeButton {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            border: 2px solid #ccc;
            display: inline-block;
            margin: 2px;
            cursor: pointer;
        }
        .sizeButton[data-size="2"] { width: 8px; height: 8px; }
        .sizeButton[data-size="4"] { width: 12px; height: 12px; }
        .sizeButton[data-size="6"] { width: 16px; height: 16px; }
        .sizeButton[data-size="8"] { width: 20px; height: 20px; }
        #pencilColorContainer, #pencilSizeContainer { display: inline-block; vertical-align: middle; }
        /* Panel para formas */
        #shapeOptionsPanel button {
            margin-right: 5px;
            padding: 3px 6px;
            border: none;      
            color: #fff;
            border-radius: 3px;
            cursor: pointer;
        }
        /* Área de canvas con fondo ajedrezado */
        .canvasContainer {
            border: 2px dashed #ccc;
            width: 100%;
            height: 60vh;
            max-height: 60vh;
            margin: auto;
            position: relative;
        }
        #customCanvas {
            width: 100%;
            height: 100%;
            background-size: 20px 20px;
            background-image:
              linear-gradient(45deg, #ccc 25%, transparent 25%),
              linear-gradient(-45deg, #ccc 25%, transparent 25%),
              linear-gradient(45deg, transparent 75%, #ccc 75%),
              linear-gradient(-45deg, #fff 75%, #ccc 75%);
            background-size: 20px 20px;
            background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
            display: block;
        }
        /* Botón flotante */
        #openStickerPanel {
            position: fixed;
            bottom: 20px;
            right: 20px;
            padding: 10px 15px;
            background-color: #005c4b;
            color: #fff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 10000;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
        }
        /* Panel de edición de texto */
        #textEditorPanel {
            margin-top: 10px;
            padding: 5px;
         
            display: none;
            border-radius: 3px;
        }
        #textEditorPanel label { margin: 3px 5px; }
        /* Panel de emojis */
        #emojiContainer {
            position: fixed;
            top: 0;
            right: 600px;
            width: auto;
            height: 400px;
            background-color: #111b21;
            border: 1px solid #ddd;
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
            z-index: 10000;
            display: none;
            flex-direction: column;
            border-radius: 3px;
        }
        #emojiCategoryContainer {
            display: flex;
            justify-content: space-around;
            padding: 5px;
        }
        #emojiCategoryContainer button {
            background-color: #005c4b;
            color: #fff;
            border: none;
            padding: 5px;
            cursor: pointer;
            flex: 1;
            margin: 0 2px;
            border-radius: 3px;
        }
        #emojiContent {
            overflow-y: auto;
            height: 350px;
            padding: 10px 0 30px 10px;
            display: grid;
            background-color: black;
            grid-template-columns: repeat(6, 1fr);
            gap: 5px;
        }
        #textFontSelect {
        width: auto;
            appearance: auto;
        }
         #textFontSelect:not(:invalid) {
        color: #fff;
        }
        .textEditorContent {
          display: flex;
          flex-direction: column;
          gap: 6px;
        }
    `);

    // =========================
    // Espera a que la página se cargue
    // =========================
    window.addEventListener("load", () => { setTimeout(initStickerTool, 3000); });


    const emojis = {
        faces_emotion: [
            { "emoji": "😀" }, { "emoji": "😁" }, { "emoji": "😂" }, { "emoji": "🤣" },
            { "emoji": "😃" }, { "emoji": "😄" }, { "emoji": "😅" }, { "emoji": "😆" },
            { "emoji": "😉" }, { "emoji": "😊" }, { "emoji": "😋" }, { "emoji": "😎" },
            { "emoji": "😍" }, { "emoji": "😘" }, { "emoji": "🥰" }, { "emoji": "😗" },
            { "emoji": "😙" }, { "emoji": "🥲" }, { "emoji": "😚" }, { "emoji": "☺️" },
            { "emoji": "🙂" }, { "emoji": "🤗" }, { "emoji": "🤩" }, { "emoji": "🤔" },
            { "emoji": "🫡" }, { "emoji": "🤨" }, { "emoji": "😐" }, { "emoji": "😑" },
            { "emoji": "😶" }, { "emoji": "🫥" }, { "emoji": "😶‍🌫️" }, { "emoji": "🙄" },
            { "emoji": "😏" }, { "emoji": "😣" }, { "emoji": "😥" }, { "emoji": "😮" },
            { "emoji": "🤐" }, { "emoji": "😯" }, { "emoji": "😪" }, { "emoji": "😫" },
            { "emoji": "🥱" }, { "emoji": "😴" }, { "emoji": "😌" }, { "emoji": "😛" },
            { "emoji": "😜" }, { "emoji": "😝" }, { "emoji": "🤤" }, { "emoji": "😒" },
            { "emoji": "😓" }, { "emoji": "😔" }, { "emoji": "😕" }, { "emoji": "🫤" },
            { "emoji": "🙃" }, { "emoji": "🫠" }, { "emoji": "🤑" }, { "emoji": "😲" },
            { "emoji": "☹️" }, { "emoji": "🙁" }, { "emoji": "😖" }, { "emoji": "😞" },
            { "emoji": "😟" }, { "emoji": "😤" }, { "emoji": "😢" }, { "emoji": "😭" },
            { "emoji": "😦" }, { "emoji": "😧" }, { "emoji": "😨" }, { "emoji": "😩" },
            { "emoji": "🤯" }, { "emoji": "😬" }, { "emoji": "😮‍💨" }, { "emoji": "😰" },
            { "emoji": "😱" }, { "emoji": "🥵" }, { "emoji": "🥶" }, { "emoji": "😳" },
            { "emoji": "🤪" }, { "emoji": "😵" }, { "emoji": "😵‍💫" }, { "emoji": "🥴" },
            { "emoji": "😠" }, { "emoji": "😡" }, { "emoji": "🤬" }, { "emoji": "😷" },
            { "emoji": "🤒" }, { "emoji": "🤕" }, { "emoji": "🤢" }, { "emoji": "🤮" },
            { "emoji": "🤧" }, { "emoji": "😇" }, { "emoji": "🥳" }, { "emoji": "🥸" },
            { "emoji": "🥺" }, { "emoji": "🥹" }, { "emoji": "🤠" }, { "emoji": "🤡" },
            { "emoji": "🤥" }, { "emoji": "🫨" }, { "emoji": "🤫" }, { "emoji": "🤭" },
            { "emoji": "🫢" }, { "emoji": "🫣" }, { "emoji": "🧐" }, { "emoji": "🤓" },
            { "emoji": "😈" }, { "emoji": "👿" }, { "emoji": "👹" }, { "emoji": "👺" },
            { "emoji": "💀" }, { "emoji": "☠️" }, { "emoji": "👻" }, { "emoji": "👽" },
            { "emoji": "👾" }, { "emoji": "💩" }, { "emoji": "🤖" }
        ],
        animals: [
            { "emoji": "😺" }, { "emoji": "😸" }, { "emoji": "😹" }, { "emoji": "😻" },
            { "emoji": "😼" }, { "emoji": "😽" }, { "emoji": "🙀" }, { "emoji": "😿" },
            { "emoji": "😾" }, { "emoji": "🙈" }, { "emoji": "🙉" }, { "emoji": "🙊" },
            { "emoji": "🐵" }, { "emoji": "🐶" }, { "emoji": "🐺" }, { "emoji": "🐱" },
            { "emoji": "🦁" }, { "emoji": "🐯" }, { "emoji": "🦒" }, { "emoji": "🦊" },
            { "emoji": "🦝" }, { "emoji": "🐮" }, { "emoji": "🐷" }, { "emoji": "🐗" },
            { "emoji": "🐭" }, { "emoji": "🐹" }, { "emoji": "🐰" }, { "emoji": "🐻" },
            { "emoji": "🐨" }, { "emoji": "🐼" }, { "emoji": "🐸" }, { "emoji": "🦓" },
            { "emoji": "🐴" }, { "emoji": "🫎" }, { "emoji": "🫏" }, { "emoji": "🦄" },
            { "emoji": "🐔" }, { "emoji": "🐲" }, { "emoji": "🐽" }, { "emoji": "🐾" },
            { "emoji": "🐒" }, { "emoji": "🦍" }, { "emoji": "🦧" }, { "emoji": "🦮" },
            { "emoji": "🐩" }, { "emoji": "🐕" }, { "emoji": "🐈" }, { "emoji": "🐅" },
            { "emoji": "🐆" }, { "emoji": "🦌" }, { "emoji": "🦬" }, { "emoji": "🦏" },
            { "emoji": "🐘" }, { "emoji": "🐁" }, { "emoji": "🐀" }, { "emoji": "🦔" },
            { "emoji": "🐇" }, { "emoji": "🦎" }, { "emoji": "🐊" }, { "emoji": "🐢" },
            { "emoji": "🐍" }, { "emoji": "🐉" }, { "emoji": "🦕" }, { "emoji": "🦖" },
            { "emoji": "🐬" }, { "emoji": "🐳" }, { "emoji": "🐋" }, { "emoji": "🐟" },
            { "emoji": "🐠" }, { "emoji": "🐡" }, { "emoji": "🦀" }, { "emoji": "🐚" }
        ]
    };

    function initStickerTool() {
        if (document.getElementById("stickerPanel")) return;

        // Crear panel principal
        const panel = document.createElement("div");
        panel.id = "stickerPanel";
        panel.style.display = "none";
        // Pestañas
        const tabsContainer = document.createElement("div");
        tabsContainer.className = "tabsContainer";
        const btnClassic = document.createElement("button");
        btnClassic.textContent = "Classic Sticker";
        const btnCustom = document.createElement("button");
        btnCustom.textContent = "Custom Sticker";
        tabsContainer.appendChild(btnClassic);
        tabsContainer.appendChild(btnCustom);
        panel.appendChild(tabsContainer);

        // Sección Clásica
        const classicSection = document.createElement("div");
        classicSection.id = "classicSection";
        classicSection.innerHTML = `
            <div id="dropZone" class="dropZone">Drag or click to select image</div>
            <input type="file" id="fileInput" accept="image/*" />
            <button id="createSticker" disabled>Create Sticker</button>
            <p id="status"></p>
            <canvas id="previewCanvas"></canvas>
        `;
        panel.appendChild(classicSection);

        // Sección Personalizada
        const customSection = document.createElement("div");
        customSection.id = "customSection";
        customSection.innerHTML = `

            <!-- Toolbar con íconos -->
            <div id="customToolbar">
             <button id="addCustomImage"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-photo-plus"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M12.5 21h-6.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6.5" /><path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l4 4" /><path d="M14 14l1 -1c.67 -.644 1.45 -.824 2.182 -.54" /><path d="M16 19h6" /><path d="M19 16v6" /></svg></button>
                <button id="openEmojiPanel"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-mood-smile"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /><path d="M9 10l.01 0" /><path d="M15 10l.01 0" /><path d="M9.5 15a3.5 3.5 0 0 0 5 0" /></svg></button>
                <input type="file" id="customFileInput" accept="image/*" />
                <button id="toggleDrawing"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-pencil"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" /><path d="M13.5 6.5l4 4" /></svg></button>
                <button id="toggleShapes"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-square"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" /></svg></button>
                <button id="bringForward"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-layers-selected"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M8 10.5l6.492 -6.492" /><path d="M13.496 16l6.504 -6.504z" /><path d="M8.586 15.414l10.827 -10.827" /><path d="M8 6a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z" /><path d="M16 16v2a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-8a2 2 0 0 1 2 -2h2" /></svg></button>
                <button id="sendBackward"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-layers-selected-bottom"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 14.5l4 -4" /><path d="M9.496 20l4.004 -4z" /><path d="M4.586 19.414l3.914 -3.914" /><path d="M8 6a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z" /><path d="M16 16v2a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-8a2 2 0 0 1 2 -2h2" /></svg></button>
                <button id="deleteElement"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-trash"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 7l16 0" /><path d="M10 11l0 6" /><path d="M14 11l0 6" /><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12" /><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3" /></svg></button>
                <button id="clearCanvas"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-restore"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3.06 13a9 9 0 1 0 .49 -4.087" /><path d="M3 4.001v5h5" /><path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /></svg></button>
                <button id="toggleMultiSelect"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-select-all"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M8 8m0 1a1 1 0 0 1 1 -1h6a1 1 0 0 1 1 1v6a1 1 0 0 1 -1 1h-6a1 1 0 0 1 -1 -1z" /><path d="M12 20v.01" /><path d="M16 20v.01" /><path d="M8 20v.01" /><path d="M4 20v.01" /><path d="M4 16v.01" /><path d="M4 12v.01" /><path d="M4 8v.01" /><path d="M4 4v.01" /><path d="M8 4v.01" /><path d="M12 4v.01" /><path d="M16 4v.01" /><path d="M20 4v.01" /><path d="M20 8v.01" /><path d="M20 12v.01" /><path d="M20 16v.01" /><path d="M20 20v.01" /></svg></btton>
                <button id="addText"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-letter-t"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6 4l12 0" /><path d="M12 4l0 16" /></svg></button>
                <button id="downloadImage"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-photo-down"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M12.5 21h-6.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6.5" /><path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l4 4" /><path d="M14 14l1 -1c.653 -.629 1.413 -.815 2.13 -.559" /><path d="M19 16v6" /><path d="M22 19l-3 3l-3 -3" /></svg></button>
                <button id="undo"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-back-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 14l-4 -4l4 -4" /><path d="M5 10h11a4 4 0 1 1 0 8h-1" /></svg></button>
                <button id="redo"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-forward-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 14l4 -4l-4 -4" /><path d="M19 10h-11a4 4 0 1 0 0 8h1" /></svg></button>
            </div>
            <!-- Panel emergente para opciones del lápiz -->
            <div id="pencilOptionsPanel">
                <div>Pincel - Colores:</div>
                <div id="pencilColorContainer"></div>
                <div>Pincel - Grosor:</div>
                <div id="pencilSizeContainer"></div>
            </div>
            <!-- Panel emergente para opciones de formas -->
            <div id="shapeOptionsPanel">
                <button id="shapeSquare"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-square"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" /></svg></button>
                <button id="shapeCircle"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-circle"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /></svg></button>
            </div>
            <div class="canvasContainer">
                <canvas id="customCanvas" width="512" height="512"></canvas>
            </div>
            <button id="createCustomSticker">Create Custom Sticker</button>
            <p id="customStatus"></p>
            <!-- Panel de edición de texto -->
            <div id="textEditorPanel">
              <div class="textEditorContent">
                <label>Text: <input type="text" id="textContentInput"></label>
               <div>
                <label>Color: <span id="textColorButtons"></span></label>
                <label>Bg: <span id="textBgButtons"></span></label>
               </div>
                <div>
                <label>Font:
                    <select id="textFontSelect">
                        <option value="" disabled selected>Select font</option>
                        <option value="Arial">Arial</option>
                        <option value="Courier New">Courier New</option>
                        <option value="Times New Roman">Times New Roman</option>
                        <option value="Verdana">Verdana</option>
                        <option value="Georgia">Georgia</option>
                    </select>
                </label>
                  <label>Size: <input type="range" id="textFontSizeInput" min="10" max="100" value="30"></label>
                </div>
              </dib>
              
            </div>
        `;
        panel.appendChild(customSection);

        document.body.appendChild(panel);

        // Botón flotante para abrir/cerrar el panel
        addFloatingButton(panel);

        // Configurar secciones
        setupClassicSection();
        setupCustomSection();

        // Cambio de pestañas
        btnClassic.addEventListener("click", () => {
            document.getElementById("classicSection").style.display = "block";
            document.getElementById("customSection").style.display = "none";
        });
        btnCustom.addEventListener("click", () => {
            document.getElementById("classicSection").style.display = "none";
            document.getElementById("customSection").style.display = "block";
        });
    }



    // Botón flotante
    function addFloatingButton(panel) {
        const btn = document.createElement("button");
        btn.id = "openStickerPanel";
        btn.textContent = "Sticker";
        btn.innerHTML = `<svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-sticker-2"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6 4h12a2 2 0 0 1 2 2v7h-5a2 2 0 0 0 -2 2v5h-7a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2z" /><path d="M20 13v.172a2 2 0 0 1 -.586 1.414l-4.828 4.828a2 2 0 0 1 -1.414 .586h-.172" /></svg>`
        document.body.appendChild(btn);
        btn.addEventListener("click", () => {
            panel.style.display = panel.style.display === "none" ? "block" : "none";
            const emojiContainer = document.getElementById("emojiContainer");

            if (emojiContainer.style.display === "flex") {
                emojiContainer.style.display = "none";
            }
            else {
                emojiContainer.style.display = "none";
            }

        });
    }

    // =========================
    // MODO CLÁSICO
    // =========================
    function setupClassicSection() {
        const dropZone = document.getElementById("dropZone");
        const fileInput = document.getElementById("fileInput");
        const createStickerButton = document.getElementById("createSticker");
        const statusText = document.getElementById("status");
        const previewCanvas = document.getElementById("previewCanvas");
        let selectedImageCanvas = null;
        let createClicked = false;

        dropZone.addEventListener("click", () => fileInput.click());
        dropZone.addEventListener("dragover", (e) => { e.preventDefault(); dropZone.style.borderColor = "#000"; });
        dropZone.addEventListener("dragleave", (e) => { e.preventDefault(); dropZone.style.borderColor = "#ccc"; });
        dropZone.addEventListener("drop", (e) => {
            e.preventDefault();
            dropZone.style.borderColor = "#ccc";
            if (e.dataTransfer.files && e.dataTransfer.files[0]) { handleFile(e.dataTransfer.files[0]); }
        });
        fileInput.addEventListener("change", () => { if (fileInput.files && fileInput.files[0]) { handleFile(fileInput.files[0]); } });

        function handleFile(file) {

            const reader = new FileReader();
            reader.onload = function (event) {
                const img = new Image();
                img.onload = function () {
                    previewCanvas.width = previewCanvas.parentElement.clientWidth;
                    previewCanvas.height = previewCanvas.parentElement.clientHeight;
                    const ctx = previewCanvas.getContext("2d");
                    ctx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);
                    const ratio = Math.min(previewCanvas.width / img.width, previewCanvas.height / img.height);
                    const newWidth = img.width * ratio;
                    const newHeight = img.height * ratio;
                    const dx = (previewCanvas.width - newWidth) / 2;
                    const dy = (previewCanvas.height - newHeight) / 2;
                    ctx.drawImage(img, dx, dy, newWidth, newHeight);
                    selectedImageCanvas = previewCanvas;
                    createStickerButton.disabled = false;
                    statusText.textContent = "Image uploaded successfully";
                    createClicked = false;
                };
                img.src = event.target.result;
            };
            reader.readAsDataURL(file);
        }

        createStickerButton.addEventListener("click", () => {
            if (!selectedImageCanvas || createClicked) return;
            createClicked = true;
            createStickerButton.disabled = true;
            statusText.textContent = "Generating sticker...";
            selectedImageCanvas.toBlob(function (blob) {
                if (!blob) { statusText.textContent = "Error al convertir la imagen."; return; }
                const stickerFile = new File([blob], "sticker.webp", { type: "image/webp" });
                simulateWhatsAppFileUpload(stickerFile, statusText);
            }, "image/webp");
        });
    }

    // =========================
    // MODO PERSONALIZADO (STICKER MAKER)
    // =========================
    function setupCustomSection() {
        const customCanvas = document.getElementById("customCanvas");
        const ctx = customCanvas.getContext("2d");
        customCanvas.width = customCanvas.offsetWidth;
        customCanvas.height = customCanvas.offsetHeight;
        const addCustomImageButton = document.getElementById("addCustomImage");
        const customFileInput = document.getElementById("customFileInput");
        const createCustomStickerButton = document.getElementById("createCustomSticker");
        const customStatus = document.getElementById("customStatus");
        const toggleDrawingButton = document.getElementById("toggleDrawing");
        const toggleShapesButton = document.getElementById("toggleShapes");
        const bringForwardButton = document.getElementById("bringForward");
        const sendBackwardButton = document.getElementById("sendBackward");
        const deleteElementButton = document.getElementById("deleteElement");
        const clearCanvasButton = document.getElementById("clearCanvas");
        const toggleMultiSelectButton = document.getElementById("toggleMultiSelect");
        const addTextButton = document.getElementById("addText");
        const fontSelect = document.getElementById("fontSelect");
        const downloadButton = document.getElementById("downloadImage");
        const undoButton = document.getElementById("undo");
        const redoButton = document.getElementById("redo");

        // Paneles emergentes
        const pencilOptionsPanel = document.getElementById("pencilOptionsPanel");
        const pencilColorContainer = document.getElementById("pencilColorContainer");
        const pencilSizeContainer = document.getElementById("pencilSizeContainer");
        const shapeOptionsPanel = document.getElementById("shapeOptionsPanel");
        const shapeSquareButton = document.getElementById("shapeSquare");
        const shapeCircleButton = document.getElementById("shapeCircle");

        // Panel de edición de texto
        const textEditorPanel = document.getElementById("textEditorPanel");
        const textContentInput = document.getElementById("textContentInput");
        const textColorButtons = document.getElementById("textColorButtons");
        const textBgButtons = document.getElementById("textBgButtons");
        const textFontSelect = document.getElementById("textFontSelect");
        const textFontSizeInput = document.getElementById("textFontSizeInput");

        // Variables internas para el lápiz
        let drawingColor = "#000000";
        const brushSizeInput = { value: 2 };

        // Variables para elementos en el canvas
        let customElements = [];
        let selectedElement = null;
        let isDrawingMode = false;
        let drawingInProgress = false;
        let currentDrawing = null;
        let customCreateClicked = false;
        let offsetX = 0, offsetY = 0;
        let isDragging = false;
        let isResizing = false, resizeStartX = 0, resizeStartY = 0;
        let originalFontSize = 0;
        let originalWidth = 0, originalHeight = 0;

        // Variables para multi-select
        let isMultiSelectMode = false;
        let multiSelectedElements = [];
        let multiSelectRect = null;
        let isGroupDragging = false;
        let groupDragStart = null;

        // Variables para undo/redo
        let history = [];
        let historyIndex = -1;

        function resizeCanvas() {
            const container = customCanvas.parentElement;
            customCanvas.width = container.clientWidth;
            customCanvas.height = container.clientHeight;
            drawCustomCanvas();
        }
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);

        function cloneCustomElements(elements) {
            return elements.map(el => {
                let newEl = Object.assign({}, el);
                if (el.points) newEl.points = el.points.map(p => ({ x: p.x, y: p.y }));
                if (el.type === "image" && el.img && el.img.src) {
                    const newImg = new Image();
                    newImg.src = el.img.src;
                    newEl.img = newImg;
                }
                return newEl;
            });
        }
        function saveHistory() {
            history = history.slice(0, historyIndex + 1);
            history.push(cloneCustomElements(customElements));
            historyIndex++;
        }

        // Helper: tamaño por defecto para imágenes
        function getDefaultImageSize(img) {
            let width = img.width, height = img.height;
            if (width > 300) {
                const ratio = 300 / width;
                width = img.width * ratio;
                height = img.height * ratio;
            }
            return { width, height };
        }

        // Función para detectar si un punto está en un elemento (considerando rotación)
        function isPointInElement(el, x, y) {
            if (el.rotation && el.rotation !== 0) {
                const cx = el.x + el.width / 2;
                const cy = el.y + el.height / 2;
                // Convertir (x,y) al sistema de coordenadas del elemento
                const dx = x - cx;
                const dy = y - cy;
                const angle = -el.rotation;
                const rx = dx * Math.cos(angle) - dy * Math.sin(angle);
                const ry = dx * Math.sin(angle) + dy * Math.cos(angle);
                return rx >= -el.width / 2 && rx <= el.width / 2 && ry >= -el.height / 2 && ry <= el.height / 2;
            } else {
                return x >= el.x && x <= el.x + el.width && y >= el.y && y <= el.y + el.height;
            }
        }

        // Variable para almacenar la posición actual del mouse
        let currentMousePos = { x: 0, y: 0 };

        // Función para dibujar un elemento (aplica rotación si tiene)
        function drawElement(el) {
            if (el.rotation && el.rotation !== 0) {
                const cx = el.x + el.width / 2, cy = el.y + el.height / 2;
                ctx.save();
                ctx.translate(cx, cy);
                ctx.rotate(el.rotation);
                if (el.type === "image") {
                    ctx.drawImage(el.img, -el.width / 2, -el.height / 2, el.width, el.height);
                } else if (el.type === "emoji") {
                    ctx.font = el.fontSize + "px sans-serif";
                    ctx.textBaseline = "top";
                    ctx.fillText(el.emoji, -el.width / 2, -el.height / 2);
                } else if (el.type === "drawing") {
                    ctx.beginPath();
                    el.points.forEach((p, index) => { index === 0 ? ctx.moveTo(p.x - cx, p.y - cy) : ctx.lineTo(p.x - cx, p.y - cy); });
                    ctx.strokeStyle = el.color; ctx.lineWidth = el.brushSize;
                    ctx.lineJoin = "round"; ctx.lineCap = "round"; ctx.stroke();
                } else if (el.type === "text") {
                    ctx.font = el.fontSize + "px " + el.fontFamily;
                    ctx.textBaseline = "top";
                    if (el.bgColor) {
                        const metrics = ctx.measureText(el.text);
                        const padding = 2;
                        ctx.fillStyle = el.bgColor;
                        ctx.fillRect(-el.width / 2 - padding, -el.height / 2 - padding, metrics.width + 2 * padding, el.fontSize + 2 * padding);
                    }
                    ctx.fillStyle = el.color;
                    ctx.fillText(el.text, -el.width / 2, -el.height / 2);
                } else if (el.type === "shape") {
                    ctx.strokeStyle = el.color; ctx.lineWidth = 2;
                    if (el.shape === "square") {
                        ctx.strokeRect(-el.width / 2, -el.height / 2, el.width, el.height);
                    } else if (el.shape === "circle") {
                        ctx.beginPath();
                        ctx.arc(0, 0, el.width / 2, 0, Math.PI * 2);
                        ctx.stroke();
                    }
                }
                ctx.restore();
            } else {
                if (el.type === "image") {
                    ctx.drawImage(el.img, el.x, el.y, el.width, el.height);
                } else if (el.type === "emoji") {
                    ctx.font = el.fontSize + "px sans-serif";
                    ctx.textBaseline = "top";
                    ctx.fillText(el.emoji, el.x, el.y);
                    const metrics = ctx.measureText(el.emoji);
                    el.width = metrics.width; el.height = el.fontSize;
                } else if (el.type === "drawing") {
                    ctx.beginPath();
                    el.points.forEach((p, index) => { index === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y); });
                    ctx.strokeStyle = el.color; ctx.lineWidth = el.brushSize;
                    ctx.lineJoin = "round"; ctx.lineCap = "round"; ctx.stroke();
                } else if (el.type === "text") {
                    ctx.font = el.fontSize + "px " + el.fontFamily;
                    ctx.textBaseline = "top";
                    if (el.bgColor) {
                        const metrics = ctx.measureText(el.text);
                        const padding = 2;
                        ctx.fillStyle = el.bgColor;
                        ctx.fillRect(el.x - padding, el.y - padding, metrics.width + 2 * padding, el.fontSize + 2 * padding);
                    }
                    ctx.fillStyle = el.color;
                    ctx.fillText(el.text, el.x, el.y);
                    const metrics = ctx.measureText(el.text);
                    el.width = metrics.width; el.height = el.fontSize;
                } else if (el.type === "shape") {
                    ctx.strokeStyle = el.color; ctx.lineWidth = 2;
                    if (el.shape === "square") ctx.strokeRect(el.x, el.y, el.width, el.height);
                    else if (el.shape === "circle") {
                        ctx.beginPath();
                        ctx.arc(el.x + el.width / 2, el.y + el.height / 2, el.width / 2, 0, Math.PI * 2);
                        ctx.stroke();
                    }
                }
            }
        }
        // Función para dibujar el canvas completo, incluyendo handles y resaltado por hover/selección
        function drawCustomCanvas(forceRedraw = false) {
            const rect = customCanvas.getBoundingClientRect();

            // Verificar si hay cambio de tamaño
            if (customCanvas.width !== rect.width || customCanvas.height !== rect.height || forceRedraw) {
                customCanvas.width = rect.width;
                customCanvas.height = rect.height;
            }

            ctx.clearRect(0, 0, customCanvas.width, customCanvas.height);
            customElements.forEach(el => { drawElement(el); });

            // Si hay un elemento hover (y no está seleccionado) se dibuja su borde en verde
            if (hoveredElement && hoveredElement !== selectedElement) {
                ctx.save();
                ctx.strokeStyle = "green";
                ctx.lineWidth = 2;
                if (hoveredElement.rotation && hoveredElement.rotation !== 0) {
                    const cx = hoveredElement.x + hoveredElement.width / 2;
                    const cy = hoveredElement.y + hoveredElement.height / 2;
                    ctx.translate(cx, cy);
                    ctx.rotate(hoveredElement.rotation);
                    ctx.strokeRect(-hoveredElement.width / 2, -hoveredElement.height / 2, hoveredElement.width, hoveredElement.height);
                } else {
                    ctx.strokeRect(hoveredElement.x, hoveredElement.y, hoveredElement.width, hoveredElement.height);
                }
                ctx.restore();
            }

            // Si hay un elemento seleccionado, dibujar borde verde, fondo semitransparente e indicadores
            if (selectedElement) {
                ctx.save();
                if (selectedElement.rotation && selectedElement.rotation !== 0) {
                    const cx = selectedElement.x + selectedElement.width / 2;
                    const cy = selectedElement.y + selectedElement.height / 2;
                    ctx.translate(cx, cy);
                    ctx.rotate(selectedElement.rotation);

                    // Fondo verde semitransparente y borde
                    ctx.fillStyle = "rgba(0,255,0,0.2)";
                    ctx.fillRect(-selectedElement.width / 2, -selectedElement.height / 2, selectedElement.width, selectedElement.height);
                    ctx.strokeStyle = "green";
                    ctx.lineWidth = 2;
                    ctx.strokeRect(-selectedElement.width / 2, -selectedElement.height / 2, selectedElement.width, selectedElement.height);

                    // Indicador de rotación (círculo verde con flecha)
                    ctx.beginPath();
                    ctx.arc(0, -selectedElement.height / 2 - 20, 8, 0, Math.PI * 2);
                    ctx.fillStyle = "green";
                    ctx.fill();
                    ctx.strokeStyle = "white";
                    ctx.lineWidth = 2;
                    // Dibujar flecha circular
                    ctx.beginPath();
                    ctx.arc(0, -selectedElement.height / 2 - 20, 12, -Math.PI / 2, Math.PI / 2, false);
                    ctx.stroke();
                    // Punta de la flecha
                    ctx.beginPath();
                    ctx.moveTo(4, -selectedElement.height / 2 - 20);
                    ctx.lineTo(8, -selectedElement.height / 2 - 24);
                    ctx.lineTo(12, -selectedElement.height / 2 - 20);
                    ctx.stroke();

                    // Indicador de redimensión (cuadrado verde)
                    ctx.fillStyle = "green";
                    ctx.fillRect(selectedElement.width / 2 - 8, selectedElement.height / 2 - 8, 16, 16);
                    ctx.strokeStyle = "white";
                    ctx.strokeRect(selectedElement.width / 2 - 8, selectedElement.height / 2 - 8, 16, 16);

                } else {
                    // Fondo verde semitransparente y borde
                    ctx.fillStyle = "rgba(0,255,0,0.2)";
                    ctx.fillRect(selectedElement.x, selectedElement.y, selectedElement.width, selectedElement.height);
                    ctx.strokeStyle = "green";
                    ctx.lineWidth = 2;
                    ctx.strokeRect(selectedElement.x, selectedElement.y, selectedElement.width, selectedElement.height);

                    // Indicador de rotación
                    ctx.beginPath();
                    ctx.arc(selectedElement.x + selectedElement.width / 2, selectedElement.y - 20, 8, 0, Math.PI * 2);
                    ctx.fillStyle = "green";
                    ctx.fill();
                    ctx.strokeStyle = "white";
                    ctx.lineWidth = 2;
                    // Dibujar flecha circular
                    ctx.beginPath();
                    ctx.arc(selectedElement.x + selectedElement.width / 2, selectedElement.y - 20, 12, -Math.PI / 2, Math.PI / 2, false);
                    ctx.stroke();
                    // Punta de la flecha
                    ctx.beginPath();
                    ctx.moveTo(selectedElement.x + selectedElement.width / 2 + 4, selectedElement.y - 20);
                    ctx.lineTo(selectedElement.x + selectedElement.width / 2 + 8, selectedElement.y - 24);
                    ctx.lineTo(selectedElement.x + selectedElement.width / 2 + 12, selectedElement.y - 20);
                    ctx.stroke();

                    // Indicador de redimensión
                    ctx.fillStyle = "green";
                    ctx.fillRect(selectedElement.x + selectedElement.width - 8, selectedElement.y + selectedElement.height - 8, 16, 16);
                    ctx.strokeStyle = "white";
                    ctx.strokeRect(selectedElement.x + selectedElement.width - 8, selectedElement.y + selectedElement.height - 8, 16, 16);
                }
                ctx.restore();
            }

            // Dibujar bordes azul dashed para multi-selección
            multiSelectedElements.forEach(el => {
                ctx.save();
                ctx.strokeStyle = "blue";
                ctx.lineWidth = 1;
                ctx.setLineDash([5, 5]);
                ctx.strokeRect(el.x, el.y, el.width, el.height);
                ctx.restore();
            });

            // Dibujar rectángulo de selección múltiple si está activo
            if (multiSelectRect) {
                ctx.save();
                ctx.strokeStyle = "blue";
                ctx.lineWidth = 1;
                ctx.setLineDash([5, 5]);
                const rx = Math.min(multiSelectRect.startX, multiSelectRect.currentX);
                const ry = Math.min(multiSelectRect.startY, multiSelectRect.currentY);
                const rw = Math.abs(multiSelectRect.currentX - multiSelectRect.startX);
                const rh = Math.abs(multiSelectRect.currentY - multiSelectRect.startY);
                ctx.strokeRect(rx, ry, rw, rh);
                ctx.restore();
            }
        }


        // Actualizar variable hoveredElement según la posición del mouse
        customCanvas.addEventListener("mousemove", (e) => {
            const rect = customCanvas.getBoundingClientRect();
            currentMousePos = { x: e.clientX - rect.left, y: e.clientY - rect.top };
            // Si no se está arrastrando, redimensionando, rotando o dibujando, detectar hover
            if (!isDragging && !isResizing && !isRotating && !drawingInProgress) {
                hoveredElement = null;
                for (let i = customElements.length - 1; i >= 0; i--) {
                    const el = customElements[i];
                    if (isPointInElement(el, currentMousePos.x, currentMousePos.y)) {
                        hoveredElement = el;
                        break;
                    }
                }
                drawCustomCanvas();
            }
        });

        // =============================
        // Eventos del canvas
        // =============================
        customCanvas.addEventListener("mousedown", (e) => {
            const rect = customCanvas.getBoundingClientRect();
            const x = e.clientX - rect.left, y = e.clientY - rect.top;
            // Si hay un elemento seleccionado, comprobar handle de rotación
            if (selectedElement) {
                const cx = selectedElement.x + selectedElement.width / 2;
                const cy = selectedElement.y + selectedElement.height / 2;
                const rot = selectedElement.rotation || 0;
                const handleOffset = { x: 0, y: -(selectedElement.height / 2 + 20) };
                const rx = cx + handleOffset.x * Math.cos(rot) - handleOffset.y * Math.sin(rot);
                const ry = cy + handleOffset.x * Math.sin(rot) + handleOffset.y * Math.cos(rot);
                if (distance({ x, y }, { x: rx, y: ry }) < 15) {
                    isRotating = true;
                    initialRotateAngle = Math.atan2(y - cy, x - cx);
                    initialElementRotation = selectedElement.rotation || 0;
                    return;
                }
                // Comprobar handle de resize
                const vectorBR = { x: selectedElement.width / 2, y: selectedElement.height / 2 };
                const brx = cx + vectorBR.x * Math.cos(rot) - vectorBR.y * Math.sin(rot);
                const bry = cy + vectorBR.x * Math.sin(rot) + vectorBR.y * Math.cos(rot);
                if (distance({ x, y }, { x: brx, y: bry }) < 15) {
                    isResizing = true;
                    resizeStartX = x; resizeStartY = y;
                    if (selectedElement.type === "text" || selectedElement.type === "emoji") {
                        originalWidth = selectedElement.width;
                        originalFontSize = selectedElement.fontSize;
                    } else {
                        originalWidth = selectedElement.width;
                        originalHeight = selectedElement.height;
                    }
                    return;
                }
            }
            if (isDrawingMode) {
                drawingInProgress = true;
                currentDrawing = { type: "drawing", points: [{ x, y }], color: drawingColor, brushSize: brushSizeInput.value, rotation: 0 };
                selectedElement = null;
            } else if (isMultiSelectMode) {
                let inSelected = multiSelectedElements.some(el => x >= el.x && x <= el.x + el.width && y >= el.y && y <= el.y + el.height);
                if (inSelected && multiSelectedElements.length > 0) {
                    isGroupDragging = true;
                    groupDragStart = { startX: x, startY: y, positions: multiSelectedElements.map(el => ({ x: el.x, y: el.y })) };
                } else {
                    multiSelectRect = { startX: x, startY: y, currentX: x, currentY: y };
                    multiSelectedElements = [];
                }
                selectedElement = null;
            } else {
                let found = false;
                for (let i = customElements.length - 1; i >= 0; i--) {
                    const el = customElements[i];
                    if (el.type === "drawing") {
                        const xs = el.points.map(p => p.x), ys = el.points.map(p => p.y);
                        const minX = Math.min(...xs), maxX = Math.max(...xs);
                        const minY = Math.min(...ys), maxY = Math.max(...ys);
                        if (x >= minX && x <= maxX && y >= minY && y <= maxY) { selectedElement = el; offsetX = x - minX; offsetY = y - minY; found = true; break; }
                    } else {
                        if (isPointInElement(el, x, y)) {
                            selectedElement = el;
                            if (x >= el.x + el.width - 15 && x <= el.x + el.width + 15 && y >= el.y + el.height - 15 && y <= el.y + el.height + 15) {
                                isResizing = true;
                                resizeStartX = x; resizeStartY = y;
                                if (el.type === "text" || el.type === "emoji") {
                                    originalWidth = el.width; originalFontSize = el.fontSize;
                                } else {
                                    originalWidth = el.width; originalHeight = el.height;
                                }
                            } else {
                                isDragging = true;
                                offsetX = x - el.x; offsetY = y - el.y;
                            }
                            found = true; break;
                        }
                    }
                }
                if (!found) { selectedElement = null; }
                drawCustomCanvas();
                updateTextEditorPanel();
            }
        });

        customCanvas.addEventListener("mousemove", (e) => {
            const rect = customCanvas.getBoundingClientRect();
            const x = e.clientX - rect.left, y = e.clientY - rect.top;
            currentMousePos = { x, y };
            // Si se está en modo rotación
            if (isRotating && selectedElement) {
                const cx = selectedElement.x + selectedElement.width / 2;
                const cy = selectedElement.y + selectedElement.height / 2;
                const currentAngle = Math.atan2(y - cy, x - cx);
                selectedElement.rotation = initialElementRotation + (currentAngle - initialRotateAngle);
                drawCustomCanvas();
                return;
            }
            if (isDrawingMode && drawingInProgress && currentDrawing) {
                currentDrawing.points.push({ x, y });
                drawCustomCanvas();
                ctx.strokeStyle = currentDrawing.color;
                ctx.lineWidth = currentDrawing.brushSize;
                ctx.lineJoin = "round"; ctx.lineCap = "round";
                ctx.beginPath();
                currentDrawing.points.forEach((point, index) => { index === 0 ? ctx.moveTo(point.x, point.y) : ctx.lineTo(point.x, point.y); });
                ctx.stroke();
            } else if (isMultiSelectMode) {
                if (isGroupDragging && groupDragStart) {
                    const deltaX = x - groupDragStart.startX, deltaY = y - groupDragStart.startY;
                    multiSelectedElements.forEach((el, idx) => {
                        const initPos = groupDragStart.positions[idx];
                        el.x = initPos.x + deltaX; el.y = initPos.y + deltaY;
                    });
                    drawCustomCanvas();
                } else if (multiSelectRect) {
                    multiSelectRect.currentX = x; multiSelectRect.currentY = y;
                    drawCustomCanvas();
                } else if (isDragging && selectedElement && !isDrawingMode && !isResizing && !isRotating) {
                    selectedElement.x = x - offsetX; selectedElement.y = y - offsetY;
                    drawCustomCanvas();
                }
            } else {
                if (isResizing && selectedElement) {
                    let newWidth = originalWidth + (x - resizeStartX);
                    if (newWidth < 20) newWidth = 20;
                    if (selectedElement.type === "text" || selectedElement.type === "emoji") {
                        let scale = newWidth / originalWidth;
                        selectedElement.fontSize = originalFontSize * scale;
                        selectedElement.width = newWidth;
                        selectedElement.height = originalFontSize * scale;
                    } else {
                        let newHeight = originalHeight + (y - resizeStartY);
                        if (newHeight < 20) newHeight = 20;
                        selectedElement.width = newWidth; selectedElement.height = newHeight;
                    }
                    drawCustomCanvas();
                } else if (isDragging && selectedElement && !isDrawingMode && !isResizing && !isRotating) {
                    selectedElement.x = x - offsetX; selectedElement.y = y - offsetY;
                    drawCustomCanvas();
                }
            }
            // Actualizar cursor sobre handles (para rotación y resize)
            if (!isDragging && !isResizing && !isRotating && selectedElement) {
                const cx = selectedElement.x + selectedElement.width / 2;
                const cy = selectedElement.y + selectedElement.height / 2;
                const rot = selectedElement.rotation || 0;
                const handleOffset = { x: 0, y: -(selectedElement.height / 2 + 20) };
                const rx = cx + handleOffset.x * Math.cos(rot) - handleOffset.y * Math.sin(rot);
                const ry = cy + handleOffset.x * Math.sin(rot) + handleOffset.y * Math.cos(rot);
                const vectorBR = { x: selectedElement.width / 2, y: selectedElement.height / 2 };
                const brx = cx + vectorBR.x * Math.cos(rot) - vectorBR.y * Math.sin(rot);
                const bry = cy + vectorBR.x * Math.sin(rot) + vectorBR.y * Math.cos(rot);
                if (distance({ x, y }, { x: rx, y: ry }) < 15) customCanvas.style.cursor = "grab";
                else if (distance({ x, y }, { x: brx, y: bry }) < 15) customCanvas.style.cursor = "nwse-resize";
                else customCanvas.style.cursor = "default";
            }
        });

        customCanvas.addEventListener("mouseup", () => {
            if (isDrawingMode && drawingInProgress && currentDrawing) {
                customElements.push(currentDrawing);
                saveHistory();
                currentDrawing = null; drawingInProgress = false;
            }
            if (isMultiSelectMode) {
                if (isGroupDragging) { isGroupDragging = false; groupDragStart = null; saveHistory(); }
                else if (multiSelectRect) {
                    const rx = Math.min(multiSelectRect.startX, multiSelectRect.currentX);
                    const ry = Math.min(multiSelectRect.startY, multiSelectRect.currentY);
                    const rw = Math.abs(multiSelectRect.currentX - multiSelectRect.startX);
                    const rh = Math.abs(multiSelectRect.currentY - multiSelectRect.startY);
                    multiSelectedElements = customElements.filter(el => (el.x >= rx && el.y >= ry && (el.x + el.width) <= (rx + rw) && (el.y + el.height) <= (ry + rh)));
                    multiSelectRect = null; drawCustomCanvas();
                }
            } else { if (isDragging || isResizing || isRotating) saveHistory(); }
            isResizing = false; isDragging = false; isRotating = false;
            drawCustomCanvas();
        });
        customCanvas.addEventListener("mouseleave", () => {
            if (isDrawingMode && drawingInProgress && currentDrawing) {
                customElements.push(currentDrawing); saveHistory();
                currentDrawing = null; drawingInProgress = false;
            }
            isResizing = false; isDragging = false; isGroupDragging = false; multiSelectRect = null; isRotating = false;
            drawCustomCanvas();
        });

        // =============================
        // Agregar imagen personalizada
        // =============================
        addCustomImageButton.addEventListener("click", () => customFileInput.click());
        customFileInput.addEventListener("change", () => {
            if (customFileInput.files && customFileInput.files[0]) {
                const file = customFileInput.files[0];
                const reader = new FileReader();
                reader.onload = function (event) {
                    const img = new Image();
                    img.onload = function () {
                        const size = getDefaultImageSize(img);
                        if (file.type === "image/gif") {
                            const element = { type: "image", isGif: true, originalBlob: file, img: new Image(), x: 50, y: 50, width: size.width, height: size.height, rotation: 0 };
                            element.img.src = URL.createObjectURL(file);
                            customElements.push(element);
                        } else {
                            const element = { type: "image", img: img, x: 50, y: 50, width: size.width, height: size.height, rotation: 0 };
                            customElements.push(element);
                        }
                        saveHistory(); drawCustomCanvas();
                    };
                    img.src = event.target.result;
                };
                reader.readAsDataURL(file);
            }
        });

        // =============================
        // Panel de emojis
        // =============================
        let currentCategory = 'faces_emotion';
        const emojiContainer = document.createElement("div");
        emojiContainer.id = "emojiContainer";
        const emojiCategoryContainer = document.createElement("div");
        emojiCategoryContainer.id = "emojiCategoryContainer";
        const btnEmotions = document.createElement("button");
        btnEmotions.textContent = "Emociones";
        const btnAnimals = document.createElement("button");
        btnAnimals.textContent = "Animales";
        btnEmotions.addEventListener("click", () => { currentCategory = 'faces_emotion'; loadEmojis(currentCategory); });
        btnAnimals.addEventListener("click", () => { currentCategory = 'animals'; loadEmojis(currentCategory); });
        emojiCategoryContainer.appendChild(btnEmotions);
        emojiCategoryContainer.appendChild(btnAnimals);
        const emojiContent = document.createElement("div");
        emojiContent.id = "emojiContent";
        emojiContainer.appendChild(emojiCategoryContainer);
        emojiContainer.appendChild(emojiContent);
        document.body.appendChild(emojiContainer);
        const emojiToggleButton = document.getElementById("openEmojiPanel");
        emojiToggleButton.addEventListener("click", () => {
            if (emojiContainer.style.display === "none" || emojiContainer.style.display === "") { emojiContainer.style.display = "flex"; loadEmojis(currentCategory); }
            else { emojiContainer.style.display = "none"; }
        });
        function loadEmojis(category) {
            emojiContent.innerHTML = "";
            const data = emojis[category];
            data.forEach(emojiData => {
                const btn = document.createElement("button");
                btn.textContent = emojiData.emoji;
                btn.style.fontSize = "24px"; btn.style.padding = "5px";
                btn.classList.add("addEmoji");
                btn.style.border = "1px solid #ccc"; btn.style.borderRadius = "5px";
                btn.style.cursor = "pointer"; btn.style.backgroundColor = "#f9f9f9";
                btn.addEventListener("click", () => {
                    const element = { type: "emoji", emoji: emojiData.emoji, x: 50, y: 50, fontSize: 70, width: 0, height: 0, rotation: 0 };
                    customElements.push(element); saveHistory(); drawCustomCanvas();
                });
                emojiContent.appendChild(btn);
            });
        }
        loadEmojis(currentCategory);

        // =============================
        // Configurar menú emergente del lápiz
        // =============================
        pencilColorContainer.innerHTML = "";
        const pencilColors = colorsText;
        pencilColors.forEach(color => {
            const btn = document.createElement("div");
            btn.className = "colorButton";
            btn.style.backgroundColor = color;
            btn.addEventListener("click", () => {
                drawingColor = color;
                Array.from(pencilColorContainer.children).forEach(b => b.style.borderColor = "#ccc");
                btn.style.borderColor = "#000";
            });
            pencilColorContainer.appendChild(btn);
        });
        pencilSizeContainer.innerHTML = "";
        const pencilSizes = [2, 4, 6, 8];
        pencilSizes.forEach(size => {
            const btn = document.createElement("div");
            btn.className = "sizeButton";
            btn.setAttribute("data-size", size);
            btn.style.backgroundColor = "#777";
            btn.addEventListener("click", () => {
                brushSizeInput.value = size;
                if (selectedElement && selectedElement.type === "drawing") {
                    selectedElement.brushSize = size; drawCustomCanvas();
                }
                Array.from(pencilSizeContainer.children).forEach(b => b.style.borderColor = "#ccc");
                btn.style.borderColor = "#000";
            });
            pencilSizeContainer.appendChild(btn);
        });
        // Toggle lápiz: ahora alterna entre activar y desactivar el modo dibujo
        toggleDrawingButton.addEventListener("click", () => {
            if (isDrawingMode) {
                isDrawingMode = false;
                pencilOptionsPanel.style.display = "none";
                toggleDrawingButton.style.backgroundColor = "#005c4b";
            } else {
                isDrawingMode = true;
                pencilOptionsPanel.style.display = "block";
                toggleDrawingButton.style.backgroundColor = "#ddd";
                // Si se activa el lápiz, desactivar modo formas
                shapeOptionsPanel.style.display = "none";
                selectedElement = null;
            }
        });

        // =============================
        // Configurar menú emergente para formas
        // =============================
        toggleShapesButton.addEventListener("click", () => {
            pencilOptionsPanel.style.display = "none";
            shapeOptionsPanel.style.display = (shapeOptionsPanel.style.display === "none" || shapeOptionsPanel.style.display === "") ? "block" : "none";
            toggleShapesButton.style.backgroundColor = shapeOptionsPanel.style.display === "block" ? "#ddd" : "#005c4b";
        });
        shapeSquareButton.addEventListener("click", () => {
            const element = { type: "shape", shape: "square", x: 50, y: 50, width: 100, height: 100, color: "#000000", rotation: 0 };
            customElements.push(element); saveHistory(); drawCustomCanvas();
        });
        shapeCircleButton.addEventListener("click", () => {
            const element = { type: "shape", shape: "circle", x: 50, y: 50, width: 100, height: 100, color: "#000000", rotation: 0 };
            customElements.push(element); saveHistory(); drawCustomCanvas();
        });

        // =============================
        // Configurar botón multi-select
        // =============================
        toggleMultiSelectButton.addEventListener("click", () => {
            isMultiSelectMode = !isMultiSelectMode;
            toggleMultiSelectButton.style.backgroundColor = isMultiSelectMode ? "#ddd" : "#005c4b";
            if (!isMultiSelectMode) { multiSelectedElements = []; drawCustomCanvas(); }
        });

        // =============================
        // Configurar edición de texto (botones de color)
        // =============================
        const textColors = colorsText;
        function populateColorButtons(container, callback) {
            container.innerHTML = "";
            textColors.forEach(color => {
                const btn = document.createElement("div");
                btn.className = "colorButton";
                btn.style.backgroundColor = color;
                btn.addEventListener("click", () => { callback(color); });
                container.appendChild(btn);
            });
        }
        populateColorButtons(textColorButtons, (color) => { if (selectedElement && selectedElement.type === "text") { selectedElement.color = color; drawCustomCanvas(); } });
        populateColorButtons(textBgButtons, (color) => { if (selectedElement && selectedElement.type === "text") { selectedElement.bgColor = color; drawCustomCanvas(); } });
        addTextButton.addEventListener("click", () => {
            const text = prompt("Enter the text:");
            if (text) {
                const element = { type: "text", text: text, x: 50, y: 50, fontSize: 30, width: 0, height: 0, color: "#000000", bgColor: "", rotation: 0 };
                customElements.push(element); saveHistory(); drawCustomCanvas();
            }
        });

        // =============================
        // Resto de controles: bringForward, sendBackward, etc.
        // =============================
        bringForwardButton.addEventListener("click", () => {
            if (selectedElement) {
                const idx = customElements.indexOf(selectedElement);
                if (idx !== -1 && idx < customElements.length - 1) { customElements.splice(idx, 1); customElements.push(selectedElement); saveHistory(); drawCustomCanvas(); }
            }
        });
        sendBackwardButton.addEventListener("click", () => {
            if (selectedElement) {
                const idx = customElements.indexOf(selectedElement);
                if (idx > 0) { customElements.splice(idx, 1); customElements.unshift(selectedElement); saveHistory(); drawCustomCanvas(); }
            }
        });
        deleteElementButton.addEventListener("click", () => {
            if (selectedElement) {
                const idx = customElements.indexOf(selectedElement);
                if (idx !== -1) { customElements.splice(idx, 1); selectedElement = null; saveHistory(); drawCustomCanvas(); }
            }
        });
        clearCanvasButton.addEventListener("click", () => { customElements = []; selectedElement = null; saveHistory(); drawCustomCanvas(); });
        downloadButton.addEventListener("click", () => {
            const dataURL = customCanvas.toDataURL("image/png");
            const a = document.createElement("a");
            a.href = dataURL; a.download = "sticker.png"; a.click();
        });
        undoButton.addEventListener("click", () => {
            if (historyIndex > 0) { historyIndex--; customElements = cloneCustomElements(history[historyIndex]); drawCustomCanvas(); }
        });
        redoButton.addEventListener("click", () => {
            if (historyIndex < history.length - 1) { historyIndex++; customElements = cloneCustomElements(history[historyIndex]); drawCustomCanvas(); }
        });

        // =============================
        // Panel de edición de texto: actualización en tiempo real
        // =============================
        function updateTextEditorPanel() {
            if (selectedElement && selectedElement.type === "text") {
                textEditorPanel.style.display = "block";
                textContentInput.value = selectedElement.text;
                textFontSelect.value = selectedElement.fontFamily || "";
                textFontSizeInput.value = selectedElement.fontSize;
            } else { textEditorPanel.style.display = "none"; }
        }
        textContentInput.addEventListener("input", () => { if (selectedElement && selectedElement.type === "text") { selectedElement.text = textContentInput.value; drawCustomCanvas(); } });
        textFontSelect.addEventListener("change", () => { if (selectedElement && selectedElement.type === "text") { selectedElement.fontFamily = textFontSelect.value; drawCustomCanvas(); } });
        textFontSizeInput.addEventListener("input", () => { if (selectedElement && selectedElement.type === "text") { selectedElement.fontSize = parseInt(textFontSizeInput.value); drawCustomCanvas(); } });

        // =============================
        // Animación: Si hay algún GIF, redibujar continuamente
        // =============================
        function animateCanvas() {
            if (customElements.some(el => el.type === "image" && el.isGif)) { drawCustomCanvas(); }
            requestAnimationFrame(animateCanvas);
        }
        animateCanvas();

        // =============================
        // Crear sticker personalizado
        // =============================
        createCustomStickerButton.addEventListener("click", () => {

            if (customCreateClicked) return;
            customCreateClicked = true;
            createCustomStickerButton.disabled = true;
            customStatus.textContent = "Generating custom sticker...";
            selectedElement = null;
            hoveredElement = null;
            multiSelectedElements = [];
            drawCustomCanvas();
            const gifElements = customElements.filter(el => el.type === "image" && el.isGif);
            if (gifElements.length === 1 && customElements.length === 1) {
                simulateWhatsAppFileUpload(gifElements[0].originalBlob, customStatus);
                customElements = []; selectedElement = null; drawCustomCanvas();
                createCustomStickerButton.disabled = false; customCreateClicked = false;
            } else {
                customCanvas.toBlob(function (blob) {
                    if (!blob) { customStatus.textContent = "Error generating sticker."; return; }
                    const stickerFile = new File([blob], "sticker_personalizado.webp", { type: "image/webp" });
                    simulateWhatsAppFileUpload(stickerFile, customStatus);
                    customElements = []; selectedElement = null; drawCustomCanvas();
                    createCustomStickerButton.disabled = false; customCreateClicked = false;
                }, "image/webp");
            }
        });
    }

    // =============================
    // Simulación de subida a WhatsApp
    // =============================
    function simulateWhatsAppFileUpload(file, statusElement) {
        openAttachmentMenu();
        setTimeout(() => {
            const waFileInput = document.querySelector("input[type='file'][accept*='image']");
            if (!waFileInput) { statusElement.textContent = "WhatsApp file input not found"; return; }
            const dt = new DataTransfer();
            dt.items.add(file);
            waFileInput.files = dt.files;
            const event = new Event("change", { bubbles: true });
            waFileInput.dispatchEvent(event);
            statusElement.textContent = "Sticker loaded. Sending...";
            setTimeout(() => {
                const sendButton = document.querySelector("span[data-icon='send']");
                if (sendButton) { sendButton.click(); statusElement.textContent = "Sticker send"; }
                else { statusElement.textContent = "Submit button not found"; }
            }, 1000);
        }, 500);
    }

    // =============================
    // Abrir menú de adjuntos de WhatsApp
    // =============================
    function openAttachmentMenu() {
        const attachmentButton = document.querySelector("div[title='Adjuntar']") || document.querySelector("span[data-icon='clip']");
        if (attachmentButton) { attachmentButton.click(); }
    }

    // Función auxiliar: distancia entre dos puntos
    function distance(p1, p2) {
        return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址