TierListMaker:修订间差异
来自卡厄思梦境WIKI
创建页面,内容为“ <includeonly> <style> .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.3s ease, box-shadow 0.3s ease; cursor: grab; margin: 2px; } .avatar-frame:active { cursor: grabbing; } .avatar-frame.dragging { opacity: 0.5; transform: scal…” |
小无编辑摘要 |
||
| 第37行: | 第37行: | ||
object-fit: cover; | object-fit: cover; | ||
pointer-events: none; | pointer-events: none; | ||
opacity: 1 !important; | |||
} | } | ||
| 第83行: | 第84行: | ||
.tierlist-table th { | .tierlist-table th { | ||
width: 100px; | width: 100px; | ||
} | |||
.tierlist-controls { | |||
margin-bottom: 20px; | |||
display: flex; | |||
gap: 10px; | |||
} | } | ||
| 第92行: | 第99行: | ||
border-radius: 5px; | border-radius: 5px; | ||
cursor: pointer; | cursor: pointer; | ||
transition: all 0.2s ease; | transition: all 0.2s ease; | ||
display: inline-block; | |||
text-align: center; | |||
user-select: none; | |||
} | } | ||
| 第137行: | 第146行: | ||
// 防止重复初始化 | // 防止重复初始化 | ||
if (window. | if (window.TierlistMakerInitialized) { | ||
console.log('TierlistMaker already initialized'); | console.log('TierlistMaker already initialized'); | ||
return; | return; | ||
| 第145行: | 第154行: | ||
draggedElement: null, | draggedElement: null, | ||
sourceContainer: null, | sourceContainer: null, | ||
init: function() { | init: function() { | ||
// 等待DOM完全加载 | // 等待DOM完全加载 | ||
if (document.readyState === 'loading') { | if (document.readyState === 'loading') { | ||
document.addEventListener('DOMContentLoaded', () => this.setup()); | document.addEventListener('DOMContentLoaded', () => this.setup()); | ||
} else { | } else { | ||
this.setup(); | setTimeout(() => this.setup(), 100); | ||
} | } | ||
}, | }, | ||
| 第169行: | 第173行: | ||
avatars.forEach(avatar => { | avatars.forEach(avatar => { | ||
// | // 不使用 cloneNode,直接设置属性 | ||
if (!avatar.getAttribute('data-drag-initialized')) { | |||
avatar.setAttribute('draggable', 'true'); | |||
avatar.setAttribute('data-drag-initialized', 'true'); | |||
avatar.addEventListener('dragstart', (e) => this.handleDragStart(e, avatar)); | |||
avatar.addEventListener('dragend', (e) => this.handleDragEnd(e, avatar)); | |||
} | |||
}); | }); | ||
| 第181行: | 第186行: | ||
const tierRows = document.querySelectorAll('.tier-row'); | const tierRows = document.querySelectorAll('.tier-row'); | ||
tierRows.forEach(row => { | tierRows.forEach(row => { | ||
row.addEventListener('dragover', (e) => this.handleDragOver(e, row)); | if (!row.getAttribute('data-drop-initialized')) { | ||
row.setAttribute('data-drop-initialized', 'true'); | |||
row.addEventListener('dragover', (e) => this.handleDragOver(e, row)); | |||
row.addEventListener('drop', (e) => this.handleDrop(e, row)); | |||
row.addEventListener('dragleave', (e) => this.handleDragLeave(e, row)); | |||
} | |||
}); | }); | ||
// 为角色池添加拖放事件 | // 为角色池添加拖放事件 | ||
const characterPool = document.getElementById('character-pool'); | const characterPool = document.getElementById('character-pool'); | ||
if (characterPool) { | if (characterPool && !characterPool.getAttribute('data-drop-initialized')) { | ||
characterPool.setAttribute('data-drop-initialized', 'true'); | |||
characterPool.addEventListener('dragover', (e) => this.handleDragOver(e, characterPool)); | characterPool.addEventListener('dragover', (e) => this.handleDragOver(e, characterPool)); | ||
characterPool.addEventListener('drop', (e) => this.handleDrop(e, characterPool)); | characterPool.addEventListener('drop', (e) => this.handleDrop(e, characterPool)); | ||
| 第200行: | 第209行: | ||
element.classList.add('dragging'); | element.classList.add('dragging'); | ||
e.dataTransfer.effectAllowed = 'move'; | e.dataTransfer.effectAllowed = 'move'; | ||
e.dataTransfer.setData('text/ | e.dataTransfer.setData('text/plain', 'drag'); // 简单的数据 | ||
}, | }, | ||
| 第210行: | 第219行: | ||
el.classList.remove('drag-over'); | el.classList.remove('drag-over'); | ||
}); | }); | ||
this.draggedElement = null; | |||
this.sourceContainer = null; | |||
}, | }, | ||
handleDragOver: function(e, element) { | handleDragOver: function(e, element) { | ||
e.preventDefault(); | |||
e.stopPropagation(); | |||
e.dataTransfer.dropEffect = 'move'; | e.dataTransfer.dropEffect = 'move'; | ||
element.classList.add('drag-over'); | |||
if (!element.classList.contains('drag-over')) { | |||
element.classList.add('drag-over'); | |||
} | |||
return false; | return false; | ||
| 第224行: | 第238行: | ||
handleDragLeave: function(e, element) { | handleDragLeave: function(e, element) { | ||
element.classList.remove('drag-over'); | // 只有当离开的是容器本身时才移除类 | ||
if (e.target === element) { | |||
element.classList.remove('drag-over'); | |||
} | |||
}, | }, | ||
handleDrop: function(e, element) { | handleDrop: function(e, element) { | ||
e.preventDefault(); | |||
e.stopPropagation(); | |||
element.classList.remove('drag-over'); | element.classList.remove('drag-over'); | ||
if (this.draggedElement && this.draggedElement !== element) { | if (this.draggedElement && this.draggedElement.parentElement !== element) { | ||
// | // 从原位置移除 | ||
if (this.draggedElement.parentElement) { | |||
this.draggedElement.parentElement.removeChild(this.draggedElement); | |||
} | |||
// 添加到新位置 | |||
element.appendChild(this.draggedElement); | element.appendChild(this.draggedElement); | ||
// | // 确保图片透明度正常 | ||
this. | const img = this.draggedElement.querySelector('img'); | ||
if (img) { | |||
img.style.opacity = '1'; | |||
} | |||
} | } | ||
| 第247行: | 第270行: | ||
initButtons: function() { | initButtons: function() { | ||
const saveBtn = document.getElementById('save-tierlist'); | const saveBtn = document.getElementById('save-tierlist-btn'); | ||
const resetBtn = document.getElementById('reset-tierlist'); | const resetBtn = document.getElementById('reset-tierlist-btn'); | ||
if (saveBtn) { | if (saveBtn) { | ||
saveBtn. | saveBtn.onclick = () => this.saveTierlist(); | ||
} | } | ||
if (resetBtn) { | if (resetBtn) { | ||
resetBtn. | resetBtn.onclick = () => this.resetTierlist(); | ||
} | } | ||
}, | }, | ||
| 第272行: | 第295行: | ||
} | } | ||
// | // 临时隐藏控制按钮和角色池 | ||
const controls = document.querySelector('.tierlist-controls'); | |||
const poolContainer = document.querySelector('.character-pool-container'); | const poolContainer = document.querySelector('.character-pool-container'); | ||
if (poolContainer) | const originalControlsDisplay = controls ? controls.style.display : ''; | ||
const originalPoolDisplay = poolContainer ? poolContainer.style.display : ''; | |||
if (controls) controls.style.display = 'none'; | |||
if (poolContainer) poolContainer.style.display = 'none'; | |||
html2canvas(table, { | html2canvas(table, { | ||
| 第288行: | 第313行: | ||
}).then(canvas => { | }).then(canvas => { | ||
// 恢复显示 | // 恢复显示 | ||
if (poolContainer) | if (controls) controls.style.display = originalControlsDisplay; | ||
if (poolContainer) poolContainer.style.display = originalPoolDisplay; | |||
// 下载图片 | // 下载图片 | ||
| 第300行: | 第324行: | ||
}).catch(err => { | }).catch(err => { | ||
console.error('生成图片失败:', err); | console.error('生成图片失败:', err); | ||
if (poolContainer) | if (controls) controls.style.display = originalControlsDisplay; | ||
if (poolContainer) poolContainer.style.display = originalPoolDisplay; | |||
alert('生成图片失败,请查看控制台了解详情'); | alert('生成图片失败,请查看控制台了解详情'); | ||
}); | }); | ||
| 第328行: | 第351行: | ||
allAvatars.forEach(avatar => { | allAvatars.forEach(avatar => { | ||
pool.appendChild(avatar); | pool.appendChild(avatar); | ||
// 确保图片透明度正常 | |||
const img = avatar.querySelector('img'); | |||
if (img) { | |||
img.style.opacity = '1'; | |||
} | |||
}); | }); | ||
} | } | ||
}; | }; | ||
// | // 标记已初始化 | ||
window.TierlistMakerInitialized = true; | |||
window.TierlistMaker = TierlistMaker; | window.TierlistMaker = TierlistMaker; | ||
2025年10月19日 (日) 22:02的版本