MediaWiki:Gadget-TierListMaker.js
来自卡厄思梦境WIKI
注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-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');
}
})();