微件

TierListMaker:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
无编辑摘要
律Rhyme留言 | 贡献
无编辑摘要
 
(未显示同一用户的10个中间版本)
第1行: 第1行:
<includeonly>
<includeonly>
<style>
<style>
.avatar-frame {
.tierlist-controls {
    position: relative;
  display: flex;
    display: inline-block;
  gap: 8px;
    vertical-align: top;
  margin: 8px 0 12px 0;
    border: 3px solid #ccc;
}
    border-radius: 5px;
.btn {
    overflow: hidden;
  display: inline-block;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);  
  padding: 6px 12px;
    background: #f5f5f5;
  background: #f0f0f0;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
  border: 1px solid #ccc;
    cursor: move;
  color: #333;
    margin: 2px;
  border-radius: 4px;
  cursor: pointer;
  user-select: none;
}
}
.avatar-frame:hover {
.btn:hover { background: #e6e6e6; }
    transform: scale(1.05);
.btn.primary { background: #4a8cf6; color: #fff; border-color: #3b78de; }
    box-shadow: 0 4px 8px rgba(0,0,0,0.2);
.btn.primary:hover { background: #3b78de; }
    z-index: 10;
.tierlist-table {
  width: 100%;
  table-layout: fixed;
}
}
.avatar-frame.dragging {
.tier-row .tier-head {
    opacity: 0.5;
  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;
}
}
.avatar-frame img {
.tier-row .tier-cell {
    display: block;
  border: 1px solid #ccc;
    width: 100px;
  padding: 0px;
    height: 100px;
    object-fit: cover;
    pointer-events: none;
}
}
.avatar-name {
.tier-tools {
    position: absolute;
  position: absolute;
    left: 0;
  right: 6px;
    bottom: 0;
  top: 6px;
    padding: 2px 8px;
  display: flex;
    color: white;
  gap: 6px;
    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;
    pointer-events: none;
}
}
.tier-content {
/* 导出时隐藏工具按钮 */
    min-height: 120px;
.exporting .tier-tools {
    transition: background-color 0.3s;
  display: none !important;
}
}
.tier-content.drag-over {
.color-toggle {
    background-color: #e3f2fd !important;
  width: 18px;
    border: 2px dashed #2196F3;
  height: 18px;
  border-radius: 3px;
  border: 1px solid rgba(0,0,0,0.2);
  cursor: pointer;
  background: rgba(255,255,255,0.6);
}
}
.tier-header {
.delete-row {
    position: relative;
  font-size: 12px;
    user-select: none;
  padding: 2px 6px;
  border-radius: 3px;
  background: rgba(0,0,0,0.1);
  cursor: pointer;
}
}
.tier-label {
.delete-row:hover { background: rgba(0,0,0,0.2); }
    display: inline-block;
.tier-dropzone {
    padding: 5px;
  min-height: 112px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: flex-start;
  padding: 4px;
}
}
.tier-label:focus {
.tier-dropzone.pool {
    outline: 2px solid white;
  border: 2px dashed #ccc;
    outline-offset: -2px;
  padding: 8px;
  border-radius: 6px;
  background: #fafafa;
}
}
.color-picker-trigger {
/* 导出时隐藏角色池 */
    position: absolute;
.exporting .pool-wrapper {
    top: 5px;
  display: none !important;
    right: 5px;
    font-size: 16px;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.3s;
}
}
.color-picker-trigger:hover {
.pool-wrapper { margin-top: 12px; }
    opacity: 1;
.pool-header {
  font-weight: bold;
  margin-bottom: 6px;
}
}
.control-button:hover {
.avatar-frame {
    opacity: 0.9;
  position: relative;
    transform: translateY(-1px);
  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;
}
}
.control-button:active {
.avatar-frame.dragging {
    transform: translateY(0);
  opacity: 0.7;
  transform: scale(1.03);
  border-color: #4a8cf6;
  z-index: 10;
}
}
#tierlist-table {
.avatar-frame img {
    border: 2px solid #ddd;
  display: block;
  width: 100px;
  height: 100px;
  object-fit: cover;
  pointer-events: none;
  -webkit-user-drag: none;
}
}
.tier-remove-btn {
.avatar-name {
    position: absolute;
  position: absolute;
    top: 5px;
  left: 0;
    left: 5px;
  bottom: 0;
    background: #f44336;
  padding: 2px 8px;
    color: white;
  color: white;
    border-radius: 3px;
  font-size: 12px;
    padding: 2px 6px;
  font-weight: bold;
    font-size: 12px;
  text-shadow: 0 0 2px black, 0 0 2px black;
    cursor: pointer;
  white-space: nowrap;
    opacity: 0.7;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  border-top-right-radius: 3px;
}
}
.tier-remove-btn:hover {
.color-palette {
    opacity: 1;
  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;
}
}
</style>
</style>


<script>
<script>
let draggedElement = null;
(function() {
let currentEditingTier = null;
  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('');
    if (!/^[0-9a-fA-F]{6}$/.test(hex)) return '#fff';
    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 ensureCrossOrigin(img) {
    try {
      if (!img) return;
      if (!img.crossOrigin) img.crossOrigin = 'anonymous';
      if (!img.referrerPolicy) img.referrerPolicy = 'no-referrer';
    } catch(e) {}
  }
  function makeDraggable(avatar) {
    if (!avatar || avatar._draggableInit) return;
    avatar._draggableInit = true;
    avatar.setAttribute('draggable', 'true');
    avatar.classList.add('draggable-avatar');
    avatar.querySelectorAll('img').forEach(ensureCrossOrigin);


// 默认层级配置
     avatar.addEventListener('dragstart', function(e) {
const defaultTiers = [
      avatar.classList.add('dragging');
     { label: 'S', bgColor: '#ff4444', textColor: '#ffffff' },
      avatar._prevParent = avatar.parentNode;
    { label: 'A', bgColor: '#ff9800', textColor: '#ffffff' },
      e.dataTransfer.setData('text/plain', avatar.dataset.id || avatar.querySelector('.avatar-name')?.textContent || '');
    { label: 'B', bgColor: '#ffeb3b', textColor: '#000000' },
      e.dataTransfer.effectAllowed = 'move';
     { label: 'C', bgColor: '#8bc34a', textColor: '#ffffff' },
     });
     { label: 'D', bgColor: '#2196F3', textColor: '#ffffff' }
     avatar.addEventListener('dragend', function() {
];
      avatar.classList.remove('dragging');
 
      cleanupEmptyWrapper(avatar._prevParent);
// 初始化拖拽功能
      avatar._prevParent = null;
function initDragAndDrop() {
    });
     const avatars = document.querySelectorAll('.avatar-frame');
  }
     const tierContents = document.querySelectorAll('.tier-content');
  function initAvatars(root) {
   
     if (!root) return;
     avatars.forEach(avatar => {
     const avatars = root.querySelectorAll('.avatar-frame');
        avatar.setAttribute('draggable', 'true');
     avatars.forEach(function(av) {
       
      if (!av.dataset.id) {
        avatar.addEventListener('dragstart', function(e) {
        const nameEl = av.querySelector('.avatar-name');
            draggedElement = this;
        av.dataset.name = nameEl ? nameEl.textContent.trim() : '';
            this.classList.add('dragging');
      }
            e.dataTransfer.effectAllowed = 'move';
      makeDraggable(av);
            e.dataTransfer.setData('text/html', this.outerHTML);
        });
       
        avatar.addEventListener('dragend', function(e) {
            this.classList.remove('dragging');
        });
     });
     });
   
  }
    tierContents.forEach(content => {
  function cleanupEmptyWrapper(node) {
        content.addEventListener('dragover', function(e) {
    if (!node || node.nodeType !== 1) return;
            e.preventDefault();
    if (node.classList && node.classList.contains('tier-dropzone')) return;
            e.dataTransfer.dropEffect = 'move';
    const hasElementChild = node.querySelector('.avatar-frame');
            this.classList.add('drag-over');
    const onlyWhitespace = !node.textContent || node.textContent.trim().length === 0;
        });
    if (!hasElementChild && node.childElementCount === 0 && onlyWhitespace) {
       
      node.parentNode && node.parentNode.removeChild(node);
        content.addEventListener('dragleave', function(e) {
    }
            this.classList.remove('drag-over');
  }
        });
  function cleanupEmptyPlaceholdersIn(container) {
       
    if (!container) return;
        content.addEventListener('drop', function(e) {
    Array.from(container.children).forEach(function(child) {
            e.preventDefault();
      if (child.nodeType !== 1) return;
            this.classList.remove('drag-over');
      if (child.classList.contains('avatar-frame')) return;
           
      const hasAvatarInside = !!child.querySelector('.avatar-frame');
            if (draggedElement) {
      const onlyWhitespace = !child.textContent || child.textContent.trim().length === 0;
                this.appendChild(draggedElement);
      if (!hasAvatarInside && child.childElementCount === 0 && onlyWhitespace) {
                draggedElement = null;
         child.remove();
            }
      }
         });
     });
     });
}
  }
  function initDropzone(zone) {
    if (!zone || zone._dropzoneInit) return;
    zone._dropzoneInit = true;


// 添加新行
     zone.addEventListener('dragover', function(e) {
function addNewTier() {
      e.preventDefault();
     const table = document.getElementById('tierlist-table');
      e.dataTransfer.dropEffect = 'move';
    const tbody = table.querySelector('tbody');
      const afterElement = getDragAfterElement(zone, e.clientY);
    const tierCount = document.querySelectorAll('.tier-header').length;
      const dragging = document.querySelector('.avatar-frame.dragging');
   
      if (!dragging) return;
    const newRow = tbody.insertRow(-1);
      if (afterElement == null) {
   
        if (dragging.parentNode !== zone) zone.appendChild(dragging);
    const headerCell = newRow.insertCell(0);
      } else {
    headerCell.className = 'tier-header';
        if (afterElement !== dragging) zone.insertBefore(dragging, afterElement);
    headerCell.setAttribute('data-tier', tierCount);
      }
    headerCell.style = 'width: 100px; background-color: #9e9e9e; color: white; font-size: 20px; text-align: center; cursor: pointer; position: relative;';
     });
    headerCell.innerHTML = '<div class="tier-label" contenteditable="true">新行</div><div class="color-picker-trigger" onclick="showColorPicker(this, ' + tierCount + ')">🎨</div><div class="tier-remove-btn" onclick="removeTier(this)">删除</div>';
   
    const contentCell = newRow.insertCell(1);
    contentCell.className = 'tier-content';
    contentCell.setAttribute('data-tier', tierCount);
    contentCell.style = 'min-height: 120px; padding: 10px; background: #fff;';
      
    initDragAndDrop();
}


// 删除行
    zone.addEventListener('drop', function(e) {
function removeTier(btn) {
      e.preventDefault();
     if (confirm('确定要删除这一行吗?')) {
      e.stopPropagation();
         const row = btn.closest('tr');
      const dragging = document.querySelector('.avatar-frame.dragging');
         row.remove();
      if (dragging) {
        if (dragging.parentNode !== zone) zone.appendChild(dragging);
        cleanupEmptyWrapper(dragging._prevParent);
        dragging._prevParent = null;
      }
      if (zone.classList.contains('pool')) {
        cleanupEmptyPlaceholdersIn(zone);
      }
    });
  }
  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';
      color.title = '更改颜色';
      const del = document.createElement('div');
      del.className = 'delete-row';
      del.textContent = '删除';
      del.title = '删除该行';
      t.appendChild(color); t.appendChild(del);
      return t;
    })();
    th.appendChild(label);
    th.appendChild(toolsWrap);
    const initialBg = th.getAttribute('data-initial-bg') || '#555';
    th.style.background = initialBg;
    th.style.color = contrastColor(initialBg);
    attachColorPalette(toolsWrap.querySelector('.color-toggle'), th);
    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');
      Array.from(dropzone.querySelectorAll('.avatar-frame')).forEach(function(av) {
        pool.appendChild(av);
      });
      tr.parentNode.removeChild(tr);
    });
  }
  function attachColorPalette(toggle, th) {
     if (!toggle) return;
    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() {
         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(e) {
      e.stopPropagation();
      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') || document.querySelector('#tierlist-table');
    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.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 downloadCanvas(canvas) {
    function done(blobOrUrl) {
      try {
        const link = document.createElement('a');
        const isBlob = blobOrUrl instanceof Blob;
        const url = isBlob ? (URL.createObjectURL(blobOrUrl)) : blobOrUrl;
         link.href = url;
        link.download = 'tierlist.png';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        if (isBlob) setTimeout(() => URL.revokeObjectURL(url), 0);
      } catch (e) {
        const dataUrl = canvas.toDataURL('image/png');
        window.open(dataUrl, '_blank');
      }
    }
    if (canvas.toBlob) {
      canvas.toBlob(function(blob) {
        if (blob) done(blob);
        else done(canvas.toDataURL('image/png'));
      }, 'image/png');
    } else {
      done(canvas.toDataURL('image/png'));
     }
     }
}
  }
 
  function prepareImagesForExport(container) {
// 重置功能
    if (!container) return;
function resetTierList() {
    container.querySelectorAll('img').forEach(ensureCrossOrigin);
     if (!confirm('确定要重置吗?所有角色将返回角色池,自定义行将被删除。')) {
  }
        return;
  function savePNG() {
    const maker = document.getElementById('tierlist-maker');
    const table = document.getElementById('tierlist-table');
     if (!table) {
      alert('未找到要导出的表格。');
      return;
     }
     }
      
      
     const characterPool = document.getElementById('character-pool');
     // 添加导出样式类
     const table = document.getElementById('tierlist-table');
     maker.classList.add('exporting');
     const tbody = table.querySelector('tbody');
     prepareImagesForExport(table);
      
      
     // 收集所有角色
     ensureHtml2Canvas(function() {
    const allAvatars = document.querySelectorAll('.tier-content .avatar-frame');
      // 稍微延迟以确保CSS生效
    allAvatars.forEach(avatar => {
      setTimeout(function() {
        characterPool.appendChild(avatar);
        html2canvas(table, {
          backgroundColor: '#ffffff',
          scale: 2,
          useCORS: true,
          allowTaint: false,
          imageTimeout: 15000
        }).then(function(canvas) {
          downloadCanvas(canvas);
        }).catch(function(err) {
          console.error('html2canvas 失败', err);
          alert('保存PNG失败:' + (err && err.message ? err.message : '未知错误'));
        }).finally(function() {
          maker.classList.remove('exporting');
        });
      }, 100);
     });
     });
   
  }
    // 清空表格
  function resetAll() {
     tbody.innerHTML = '';
     const pool = document.getElementById('character-pool');
      
     if (!pool) return;
    // 重建默认行
    const rows = document.querySelectorAll('#tierlist-table .tier-dropzone');
    defaultTiers.forEach((tier, index) => {
    rows.forEach(function(zone) {
        const newRow = tbody.insertRow(-1);
      if (zone.classList.contains('pool')) return;
       
      Array.from(zone.querySelectorAll('.avatar-frame')).forEach(function(av) {
        const headerCell = newRow.insertCell(0);
         pool.appendChild(av);
        headerCell.className = 'tier-header';
      });
        headerCell.setAttribute('data-tier', index);
      cleanupEmptyPlaceholdersIn(zone);
        headerCell.style = `width: 100px; background-color: ${tier.bgColor}; color: ${tier.textColor}; font-size: 20px; text-align: center; cursor: pointer; position: relative;`;
        headerCell.innerHTML = `<div class="tier-label" contenteditable="true">${tier.label}</div><div class="color-picker-trigger" onclick="showColorPicker(this, ${index})">🎨</div>`;
       
         const contentCell = newRow.insertCell(1);
        contentCell.className = 'tier-content';
        contentCell.setAttribute('data-tier', index);
        contentCell.style = 'min-height: 120px; padding: 10px; background: #fff;';
     });
     });
      
     cleanupEmptyPlaceholdersIn(pool);
    initDragAndDrop();
  }
}
 
// 显示颜色选择器
function showColorPicker(trigger, tier) {
    event.stopPropagation();
    currentEditingTier = tier;
   
    const header = document.querySelector('.tier-header[data-tier="' + tier + '"]');
    const bgColor = rgbToHex(header.style.backgroundColor);
    const textColor = rgbToHex(header.style.color);
   
    document.getElementById('bg-color-picker').value = bgColor;
    document.getElementById('text-color-picker').value = textColor;
    document.getElementById('color-picker-modal').style.display = 'block';
    document.getElementById('modal-overlay').style.display = 'block';
}
 
// 应用颜色
function applyColor() {
    if (currentEditingTier !== null) {
        const bgColor = document.getElementById('bg-color-picker').value;
        const textColor = document.getElementById('text-color-picker').value;
        const header = document.querySelector('.tier-header[data-tier="' + currentEditingTier + '"]');
       
        header.style.backgroundColor = bgColor;
        header.style.color = textColor;
    }
    closeColorPicker();
}


// 关闭颜色选择器
  ready(function() {
function closeColorPicker() {
     document.querySelectorAll('#tierlist-table .tier-head').forEach(buildEditableHead);
     document.getElementById('color-picker-modal').style.display = 'none';
    document.querySelectorAll('.tier-dropzone').forEach(initDropzone);
     document.getElementById('modal-overlay').style.display = 'none';
     initAvatars(document.getElementById('character-pool'));
    currentEditingTier = null;
}


// RGB转HEX
     var addBtn = document.getElementById('add-row');
function rgbToHex(rgb) {
     if (addBtn) addBtn.addEventListener('click', addNewRow);
     if (!rgb || rgb.indexOf('rgb') === -1) return '#000000';
     var saveBtn = document.getElementById('save-png');
   
     if (saveBtn) saveBtn.addEventListener('click', savePNG);
    const values = rgb.match(/\d+/g);
     if (!values) return '#000000';
      
    const hex = values.map(x => {
        const hexValue = parseInt(x).toString(16);
        return hexValue.length === 1 ? '0' + hexValue : hexValue;
     });
   
    return '#' + hex.join('');
}


// 导出为PNG
    (function insertResetButton() {
function exportToPNG() {
      const controls = document.querySelector('#tierlist-maker .tierlist-controls');
    const container = document.getElementById('tier-list-container');
      if (!controls || document.getElementById('reset-roles')) return;
   
      const resetBtn = document.createElement('div');
    // 使用html2canvas库
      resetBtn.id = 'reset-roles';
    if (typeof html2canvas === 'undefined') {
      resetBtn.className = 'btn';
        // 动态加载html2canvas
      resetBtn.textContent = '重置';
        const script = document.createElement('script');
      controls.insertBefore(resetBtn, controls.querySelector('#save-png') || null);
        script.src = 'https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js';
      resetBtn.addEventListener('click', resetAll);
        script.onload = function() {
     })();
            captureAndDownload(container);
        };
        document.head.appendChild(script);
     } else {
        captureAndDownload(container);
    }
}


function captureAndDownload(container) {
    const pool = document.getElementById('character-pool');
     html2canvas(container, {
     if (pool) {
        backgroundColor: '#ffffff',
      const obs = new MutationObserver(function(muts) {
        scale: 2,
         muts.forEach(function(m) {
        logging: false,
          if (m.addedNodes && m.addedNodes.length) {
        useCORS: true
             m.addedNodes.forEach(function(n) {
    }).then(canvas => {
              if (n.nodeType === 1) {
         canvas.toBlob(function(blob) {
                if (n.classList.contains('avatar-frame')) {
             const url = URL.createObjectURL(blob);
                  makeDraggable(n);
            const a = document.createElement('a');
                }
            a.href = url;
                n.querySelectorAll && n.querySelectorAll('.avatar-frame').forEach(makeDraggable);
            a.download = 'tier-list-' + new Date().getTime() + '.png';
                if (pool.contains(n)) cleanupEmptyPlaceholdersIn(pool);
            a.click();
              }
             URL.revokeObjectURL(url);
             });
          }
         });
         });
    });
      });
}
      obs.observe(pool, { childList: true, subtree: true });
 
    }
// 页面加载完成后初始化
  });
if (document.readyState === 'loading') {
})();
    document.addEventListener('DOMContentLoaded', initDragAndDrop);
} else {
    initDragAndDrop();
}
 
// 监听动态添加的元素
const observer = new MutationObserver(function(mutations) {
    initDragAndDrop();
});
 
observer.observe(document.body, {
    childList: true,
    subtree: true
});
</script>
</script>
</includeonly>
</includeonly>

2025年10月29日 (三) 14:50的最新版本