今天晚上摸鱼把一些网上的花火表情包搜集了一下,转化了一下表情包的尺寸大小,图床是用的是论坛官方图床,点击即可插入表情包,给论坛带来更多欢愉

|

使用演示 GIF

表情包示例

代码 复制全部内容,在油猴插件里新建脚本粘贴即可~

// ==UserScript==// @name         花火御用表情包面板 一键爆炸// @namespace    https://deepflood.com/// @version      0.1// @description  可自定义添加/删除表情,点击表情包直接插入并发送,带磨砂质感浮动面板与开关 + 发送提示// @author       Sparkle// @match        *://www.deepflood.com/*// @match        *://www.nodeseek.com/*// @grant        none// @icon         https://cdn.nodeimage.com/i/IEyH4NN7T0gzIj2GNDLEkMNfxi5e7S5R.png// ==/UserScript==(function () {    'use strict';    // 默认表情列表    const defaultEmojiList = [        "https://cdn.nodeimage.com/i/kiTPNRkkUMXrFbcqiQjInY997EXX8ugQ.png",        "https://cdn.nodeimage.com/i/yNwUePEGVy7u15Dav0dsnKe44c3YJvAK.gif",        "https://cdn.nodeimage.com/i/YtrI0qXlSjH1vjIVEPCIFrra7p93S9kn.webp",        "https://cdn.nodeimage.com/i/BAyT6QNxu41dsi2jLwmhfE2qaRiIxyY6.webp",        "https://cdn.nodeimage.com/i/p4NKizdYxK7YtdBjHmuYqaogU4QBYaUd.webp",        "https://cdn.nodeimage.com/i/vTcG6KHwda3ZzsWCYHxPIXI36cPvFgaR.avif",        "https://cdn.nodeimage.com/i/MdE5TIiLs1sogvre8Rc1TunNkROvwXbR.png",        "https://cdn.nodeimage.com/i/DLckJTHxmoTysBWShRGhXcmY3bmB56TG.png",        "https://cdn.nodeimage.com/i/rM7RVynnxChinGGZXXc1kzcJNaPsxx09.webp",        "https://cdn.nodeimage.com/i/nJj1NJMN3FrvCjiYxLjDGnnMQrOuodX0.webp",        "https://cdn.nodeimage.com/i/dI2NfaGlg4LMHsJJYbj6Deg7AvSrvfPW.webp",        "https://cdn.nodeimage.com/i/v8bbgwPmDhn8CJfRLoJfTExECZXY9cAJ.avif",        "https://cdn.nodeimage.com/i/s6yvTaNndMqSW2237VHvVaGbGUrtR482.avif",        "https://cdn.nodeimage.com/i/IqtoK3LNY6UH8F49SMH6PnrdHbJDxbL5.avif",        "https://cdn.nodeimage.com/i/EcfVbQVEhIQuhhZfz3GfmUbXbOugaTKs.avif",        "https://cdn.nodeimage.com/i/jjmCWuOeedjWFyUMI1tM9KDLpK0YzMuU.avif",        "https://cdn.nodeimage.com/i/d2Ybd1xx8ejNkfu7Rvv6YXHEEcj4dDuE.avif",        "https://cdn.nodeimage.com/i/a53uo9CgZlL78BqIResfFmVJSk6YSVpi.webp",        "https://cdn.nodeimage.com/i/2Jmuo2O6rd2BAwUv5IPnzrqOndF4GaXH.avif",        "https://cdn.nodeimage.com/i/aa5u2pyhmLgxiqNye1Bm600GdFgQwnoH.avif",        "https://cdn.nodeimage.com/i/sg1QIipECwsa0mVAXhGtDEUtrXz32I9j.avif",        "https://cdn.nodeimage.com/i/Z24cydZ2nUL5jYmIxYbx8PTCgHUYWHVk.avif",        "https://cdn.nodeimage.com/i/ixMkhZuRNt39ObpRpY5XTyNdyEpVenGh.avif",        "https://cdn.nodeimage.com/i/qJbzpaPkUflHQxf0aUszKZrEgQzta5jd.webp",        "https://cdn.nodeimage.com/i/Bjm9HjOzzaXTqNUWYx1yZexGs0lIN9so.webp",        "https://cdn.nodeimage.com/i/3TyPkkNXQ2iWsT2cuUBb5lqNEXkhQwMu.gif",        "https://cdn.nodeimage.com/i/Rs1eZBpod5QsSoV1kIv1husXtopA6AcI.png",        "https://cdn.nodeimage.com/i/Gy9MjsQyA7tW6kkRBux6Vurjw8tIuGAX.png",        "https://cdn.nodeimage.com/i/4dQT9ylVI51vzTvwdWAzZalZCOXS3RYc.png",        "https://cdn.nodeimage.com/i/5Z2V8HGqrFYzTdJDdoNAvIX4WQIQnBZz.png",        "https://cdn.nodeimage.com/i/yIdwRnUajcvuVOlHaO5647PdMcRua2yS.png",        "https://cdn.nodeimage.com/i/IEyH4NN7T0gzIj2GNDLEkMNfxi5e7S5R.png",        "https://cdn.nodeimage.com/i/Q05BMry7UbL1QzNAAr0b4CO1jwB7po5v.png",        "https://cdn.nodeimage.com/i/jCc6NDHOEP8AmpWifMkopF0w1vcNJVMC.png",        "https://cdn.nodeimage.com/i/cLmlEhOL5qv1r7UNW6MgRuYePyupd35k.png",        "https://cdn.nodeimage.com/i/5qP7UR9sOgTBVH63ZXf5pWPiMq18iTyK.png",        "https://cdn.nodeimage.com/i/43KwtgzDgaU2C91WXwp4ItBKHjsevHQE.png",        "https://cdn.nodeimage.com/i/mRtWtxLeHYXdhM4yXmKAvPAZlkTzHfSl.gif",        "https://cdn.nodeimage.com/i/Jrn7JvYVY7dAhQHMrQ0i2ixfaDDvxGYU.png"    ];    // --- 新增功能:全局变量 ---    const STORAGE_KEY = 'hanabi_custom_emojis';    let isDeleteMode = false;    let customEmojiList = [];    // --- 新增功能:本地存储操作 ---    function loadCustomEmojis() {        try {            const stored = localStorage.getItem(STORAGE_KEY);            return stored ? JSON.parse(stored) : [];        } catch (e) {            console.error("加载自定义表情失败", e);            return [];        }    }    function saveCustomEmojis(emojis) {        try {            localStorage.setItem(STORAGE_KEY, JSON.stringify(emojis));        } catch (e) {            console.error("保存自定义表情失败", e);        }    }    function findInputElement() {        const selectors = [            'textarea[name="message"]', 'textarea[placeholder*="输入"]', 'textarea[placeholder*="回复"]', 'textarea[placeholder*="说点什么"]',            'input[type="text"][name="message"]', 'input[type="text"][placeholder*="输入"]',            '.editor-input textarea', '.message-input textarea', '.chat-input textarea', '.reply-box textarea', '.comment-box textarea',            'textarea.form-control', 'textarea', 'input[type="text"]'        ];        for (const selector of selectors) {            const el = document.querySelector(selector);            if (el && !el.disabled && !el.readOnly && el.offsetWidth > 0 && el.offsetHeight > 0) return el;        }        const focused = document.activeElement;        return (focused && (focused.tagName === 'TEXTAREA' || (focused.tagName === 'INPUT' && focused.type === 'text'))) ? focused : null;    }    function insertTextAtCursor(el, text) {        if (!el) return false;        el.focus();        if (document.execCommand) document.execCommand('insertText', false, text);        else if (el.setRangeText) {            const s = el.selectionStart || 0, e = el.selectionEnd || 0;            el.setRangeText(text, s, e, 'end');        } else {            const s = el.selectionStart || el.value.length;            const before = el.value.substring(0, s);            const after = el.value.substring(el.selectionEnd || el.value.length);            el.value = before + text + after;            el.selectionStart = el.selectionEnd = s + text.length;        }        el.dispatchEvent(new Event('input', { bubbles: true }));        return true;    }    function showToast(msg) {        const toast = document.createElement("div");        toast.textContent = msg;        Object.assign(toast.style, {            position: "fixed", bottom: "90px", right: "20px", padding: "10px 20px", borderRadius: "12px",            background: "rgba(255,255,255,0.3)", backdropFilter: "blur(10px) saturate(180%)", color: "#fff",            fontWeight: "500", fontSize: "15px", boxShadow: "0 4px 12px rgba(0,0,0,0.2)", zIndex: "100000",            opacity: "0", transition: "opacity 0.3s ease, transform 0.3s ease", transform: "translateY(10px)"        });        document.body.appendChild(toast);        requestAnimationFrame(() => {            toast.style.opacity = "1";            toast.style.transform = "translateY(0)";        });        setTimeout(() => {            toast.style.opacity = "0";            toast.style.transform = "translateY(10px)";            setTimeout(() => toast.remove(), 300);        }, 1500);    }    // === 悬浮按钮 ===    const toggleBtn = document.createElement("img");    toggleBtn.src = "https://cdn.nodeimage.com/i/IEyH4NN7T0gzIj2GNDLEkMNfxi5e7S5R.png";    Object.assign(toggleBtn.style, {        position: "fixed", right: "15px", bottom: "15px", width: "60px", height: "60px", borderRadius: "50%",        cursor: "pointer", zIndex: "99998", background: "rgba(255,255,255,0.4)", backdropFilter: "blur(10px) saturate(180%)",        border: "1px solid rgba(255,255,255,0.5)", boxShadow: "0 4px 18px rgba(0,0,0,0.25)", transition: "transform 0.25s ease, box-shadow 0.25s ease"    });    toggleBtn.addEventListener("mouseenter", () => { toggleBtn.style.transform = "scale(1.1)"; toggleBtn.style.boxShadow = "0 6px 20px rgba(0,0,0,0.35)"; });    toggleBtn.addEventListener("mouseleave", () => { toggleBtn.style.transform = "scale(1)"; toggleBtn.style.boxShadow = "0 4px 18px rgba(0,0,0,0.25)"; });    document.body.appendChild(toggleBtn);    // === 主面板 ===    const panel = document.createElement("div");    panel.id = "emoji-panel";    Object.assign(panel.style, {        position: "fixed", right: "80px", bottom: "80px", width: "240px", height: "auto", maxHeight: "50vh", display: "flex", flexDirection: "column",        background: "rgba(255, 255, 255, 0.15)", border: "1px solid rgba(255, 255, 255, 0.4)", borderRadius: "16px",        backdropFilter: "blur(12px) saturate(180%)", boxShadow: "0 10px 30px rgba(0,0,0,0.25)", zIndex: "99999",        padding: "10px", color: "#222", display: "none", transition: "opacity 0.3s ease, transform 0.3s ease", transform: "translateY(10px)",    });    const style = document.createElement("style");    style.textContent = `      #emoji-panel * { box-sizing: border-box; }      #emoji-panel-grid::-webkit-scrollbar { width: 6px; }      #emoji-panel-grid::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.4); border-radius: 3px; }      #emoji-panel-grid::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.6); }      .emoji-item img:hover { transform: scale(1.08); box-shadow: 0 4px 10px rgba(0,0,0,0.2); }      /* 新增:删除模式样式 */      #emoji-panel.delete-mode .emoji-item[data-is-custom="true"] > img { border: 2px dashed #ff4757; opacity: 0.8; cursor: pointer; }      #emoji-panel.delete-mode .emoji-item[data-is-custom="true"]:hover > img { opacity: 1; box-shadow: 0 0 10px #ff4757; }      #emoji-panel.delete-mode .emoji-item:not([data-is-custom="true"]) { filter: grayscale(80%); opacity: 0.5; pointer-events: none; }      .control-button { background: rgba(255,255,255,0.3); border: none; padding: 4px 8px; font-size: 12px; border-radius: 6px; color: white; cursor: pointer; transition: background 0.2s ease; }      .control-button:hover { background: rgba(255,255,255,0.5); }    `;    document.head.appendChild(style);    const header = document.createElement("div");    Object.assign(header.style, { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "8px", color: "#fff", fontWeight: "600", textShadow: "0 1px 3px rgba(0,0,0,0.4)", cursor: "move", flexShrink: "0" });    header.innerHTML = `<span>🌸 花火表情包面板</span><span style="cursor:pointer;font-size:16px;">✖</span>`;    header.querySelector("span:last-child").onclick = () => { panel.style.display = "none"; };    panel.appendChild(header);    const grid = document.createElement("div");    grid.id = "emoji-panel-grid";    Object.assign(grid.style, { display: "flex", flexWrap: "wrap", justifyContent: "flex-start", overflowY: "auto", flexGrow: "1" });    panel.appendChild(grid);    // --- 新增功能:控制区 ---    const controls = document.createElement("div");    controls.style.marginTop = "8px";    controls.style.flexShrink = "0";    const urlInput = document.createElement("input");    Object.assign(urlInput.style, { width: "100%", padding: "6px", borderRadius: "6px", border: "1px solid rgba(255,255,255,0.4)", background: "rgba(0,0,0,0.1)", color: "white", marginBottom: "6px" });    urlInput.placeholder = "粘贴图片链接...";    const buttonContainer = document.createElement("div");    Object.assign(buttonContainer.style, { display: "flex", justifyContent: "space-between" });    const addButton = document.createElement("button");    addButton.textContent = "✓ 添加表情";    addButton.className = "control-button";    const deleteModeButton = document.createElement("button");    deleteModeButton.textContent = "🗑️ 删除模式";    deleteModeButton.className = "control-button";    buttonContainer.append(addButton, deleteModeButton);    controls.append(urlInput, buttonContainer);    panel.appendChild(controls);    document.body.appendChild(panel);    // --- 核心功能重构:渲染所有表情 ---    function renderEmojis() {        grid.innerHTML = ''; // 清空        const createEmojiItem = (url, isCustom) => {            const item = document.createElement("div");            item.className = "emoji-item";            if (isCustom) item.dataset.isCustom = "true";            const img = document.createElement("img");            img.src = url;            img.loading = "lazy";            Object.assign(img.style, { width: "64px", height: "64px", borderRadius: "10px", margin: "4px", objectFit: "cover", cursor: "pointer", transition: "transform 0.2s ease, box-shadow 0.2s ease" });            img.onclick = () => {                // 删除模式逻辑                if (isDeleteMode && isCustom) {                    if (confirm("确定要删除这个自定义表情吗?")) {                        customEmojiList = customEmojiList.filter(e => e !== url);                        saveCustomEmojis(customEmojiList);                        renderEmojis();                        showToast("🗑️ 表情已删除!");                    }                    return;                }                // 发送模式逻辑                const markdown = ` ![emote](${url}) `;                const input = findInputElement();                if (input && insertTextAtCursor(input, markdown)) {                    setTimeout(() => {                        const enterEvent = new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true, cancelable: true });                        input.dispatchEvent(enterEvent);                    }, 50);                    showToast("✨ 表情包已发送!");                }            };            item.appendChild(img);            grid.appendChild(item);        };        defaultEmojiList.forEach(url => createEmojiItem(url, false));        customEmojiList.forEach(url => createEmojiItem(url, true));    }    // --- 新增功能:按钮事件监听 ---    addButton.onclick = () => {        const url = urlInput.value.trim();        if (!url || !url.startsWith('http')) {            showToast("❌ 请输入有效的图片链接!");            return;        }        if (customEmojiList.includes(url)) {            showToast("😅 这个表情已经添加过啦!");            return;        }        customEmojiList.push(url);        saveCustomEmojis(customEmojiList);        renderEmojis();        urlInput.value = '';        showToast("✅ 自定义表情已添加!");        grid.scrollTop = grid.scrollHeight; // 滚动到底部    };    deleteModeButton.onclick = () => {        isDeleteMode = !isDeleteMode;        panel.classList.toggle('delete-mode', isDeleteMode);        deleteModeButton.textContent = isDeleteMode ? "✓ 完成删除" : "🗑️ 删除模式";        deleteModeButton.style.background = isDeleteMode ? "rgba(255, 71, 87, 0.5)" : "rgba(255,255,255,0.3)";    };    toggleBtn.onclick = () => {        const show = panel.style.display === "none" || !panel.style.display;        panel.style.display = show ? "flex" : "none";        panel.style.opacity = show ? "1" : "0";        panel.style.transform = show ? "translateY(0)" : "translateY(10px)";        // 退出时,自动关闭删除模式        if (!show && isDeleteMode) {            isDeleteMode = false;            panel.classList.remove('delete-mode');            deleteModeButton.textContent = "🗑️ 删除模式";            deleteModeButton.style.background = "rgba(255,255,255,0.3)";        }    };    // --- 初始化 ---    customEmojiList = loadCustomEmojis();    renderEmojis();    console.log("🌸 花火表情包面板 已加载");})();