卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
微件
查看“︁TierListMaker”︁的源代码
←
微件:TierListMaker
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您没有权限编辑
微件
命名空间内的页面。
您可以查看和复制此页面的源代码。
<includeonly> <style> .tierlist-controls { display: flex; gap: 8px; margin: 8px 0 12px 0; } .btn { display: inline-block; padding: 6px 12px; background: #f0f0f0; border: 1px solid #ccc; color: #333; border-radius: 4px; cursor: pointer; user-select: none; } .btn:hover { background: #e6e6e6; } .btn.primary { background: #4a8cf6; color: #fff; border-color: #3b78de; } .btn.primary:hover { background: #3b78de; } .tierlist-table { width: 100%; table-layout: fixed; } .tier-row .tier-head { position: relative; width: 120px; color: #fff; text-align: center; font-size: 18px; font-weight: bold; padding: 8px; white-space: nowrap; border: 1px solid #ccc; background: #555; } .tier-row .tier-cell { border: 1px solid #ccc; padding: 6px; } .tier-tools { position: absolute; right: 6px; top: 6px; display: flex; gap: 6px; } .color-toggle { width: 18px; height: 18px; border-radius: 3px; border: 1px solid rgba(0,0,0,0.2); cursor: pointer; background: rgba(255,255,255,0.6); } .delete-row { font-size: 12px; padding: 2px 6px; border-radius: 3px; background: rgba(0,0,0,0.1); cursor: pointer; } .delete-row:hover { background: rgba(0,0,0,0.2); } .tier-dropzone { min-height: 112px; display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; } .tier-dropzone.pool { border: 2px dashed #ccc; padding: 8px; border-radius: 6px; background: #fafafa; } .pool-wrapper { margin-top: 12px; } .pool-header { font-weight: bold; margin-bottom: 6px; } .avatar-frame { position: relative; display: inline-block; vertical-align: top; border: 3px solid #ccc; border-radius: 5px; overflow: hidden; box-shadow: 0 2px 5px rgba(0,0,0,0.1); background: #f5f5f5; transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; cursor: move; } .avatar-frame.dragging { opacity: 0.7; transform: scale(1.03); border-color: #4a8cf6; z-index: 10; } .avatar-frame img { display: block; width: 100px; height: 100px; object-fit: cover; pointer-events: none; -webkit-user-drag: none; } .avatar-name { position: absolute; left: 0; bottom: 0; padding: 2px 8px; color: white; font-size: 12px; font-weight: bold; text-shadow: 0 0 2px black, 0 0 2px black; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; border-top-right-radius: 3px; } .color-palette { position: absolute; display: none; gap: 6px; flex-wrap: wrap; width: 210px; padding: 8px; background: #fff; border: 1px solid #ccc; box-shadow: 0 2px 8px rgba(0,0,0,0.15); border-radius: 6px; z-index: 9999; } .color-swatch { width: 24px; height: 24px; border-radius: 4px; border: 1px solid rgba(0,0,0,0.2); cursor: pointer; } .color-swatch:hover { outline: 2px solid rgba(0,0,0,0.2); } .tier-label { display: inline-block; padding: 2px 6px; border-radius: 3px; background: rgba(255,255,255,0.15); } .tier-label[contenteditable="true"] { outline: none; cursor: text; } .exporting .tier-dropzone.pool { border: 0; background: transparent; } </style> <script> (function() { function ready(fn) { if (document.readyState !== 'loading') fn(); else document.addEventListener('DOMContentLoaded', fn); } function contrastColor(hex) { hex = hex.replace('#',''); if (hex.length === 3) hex = hex.split('').map(c => c + c).join(''); var r = parseInt(hex.substr(0,2), 16); var g = parseInt(hex.substr(2,2), 16); var b = parseInt(hex.substr(4,2), 16); var yiq = ((r*299)+(g*587)+(b*114))/1000; return yiq >= 128 ? '#000' : '#fff'; } function getDragAfterElement(container, y) { const elements = [...container.querySelectorAll('.avatar-frame:not(.dragging)')]; return elements.reduce((closest, child) => { const box = child.getBoundingClientRect(); const offset = y - box.top - box.height/2; if (offset < 0 && offset > closest.offset) { return { offset: offset, element: child }; } else { return closest; } }, { offset: Number.NEGATIVE_INFINITY, element: null }).element; } function makeDraggable(avatar) { avatar.setAttribute('draggable', 'true'); avatar.classList.add('draggable-avatar'); avatar.addEventListener('dragstart', function(e) { avatar.classList.add('dragging'); e.dataTransfer.setData('text/plain', avatar.dataset.id || avatar.querySelector('.avatar-name')?.textContent || ''); // allow move effect e.dataTransfer.effectAllowed = 'move'; }); avatar.addEventListener('dragend', function() { avatar.classList.remove('dragging'); }); } function initAvatars(root) { const avatars = root.querySelectorAll('.avatar-frame'); avatars.forEach(function(av) { // Ensure data attributes exist if (!av.dataset.id) { const nameEl = av.querySelector('.avatar-name'); av.dataset.name = nameEl ? nameEl.textContent.trim() : ''; } makeDraggable(av); }); } function initDropzone(zone) { zone.addEventListener('dragover', function(e) { e.preventDefault(); const afterElement = getDragAfterElement(zone, e.clientY); const dragging = document.querySelector('.avatar-frame.dragging'); if (!dragging) return; if (afterElement == null) { zone.appendChild(dragging); } else { zone.insertBefore(dragging, afterElement); } }); zone.addEventListener('drop', function(e) { e.preventDefault(); const dragging = document.querySelector('.avatar-frame.dragging'); if (dragging && dragging.parentNode !== zone) { zone.appendChild(dragging); } }); } function buildEditableHead(th) { const currentText = (th.childNodes[0] && th.childNodes[0].nodeType === 3) ? th.childNodes[0].nodeValue.trim() : th.textContent.trim(); const tools = th.querySelector('.tier-tools'); th.innerHTML = ''; const label = document.createElement('div'); label.className = 'tier-label'; label.setAttribute('contenteditable', 'true'); label.textContent = currentText || '未命名'; const toolsWrap = tools || (function() { const t = document.createElement('div'); t.className = 'tier-tools'; const color = document.createElement('div'); color.className = 'color-toggle'; const del = document.createElement('div'); del.className = 'delete-row'; del.textContent = '删除'; t.appendChild(color); t.appendChild(del); return t; })(); th.appendChild(label); th.appendChild(toolsWrap); // initial colors const initialBg = th.getAttribute('data-initial-bg') || 'gray'; const fg = contrastColor(initialBg); th.style.background = initialBg; th.style.color = fg; // color palette attachColorPalette(toolsWrap.querySelector('.color-toggle'), th); // delete handler const delBtn = toolsWrap.querySelector('.delete-row'); delBtn.addEventListener('click', function() { const tr = th.closest('tr'); const dropzone = tr.querySelector('.tier-dropzone'); const pool = document.getElementById('character-pool'); // move items back to pool Array.from(dropzone.querySelectorAll('.avatar-frame')).forEach(function(av) { pool.appendChild(av); }); tr.parentNode.removeChild(tr); }); } function attachColorPalette(toggle, th) { const palette = document.createElement('div'); palette.className = 'color-palette'; const colors = [ '#e53935','#d81b60','#8e24aa','#5e35b1','#3949ab','#1e88e5','#039be5','#00acc1', '#00897b','#43a047','#7cb342','#c0ca33','#fdd835','#fb8c00','#f4511e','#6d4c41', '#546e7a','#9e9e9e','#000000','#ffffff' ]; colors.forEach(function(c) { const sw = document.createElement('div'); sw.className = 'color-swatch'; sw.style.background = c; sw.addEventListener('click', function(e) { th.style.background = c; th.style.color = contrastColor(c); palette.style.display = 'none'; }); palette.appendChild(sw); }); document.body.appendChild(palette); function placePalette() { const rect = toggle.getBoundingClientRect(); palette.style.left = (window.scrollX + rect.left) + 'px'; palette.style.top = (window.scrollY + rect.bottom + 6) + 'px'; } toggle.addEventListener('click', function() { if (palette.style.display === 'block') { palette.style.display = 'none'; } else { placePalette(); palette.style.display = 'block'; } }); document.addEventListener('click', function(e) { if (e.target === toggle || palette.contains(e.target)) return; palette.style.display = 'none'; }); window.addEventListener('scroll', function() { if (palette.style.display === 'block') placePalette(); }); window.addEventListener('resize', function() { if (palette.style.display === 'block') placePalette(); }); } function addNewRow() { const tbody = document.querySelector('#tierlist-table tbody'); const tr = document.createElement('tr'); tr.className = 'tier-row'; const th = document.createElement('th'); th.className = 'tier-head'; th.setAttribute('data-initial-bg', '#8888ff'); th.setAttribute('data-initial-fg', 'white'); th.textContent = '新行'; const td = document.createElement('td'); td.className = 'tier-cell'; const dz = document.createElement('div'); dz.className = 'tier-dropzone'; dz.setAttribute('data-tier', 'CUSTOM'); td.appendChild(dz); tr.appendChild(th); tr.appendChild(td); tbody.appendChild(tr); initDropzone(dz); buildEditableHead(th); } function ensureHtml2Canvas(cb) { if (window.html2canvas) { cb(); return; } var s = document.createElement('script'); s.src = 'https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js'; s.onload = cb; s.onerror = function() { alert('加载截图库失败,请检查网络或跨域策略。'); }; document.body.appendChild(s); } function savePNG() { const table = document.getElementById('tierlist-table'); document.getElementById('tierlist-maker').classList.add('exporting'); ensureHtml2Canvas(function() { // Use higher scale for sharper image html2canvas(table, {backgroundColor: null, scale: 2}).then(function(canvas) { const link = document.createElement('a'); link.href = canvas.toDataURL('image/png'); link.download = 'tierlist.png'; document.body.appendChild(link); link.click(); document.body.removeChild(link); document.getElementById('tierlist-maker').classList.remove('exporting'); }).catch(function() { document.getElementById('tierlist-maker').classList.remove('exporting'); alert('保存PNG失败。'); }); }); } ready(function() { // Initialize table heads editable and with tools document.querySelectorAll('#tierlist-table .tier-head').forEach(buildEditableHead); // Initialize dropzones document.querySelectorAll('.tier-dropzone').forEach(initDropzone); // Initialize avatars in pool initAvatars(document.getElementById('character-pool')); // Controls document.getElementById('add-row').addEventListener('click', addNewRow); document.getElementById('save-png').addEventListener('click', savePNG); // If avatars are loaded later (SMW), observe mutations to init new avatars const pool = document.getElementById('character-pool'); const obs = new MutationObserver(function(muts) { muts.forEach(function(m) { if (m.addedNodes && m.addedNodes.length) { m.addedNodes.forEach(function(n) { if (n.nodeType === 1) { if (n.classList.contains('avatar-frame')) makeDraggable(n); // Also init any nested avatar frames n.querySelectorAll && n.querySelectorAll('.avatar-frame').forEach(makeDraggable); } }); } }); }); obs.observe(pool, { childList: true, subtree: true }); }); })(); </script> </includeonly>
返回
微件:TierListMaker
。