B站表情展示器

在阳光沙滩网站上显示B站表情图片和名称

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         B站表情展示器
// @namespace    https://github.com/anjiemo
// @version      1.0.5
// @description  在阳光沙滩网站上显示B站表情图片和名称
// @author       anjiemo
// @match        *://*.sunofbeach.net/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_setClipboard
// @grant        GM_xmlhttpRequest
// @license      Apache-2.0
// @connect      gitee.com
// ==/UserScript==
 
(function() {
    'use strict';
 
    // 添加样式
    GM_addStyle(`
        .bemoji-floating-panel {
            position: fixed;
            top: 100px;
            right: 20px;
            width: 600px;
            background: white;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            z-index: 10000;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
            overflow: hidden;
            resize: both;
            max-width: 90vw;
            max-height: 80vh;
        }
 
        .bemoji-panel-header {
            background: linear-gradient(135deg, #FB7299 0%, #FFB6C1 100%);
            color: white;
            padding: 15px;
            cursor: move;
            display: flex;
            justify-content: space-between;
            align-items: center;
            user-select: none;
        }
 
        .bemoji-panel-title {
            font-size: 18px;
            font-weight: bold;
        }
 
        .bemoji-panel-controls {
            display: flex;
            gap: 10px;
        }
 
        .bemoji-panel-btn {
            background: rgba(255, 255, 255, 0.2);
            border: none;
            color: white;
            width: 30px;
            height: 30px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            font-size: 16px;
            transition: all 0.3s;
        }
 
        .bemoji-panel-btn:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: scale(1.1);
        }
 
        .bemoji-panel-content {
            padding: 15px;
            max-height: 500px;
            overflow-y: auto;
        }
 
        .bemoji-search-container {
            margin-bottom: 15px;
        }
 
        .bemoji-search-input {
            width: 100%;
            padding: 10px 15px;
            border: 1px solid #ddd;
            border-radius: 25px;
            font-size: 14px;
            outline: none;
            transition: all 0.3s;
        }
 
        .bemoji-search-input:focus {
            border-color: #FB7299;
            box-shadow: 0 0 0 2px rgba(251, 114, 153, 0.2);
        }
 
        .bemoji-grid {
            display: grid;
            grid-template-columns: repeat(7, 1fr);
            gap: 12px;
        }
 
        .bemoji-item {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 10px 5px;
            text-align: center;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 90px;
        }
 
        .bemoji-item:hover {
            background: #e9ecef;
            transform: translateY(-3px);
            box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
        }
 
        .bemoji-img {
            width: 32px;
            height: 32px;
            object-fit: contain;
            margin-bottom: 8px;
        }
 
        .bemoji-text {
            font-size: 12px;
            color: #555;
            word-break: break-word;
            line-height: 1.2;
            max-width: 100%;
            overflow: hidden;
            text-overflow: ellipsis;
        }
 
        .bemoji-count {
            text-align: center;
            margin: 15px 0;
            color: #6c757d;
            font-size: 14px;
        }
 
        .bemoji-loading {
            text-align: center;
            padding: 20px;
            color: #6c757d;
        }
 
        .bemoji-notification {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #28a745;
            color: white;
            padding: 12px 20px;
            border-radius: 5px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
            z-index: 10001;
            opacity: 0;
            transition: opacity 0.3s;
        }
 
        .bemoji-notification.show {
            opacity: 1;
        }
 
        .bemoji-item.copied {
            background-color: #d4edda;
            border: 1px solid #c3e6cb;
        }
 
        .bemoji-toggle-btn {
            position: fixed;
            width: 50px;
            height: 50px;
            background: linear-gradient(135deg, #FB7299 0%, #FFB6C1 100%);
            color: white;
            border: none;
            border-radius: 50%;
            font-size: 20px;
            cursor: move;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
            z-index: 9999;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s;
            user-select: none;
        }
 
        .bemoji-toggle-btn:hover {
            transform: scale(1.1);
            background: linear-gradient(135deg, #FFB6C1 0%, #FB7299 100%);
        }
 
        @media (max-width: 700px) {
            .bemoji-floating-panel {
                width: 90vw;
                right: 5vw;
            }
            .bemoji-grid {
                grid-template-columns: repeat(4, 1fr);
            }
        }
 
        @media (max-width: 480px) {
            .bemoji-grid {
                grid-template-columns: repeat(3, 1fr);
            }
        }
    `);
 
    // 表情数据 - 名称和图片URL映射
    const bilibiliEmojis = [
        { name: "微笑", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default001.png" },
        { name: "呲牙", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f601.png" },
        { name: "OK", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f44c.png" },
        { name: "星星眼", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f929.png" },
        { name: "哦呼", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default005.png" },
        { name: "歪嘴", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f60f.png" },
        { name: "嫌弃", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f612.png" },
        { name: "喜欢", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f60d.png" },
        { name: "酸了", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f34b.png" },
        { name: "大哭", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f62d.png" },
        { name: "害羞", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f60a.png" },
        { name: "疑惑", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default012.png" },
        { name: "辣眼睛", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default013.png" },
        { name: "调皮", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f61b.png" },
        { name: "喜极而泣", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f602.png" },
        { name: "奸笑", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default016.png" },
        { name: "笑", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f642.png" },
        { name: "偷笑", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f92d.png" },
        { name: "大笑", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f604.png" },
        { name: "阴险", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default020.png" },
        { name: "捂脸", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f926.png" },
        { name: "囧", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default022.png" },
        { name: "呆", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f633.png" },
        { name: "抠鼻", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default024.png" },
        { name: "惊喜", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f61d.png" },
        { name: "惊讶", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f632.png" },
        { name: "笑哭", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default027.png" },
        { name: "妙啊", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default028.png" },
        { name: "doge", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f436.png" },
        { name: "滑稽", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default030.png" },
        { name: "吃瓜", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f349.png" },
        { name: "打call", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f64c.png" },
        { name: "点赞", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default033.png" },
        { name: "鼓掌", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f44f.png" },
        { name: "无语", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f611.png" },
        { name: "尴尬", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default036.png" },
        { name: "冷", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f976.png" },
        { name: "灵魂出窍", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f47b.png" },
        { name: "委屈", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f622.png" },
        { name: "傲娇", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default040.png" },
        { name: "疼", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default041.png" },
        { name: "吓", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f631.png" },
        { name: "生病", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f912.png" },
        { name: "吐", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f92e.png" },
        { name: "嘘声", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f92b.png" },
        { name: "捂眼", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f648.png" },
        { name: "思考", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f914.png" },
        { name: "再见", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f44b.png" },
        { name: "翻白眼", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f644.png" },
        { name: "哈欠", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f971.png" },
        { name: "奋斗", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default051.png" },
        { name: "墨镜", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f60e.png" },
        { name: "难过", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f641.png" },
        { name: "撇嘴", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f61f.png" },
        { name: "抓狂", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f62b.png" },
        { name: "生气", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f621.png" },
        { name: "口罩", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f637.png" },
        { name: "月饼", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f96e.png" },
        { name: "视频卫星", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f6f0.png" },
        { name: "11周年", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f4fa.png" },
        { name: "鸡腿", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f357.png" },
        { name: "干杯", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f37b.png" },
        { name: "爱心", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/2764.png" },
        { name: "锦鲤", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default064.png" },
        { name: "胜利", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/270c.png" },
        { name: "加油", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f4aa.png" },
        { name: "保佑", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f64f.png" },
        { name: "抱拳", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default068.png" },
        { name: "响指", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default069.png" },
        { name: "支持", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f44d.png" },
        { name: "拥抱", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1fac2.png" },
        { name: "怪我咯", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f937-200d-2640-fe0f.png" },
        { name: "跪了", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f9ce.png" },
        { name: "黑洞", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default074.png" },
        { name: "老鼠", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/1f439.png" },
        { name: "2020", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default076.png" },
        { name: "福到了", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default077.png" },
        { name: "高兴", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default078.png" },
        { name: "气愤", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default079.png" },
        { name: "耍帅", url: "https://gitee.com/anjiemo/figure-bed/raw/master/emoji/bilibili/default080.png" }
    ];
 
    // 创建浮动面板
    function createFloatingPanel() {
        // 检查是否已存在面板
        if (document.getElementById('bemoji-floating-panel')) {
            return;
        }
 
        // 创建面板
        const panel = document.createElement('div');
        panel.id = 'bemoji-floating-panel';
        panel.className = 'bemoji-floating-panel';
 
        // 从存储中获取位置
        const savedPosition = GM_getValue('bemojiPanelPosition', {
            top: '100px',
            right: '20px'
        });
        if (savedPosition.top) panel.style.top = savedPosition.top;
        if (savedPosition.left) panel.style.left = savedPosition.left;
        if (savedPosition.right) panel.style.right = savedPosition.right;
 
        // 面板头部
        const header = document.createElement('div');
        header.className = 'bemoji-panel-header';
 
        const title = document.createElement('div');
        title.className = 'bemoji-panel-title';
        title.textContent = 'B站表情包';
 
        const controls = document.createElement('div');
        controls.className = 'bemoji-panel-controls';
 
        const minimizeBtn = document.createElement('button');
        minimizeBtn.className = 'bemoji-panel-btn';
        minimizeBtn.innerHTML = '−';
        minimizeBtn.title = '最小化';
 
        const closeBtn = document.createElement('button');
        closeBtn.className = 'bemoji-panel-btn';
        closeBtn.innerHTML = '×';
        closeBtn.title = '关闭';
 
        controls.appendChild(minimizeBtn);
        controls.appendChild(closeBtn);
 
        header.appendChild(title);
        header.appendChild(controls);
 
        // 面板内容
        const content = document.createElement('div');
        content.className = 'bemoji-panel-content';
 
        // 搜索框
        const searchContainer = document.createElement('div');
        searchContainer.className = 'bemoji-search-container';
 
        const searchInput = document.createElement('input');
        searchInput.type = 'text';
        searchInput.className = 'bemoji-search-input';
        searchInput.placeholder = '搜索表情...';
 
        searchContainer.appendChild(searchInput);
        content.appendChild(searchContainer);
 
        // 表情数量
        const countElement = document.createElement('div');
        countElement.className = 'bemoji-count';
        content.appendChild(countElement);
 
        // 表情网格
        const emojiGrid = document.createElement('div');
        emojiGrid.className = 'bemoji-grid';
        content.appendChild(emojiGrid);
 
        // 组装面板
        panel.appendChild(header);
        panel.appendChild(content);
        document.body.appendChild(panel);
 
        // 创建通知元素
        const notification = document.createElement('div');
        notification.className = 'bemoji-notification';
        notification.textContent = '表情已复制到剪贴板!';
        document.body.appendChild(notification);
 
        // 显示表情
        displayEmojis(bilibiliEmojis, emojiGrid, countElement);
 
        // 搜索功能
        searchInput.addEventListener('input', function() {
            const searchTerm = this.value.toLowerCase();
            const filteredEmojis = bilibiliEmojis.filter(emoji => 
                emoji.name.toLowerCase().includes(searchTerm)
            );
            displayEmojis(filteredEmojis, emojiGrid, countElement);
        });
 
        // 关闭按钮事件
        closeBtn.addEventListener('click', function() {
            document.body.removeChild(panel);
            document.body.removeChild(notification);
            toggleBtn.style.display = 'flex';
        });
 
        // 最小化按钮事件
        minimizeBtn.addEventListener('click', function() {
            content.style.display = content.style.display === 'none' ? 'block' : 'none';
        });
 
        // 拖拽功能(带边界限制)
        makeElementDraggableWithBoundary(panel, header, 'bemojiPanelPosition');
 
        return panel;
    }
 
    // 显示表情函数
    // 在 displayEmojis 函数中修改图片创建部分
    function displayEmojis(emojisToShow, container, countElement) {
        container.innerHTML = '';
        countElement.textContent = `共${emojisToShow.length}个表情`;
    
        if (emojisToShow.length === 0) {
            container.innerHTML = '<div class="bemoji-loading">未找到匹配的表情</div>';
            return;
        }
    
        emojisToShow.forEach(emoji => {
            const emojiItem = document.createElement('div');
            emojiItem.className = 'bemoji-item';
            emojiItem.title = `点击复制: [${emoji.name}]`;
    
            const emojiImg = document.createElement('img');
            emojiImg.className = 'bemoji-img';
            emojiImg.alt = emoji.name;
            
            // 使用 GM_xmlhttpRequest 加载图片
            loadImageWithGM(emoji.url, emojiImg);
    
            const emojiText = document.createElement('div');
            emojiText.className = 'bemoji-text';
            emojiText.textContent = emoji.name;
    
            emojiItem.appendChild(emojiImg);
            emojiItem.appendChild(emojiText);
    
            // 点击复制功能
            emojiItem.addEventListener('click', function() {
                copyToClipboard(`[${emoji.name}]`);
                emojiItem.classList.add('copied');
                setTimeout(() => {
                    emojiItem.classList.remove('copied');
                }, 500);
                showNotification();
            });
    
            container.appendChild(emojiItem);
        });
    }
 
    // 复制到剪贴板函数
    function copyToClipboard(text) {
        // 优先使用GM_setClipboard,如果不可用则回退到传统方法
        if (typeof GM_setClipboard !== 'undefined') {
            GM_setClipboard(text);
        } else {
            const textarea = document.createElement('textarea');
            textarea.value = text;
            document.body.appendChild(textarea);
            textarea.select();
            document.execCommand('copy');
            document.body.removeChild(textarea);
        }
    }
 
    // 显示通知函数
    function showNotification() {
        const notification = document.querySelector('.bemoji-notification');
        if (notification) {
            notification.classList.add('show');
            setTimeout(() => {
                notification.classList.remove('show');
            }, 2000);
        }
    }
 
 // 添加新的图片加载函数
 function loadImageWithGM(imageUrl, imgElement) {
     if (typeof GM_xmlhttpRequest !== 'undefined') {
         GM_xmlhttpRequest({
             method: 'GET',
             url: imageUrl,
             responseType: 'blob',
             onload: function(response) {
                 const blob = response.response;
                 const blobUrl = URL.createObjectURL(blob);
                 imgElement.src = blobUrl;
                 
                 // 添加加载完成的回调处理
                 imgElement.onload = function() {
                     // 图片加载完成后释放 blob URL
                     URL.revokeObjectURL(blobUrl);
                 };
             },
             onerror: function(error) {
                 console.error('图片加载失败:', error);
                 // 失败时回退到原始URL
                 imgElement.src = imageUrl;
             }
         });
     } else {
         // 如果 GM_xmlhttpRequest 不可用,直接使用原始URL
         imgElement.src = imageUrl;
     }
 }
 
    // 使元素可拖拽(带边界限制)
    function makeElementDraggableWithBoundary(element, handle, storageKey) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
 
        handle.onmousedown = dragMouseDown;
 
        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            // 获取鼠标初始位置
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }
 
        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            // 计算新位置
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
 
            // 计算新位置
            let newTop = element.offsetTop - pos2;
            let newLeft = element.offsetLeft - pos1;
 
            // 边界限制
            newTop = Math.max(0, Math.min(newTop, window.innerHeight - element.offsetHeight));
            newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - element.offsetWidth));
 
            // 设置元素新位置
            element.style.top = newTop + "px";
            element.style.left = newLeft + "px";
            element.style.right = "auto";
 
            // 保存位置到存储
            if (storageKey) {
                GM_setValue(storageKey, {
                    top: element.style.top,
                    left: element.style.left,
                    right: element.style.right
                });
            }
        }
 
        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }
 
    // 创建切换按钮
    const toggleBtn = document.createElement('button');
    toggleBtn.className = 'bemoji-toggle-btn';
    toggleBtn.innerHTML = '😊';
    toggleBtn.title = '显示/隐藏B站表情面板';
    document.body.appendChild(toggleBtn);
 
    // 添加初始位置和显示样式
    toggleBtn.style.position = 'fixed';
    toggleBtn.style.top = '100px';
    toggleBtn.style.right = '20px';
    toggleBtn.style.display = 'flex';
 
    // 拖拽逻辑(仅限切换按钮)
    function makeButtonDraggable(button) {
        let isDragging = false;
        let startX, startY, initialX, initialY;
        let animationFrameId = null;
 
        button.addEventListener('mousedown', startDrag);
 
        function startDrag(e) {
            // 阻止默认行为,避免文本选中
            e.preventDefault();
            e.stopPropagation();
 
            isDragging = false;
            button.isDragging = true;
 
            // 获取初始位置
            startX = e.clientX;
            startY = e.clientY;
            initialX = button.offsetLeft;
            initialY = button.offsetTop;
 
            // 添加拖动样式
            button.style.opacity = '0.9';
            button.style.cursor = 'grabbing';
            button.style.transition = 'none';
            document.addEventListener('mousemove', onDrag);
            document.addEventListener('mouseup', stopDrag);
 
            // 阻止鼠标事件冒泡
            document.addEventListener('click', preventClickDuringDrag, true);
        }
 
        function onDrag(e) {
            if (!isDragging) {
                isDragging = true;
            }
 
            if (animationFrameId) {
                cancelAnimationFrame(animationFrameId);
            }
 
            animationFrameId = requestAnimationFrame(() => {
                const dx = e.clientX - startX;
                const dy = e.clientY - startY;
 
                let newLeft = initialX + dx;
                let newTop = initialY + dy;
 
                const margin = 5;
                newTop = Math.max(margin, Math.min(newTop, window.innerHeight - button.offsetHeight - margin));
                newLeft = Math.max(margin, Math.min(newLeft, window.innerWidth - button.offsetWidth - margin));
 
                button.style.left = newLeft + 'px';
                button.style.top = newTop + 'px';
                button.style.right = 'auto';
            });
        }
 
        function stopDrag(e) {
            if (animationFrameId) {
                cancelAnimationFrame(animationFrameId);
                animationFrameId = null;
            }
 
            document.removeEventListener('mousemove', onDrag);
            document.removeEventListener('mouseup', stopDrag);
            document.removeEventListener('click', preventClickDuringDrag, true);
 
            button.style.opacity = '1';
            button.style.cursor = 'move';
            button.style.transition = 'all 0.2s ease';
            button.isDragging = false;
 
            saveButtonPosition();
 
            if (isDragging) {
                e.preventDefault();
                e.stopPropagation();
                setTimeout(() => {
                    isDragging = false;
                }, 50);
            }
        }
 
        function preventClickDuringDrag(e) {
            if (isDragging) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();
            }
        }
 
        function saveButtonPosition() {
            const position = {
                left: button.style.left,
                top: button.style.top
            };
            localStorage.setItem('bemojiToggleBtnPosition', JSON.stringify(position));
        }
 
        function loadButtonPosition() {
            const saved = localStorage.getItem('bemojiToggleBtnPosition');
            if (saved) {
                try {
                    const position = JSON.parse(saved);
                    if (position.left) button.style.left = position.left;
                    if (position.top) button.style.top = position.top;
                    button.style.right = 'auto';
                } catch(e) {
                    console.log('加载按钮位置失败:', e);
                }
            }
        }
 
        setTimeout(loadButtonPosition, 100);
 
        button.addEventListener('click', (e) => {
            if (isDragging) {
                e.preventDefault();
                e.stopPropagation();
                return;
            }
 
            if (!panel || !document.body.contains(panel)) {
                panel = createFloatingPanel();
                button.style.display = 'none';
            } else {
                panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
            }
        });
    }
 
    // 应用优化的拖拽功能到切换按钮
    makeButtonDraggable(toggleBtn);
 
    let panel = null;
})();