MediaWiki

MediaWiki:Gadget-TierListMaker.js

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献2025年10月6日 (一) 17:17的版本 (创建页面,内容为“* * 战斗员图鉴分级表制作工具 * 支持拖放卡片到表格并导出为PNG:​ (function() { 'use strict'; // 仅在特定页面启用 if (mw.config.get('wgPageName') !== '节奏榜') { return; } // 等待页面加载完成 mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() { init(); }); function init() { // 添加控制按钮 addControlPanel();…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
/**
 * 战斗员图鉴分级表制作工具
 * 支持拖放卡片到表格并导出为PNG
 */
(function() {
    'use strict';

    // 仅在特定页面启用
    if (mw.config.get('wgPageName') !== '节奏榜') {
        return;
    }

    // 等待页面加载完成
    mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() {
        init();
    });

    function init() {
        // 添加控制按钮
        addControlPanel();
        
        // 使卡片可拖动
        makeCardsDraggable();
        
        // 使表格单元格可接收
        makeTableDroppable();
        
        // 添加样式
        addStyles();
    }

    function addControlPanel() {
        var $panel = $('<div>')
            .attr('id', 'tierlist-control-panel')
            .css({
                'position': 'fixed',
                'top': '100px',
                'right': '20px',
                'z-index': '9999',
                'background': '#fff',
                'border': '2px solid #0645ad',
                'border-radius': '8px',
                'padding': '15px',
                'box-shadow': '0 4px 6px rgba(0,0,0,0.1)',
                'min-width': '200px'
            });

        var $title = $('<h3>')
            .text('分级表工具')
            .css({
                'margin': '0 0 10px 0',
                'font-size': '16px',
                'color': '#0645ad'
            });

        var $exportBtn = $('<button>')
            .text('📸 导出为PNG')
            .css({
                'width': '100%',
                'padding': '10px',
                'margin': '5px 0',
                'background': '#0645ad',
                'color': '#fff',
                'border': 'none',
                'border-radius': '4px',
                'cursor': 'pointer',
                'font-size': '14px'
            })
            .hover(
                function() { $(this).css('background', '#0b5394'); },
                function() { $(this).css('background', '#0645ad'); }
            )
            .click(exportToPNG);

        var $clearBtn = $('<button>')
            .text('🗑️ 清空表格')
            .css({
                'width': '100%',
                'padding': '10px',
                'margin': '5px 0',
                'background': '#d33',
                'color': '#fff',
                'border': 'none',
                'border-radius': '4px',
                'cursor': 'pointer',
                'font-size': '14px'
            })
            .hover(
                function() { $(this).css('background', '#a00'); },
                function() { $(this).css('background', '#d33'); }
            )
            .click(clearTable);

        var $toggleBtn = $('<button>')
            .text('👁️ 切换编辑模式')
            .attr('id', 'toggle-edit-mode')
            .css({
                'width': '100%',
                'padding': '10px',
                'margin': '5px 0',
                'background': '#36c',
                'color': '#fff',
                'border': 'none',
                'border-radius': '4px',
                'cursor': 'pointer',
                'font-size': '14px'
            })
            .hover(
                function() { $(this).css('background', '#258'); },
                function() { $(this).css('background', '#36c'); }
            )
            .click(toggleEditMode);

        var $info = $('<div>')
            .css({
                'margin-top': '10px',
                'padding': '10px',
                'background': '#f8f9fa',
                'border-radius': '4px',
                'font-size': '12px',
                'color': '#666'
            })
            .html('<strong>使用说明:</strong><br>1. 拖动卡片到表格<br>2. 右键点击可删除<br>3. 导出前切换预览');

        $panel.append($title, $exportBtn, $clearBtn, $toggleBtn, $info);
        $('body').append($panel);
    }

    function makeCardsDraggable() {
        $('.战斗员卡片').each(function() {
            var $card = $(this);
            
            $card.attr('draggable', 'true')
                .css('cursor', 'move')
                .on('dragstart', function(e) {
                    var cardHTML = $card[0].outerHTML;
                    e.originalEvent.dataTransfer.setData('text/html', cardHTML);
                    e.originalEvent.dataTransfer.effectAllowed = 'copy';
                    $card.css('opacity', '0.5');
                })
                .on('dragend', function() {
                    $card.css('opacity', '1');
                });
        });
    }

    function makeTableDroppable() {
        $('.wikitable td').each(function() {
            var $cell = $(this);
            
            $cell.addClass('tierlist-dropzone')
                .css({
                    'min-height': '280px',
                    'vertical-align': 'top',
                    'padding': '10px',
                    'position': 'relative'
                })
                .on('dragover', function(e) {
                    e.preventDefault();
                    e.originalEvent.dataTransfer.dropEffect = 'copy';
                    $cell.addClass('drag-over');
                })
                .on('dragleave', function() {
                    $cell.removeClass('drag-over');
                })
                .on('drop', function(e) {
                    e.preventDefault();
                    $cell.removeClass('drag-over');
                    
                    var cardHTML = e.originalEvent.dataTransfer.getData('text/html');
                    if (cardHTML) {
                        var $newCard = $(cardHTML);
                        $newCard.addClass('placed-card')
                            .css('margin', '5px')
                            .on('contextmenu', function(e) {
                                e.preventDefault();
                                if (confirm('确定要删除这张卡片吗?')) {
                                    $newCard.remove();
                                }
                            })
                            .on('dblclick', function() {
                                if (confirm('确定要删除这张卡片吗?')) {
                                    $newCard.remove();
                                }
                            });
                        
                        $cell.append($newCard);
                        makeCardsDraggable(); // 重新启用新卡片的拖动
                    }
                });
        });
    }

    function toggleEditMode() {
        $('body').toggleClass('tierlist-preview-mode');
        var isPreview = $('body').hasClass('tierlist-preview-mode');
        $('#toggle-edit-mode').text(isPreview ? '✏️ 切换编辑模式' : '👁️ 切换预览模式');
        
        if (isPreview) {
            $('.placed-card').css('pointer-events', 'none');
            $('#tierlist-control-panel').fadeOut();
        } else {
            $('.placed-card').css('pointer-events', 'auto');
            $('#tierlist-control-panel').fadeIn();
        }
    }

    function clearTable() {
        if (confirm('确定要清空表格中的所有卡片吗?此操作不可撤销!')) {
            $('.wikitable .placed-card').remove();
        }
    }

    function exportToPNG() {
        var $btn = $('#tierlist-control-panel button').eq(0);
        $btn.prop('disabled', true).text('正在生成...');

        // 加载 html2canvas 库
        if (typeof html2canvas === 'undefined') {
            mw.loader.load('https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js', 'text/javascript');
            
            var checkLoaded = setInterval(function() {
                if (typeof html2canvas !== 'undefined') {
                    clearInterval(checkLoaded);
                    performExport($btn);
                }
            }, 100);
        } else {
            performExport($btn);
        }
    }

    function performExport($btn) {
        var $table = $('.wikitable').first();
        
        // 临时隐藏控制面板
        var $panel = $('#tierlist-control-panel');
        $panel.hide();
        
        // 进入预览模式
        var wasPreview = $('body').hasClass('tierlist-preview-mode');
        if (!wasPreview) {
            $('body').addClass('tierlist-preview-mode');
        }

        html2canvas($table[0], {
            backgroundColor: '#ffffff',
            scale: 2,
            logging: false,
            useCORS: true,
            allowTaint: true
        }).then(function(canvas) {
            // 恢复界面
            $panel.show();
            if (!wasPreview) {
                $('body').removeClass('tierlist-preview-mode');
            }
            
            // 下载图片
            var link = document.createElement('a');
            var timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
            link.download = '战斗员分级表_' + timestamp + '.png';
            link.href = canvas.toDataURL('image/png');
            link.click();
            
            $btn.prop('disabled', false).text('📸 导出为PNG');
            
            mw.notify('分级表已成功导出!', { type: 'success' });
        }).catch(function(error) {
            console.error('导出失败:', error);
            $panel.show();
            $btn.prop('disabled', false).text('📸 导出为PNG');
            mw.notify('导出失败,请查看控制台了解详情', { type: 'error' });
        });
    }

    function addStyles() {
        var styles = `
            .tierlist-dropzone {
                transition: background-color 0.3s;
            }
            
            .tierlist-dropzone.drag-over {
                background-color: #e6f3ff !important;
                border: 2px dashed #0645ad !important;
            }
            
            .placed-card {
                transition: transform 0.2s, box-shadow 0.2s;
            }
            
            .placed-card:hover {
                transform: scale(1.05);
                box-shadow: 0 4px 8px rgba(0,0,0,0.2);
                z-index: 10;
            }
            
            .tierlist-preview-mode .placed-card {
                pointer-events: none;
            }
            
            .tierlist-preview-mode .placed-card:hover {
                transform: none;
                box-shadow: none;
            }
            
            @media print {
                #tierlist-control-panel {
                    display: none !important;
                }
            }
        `;
        
        $('<style>').text(styles).appendTo('head');
    }

})();