配队模拟器:修订间差异
来自卡厄思梦境WIKI
无编辑摘要 |
无编辑摘要 |
||
| 第1行: | 第1行: | ||
<!-- 加载html2canvas库 --> | |||
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> | |||
<script> | <script> | ||
(function() { | (function() { | ||
| 第12行: | 第15行: | ||
characterUnits[unitIndex] = { | characterUnits[unitIndex] = { | ||
characterName: null, | characterName: null, | ||
characterClass: null, | characterClass: null, | ||
cardIdCounter: 0, | cardIdCounter: 0, | ||
selectedCards: {} | selectedCards: {} | ||
}; | }; | ||
}); | |||
// ========== 保存为图片功能 ========== | |||
document.getElementById('save-team-btn').addEventListener('click', function() { | |||
var btn = this; | |||
var originalText = btn.textContent; | |||
btn.textContent = '生成中...'; | |||
btn.style.pointerEvents = 'none'; | |||
var contentElement = document.getElementById('team-content'); | |||
// 临时隐藏删除按钮 | |||
var deleteButtons = contentElement.querySelectorAll('.card-delete-btn'); | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = 'none'; | |||
}); | |||
html2canvas(contentElement, { | |||
backgroundColor: '#ffffff', | |||
scale: 2, | |||
logging: false, | |||
useCORS: true, | |||
allowTaint: true | |||
}).then(function(canvas) { | |||
// 恢复删除按钮 | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = 'flex'; | |||
}); | |||
// 下载图片 | |||
var link = document.createElement('a'); | |||
link.download = '配队方案_' + new Date().getTime() + '.png'; | |||
link.href = canvas.toDataURL('image/png'); | |||
link.click(); | |||
btn.textContent = originalText; | |||
btn.style.pointerEvents = 'auto'; | |||
}).catch(function(error) { | |||
console.error('保存失败:', error); | |||
alert('保存失败,请重试'); | |||
// 恢复删除按钮 | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = 'flex'; | |||
}); | |||
btn.textContent = originalText; | |||
btn.style.pointerEvents = 'auto'; | |||
}); | |||
}); | }); | ||
| 第49行: | 第101行: | ||
console.log('加载战斗员卡牌:', characterName, '单元:', unitIndex); | console.log('加载战斗员卡牌:', characterName, '单元:', unitIndex); | ||
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | ||
var deckArea = unit.querySelector('.deck-area'); | var deckArea = unit.querySelector('.deck-area'); | ||
// | // 显示加载状态 | ||
var placeholder = deckArea.querySelector('.deck-placeholder'); | |||
if (placeholder) { | |||
placeholder.textContent = '加载中...'; | |||
placeholder.style.fontSize = '18px'; | |||
placeholder.style.color = '#999'; | |||
} | |||
var apiUrl = mw.util.wikiScript('api'); | var apiUrl = mw.util.wikiScript('api'); | ||
var params = { | var params = { | ||
| 第69行: | 第126行: | ||
.then(data => { | .then(data => { | ||
if (data.parse && data.parse.text) { | if (data.parse && data.parse.text) { | ||
// 清空并添加卡牌 | |||
deckArea.innerHTML = data.parse.text['*']; | deckArea.innerHTML = data.parse.text['*']; | ||
| 第75行: | 第133行: | ||
unitData.cardIdCounter = 0; | unitData.cardIdCounter = 0; | ||
setTimeout(function() { | setTimeout(function() { | ||
initializeCardFeatures(unitIndex); | initializeCardFeatures(unitIndex); | ||
}, 100); | }, 100); | ||
} else { | } else { | ||
if (placeholder) { | |||
placeholder.textContent = '加载失败'; | |||
placeholder.style.color = 'red'; | |||
} | |||
} | } | ||
}) | }) | ||
.catch(error => { | .catch(error => { | ||
console.error('加载卡牌失败:', error); | console.error('加载卡牌失败:', error); | ||
if (placeholder) { | |||
placeholder.textContent = '加载出错'; | |||
placeholder.style.color = 'red'; | |||
} | |||
}); | }); | ||
} | } | ||
// 初始化卡牌功能 | // 初始化卡牌功能 | ||
function initializeCardFeatures(unitIndex) { | function initializeCardFeatures(unitIndex) { | ||
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | ||
var unitData = characterUnits[unitIndex]; | var unitData = characterUnits[unitIndex]; | ||
var deckArea = unit.querySelector('.deck-area'); | var deckArea = unit.querySelector('.deck-area'); | ||
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper'); | var wrappers = deckArea.querySelectorAll('.deck-card-wrapper'); | ||
| 第114行: | 第164行: | ||
if (!card) return; | if (!card) return; | ||
// | // 确保wrapper样式正确 | ||
wrapper.style.flexShrink = '0'; | |||
wrapper.style.display = 'inline-block'; | |||
var uniqueId = 'deck-card-' + unitIndex + '-' + (++unitData.cardIdCounter); | var uniqueId = 'deck-card-' + unitIndex + '-' + (++unitData.cardIdCounter); | ||
wrapper.setAttribute('data-unique-id', uniqueId); | wrapper.setAttribute('data-unique-id', uniqueId); | ||
wrapper.setAttribute('data-unit-index', unitIndex); | wrapper.setAttribute('data-unit-index', unitIndex); | ||
unitData.selectedCards[uniqueId] = { | unitData.selectedCards[uniqueId] = { | ||
module: wrapper.getAttribute('data-module') || unitData.characterName, | module: wrapper.getAttribute('data-module') || unitData.characterName, | ||
| 第128行: | 第180行: | ||
}; | }; | ||
if (!card.querySelector('.card-delete-btn')) { | if (!card.querySelector('.card-delete-btn')) { | ||
var deleteBtn = document.createElement('div'); | var deleteBtn = document.createElement('div'); | ||
| 第139行: | 第190行: | ||
wrapper.remove(); | wrapper.remove(); | ||
delete unitData.selectedCards[uniqueId]; | delete unitData.selectedCards[uniqueId]; | ||
// 如果没有卡牌了,显示占位符 | |||
checkAndShowPlaceholder(unitIndex); | |||
}); | }); | ||
| 第146行: | 第200行: | ||
}); | }); | ||
setupGlobalModalListener(); | setupGlobalModalListener(); | ||
} | |||
// 检查并显示占位符 | |||
function checkAndShowPlaceholder(unitIndex) { | |||
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | |||
var deckArea = unit.querySelector('.deck-area'); | |||
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper'); | |||
if (wrappers.length === 0) { | |||
deckArea.innerHTML = '<div class="deck-placeholder" style="width: 100%; text-align: center; font-size: 48px; color: #ccc; line-height: 330px;">+</div>'; | |||
} | |||
} | } | ||
// 设置全局模态框监听器 | // 设置全局模态框监听器 | ||
function setupGlobalModalListener() { | function setupGlobalModalListener() { | ||
if (window.deckModalObserver) { | if (window.deckModalObserver) { | ||
window.deckModalObserver.disconnect(); | window.deckModalObserver.disconnect(); | ||
} | } | ||
window.deckModalObserver = new MutationObserver(function(mutations) { | window.deckModalObserver = new MutationObserver(function(mutations) { | ||
mutations.forEach(function(mutation) { | mutations.forEach(function(mutation) { | ||
| 第163行: | 第225行: | ||
var modal = mutation.target; | var modal = mutation.target; | ||
if (modal.classList.contains('card-modal') && modal.style.display !== 'none') { | if (modal.classList.contains('card-modal') && modal.style.display !== 'none') { | ||
setTimeout(function() { | setTimeout(function() { | ||
enhanceActiveModal(modal); | enhanceActiveModal(modal); | ||
| 第172行: | 第233行: | ||
}); | }); | ||
document.querySelectorAll('.card-modal').forEach(function(modal) { | document.querySelectorAll('.card-modal').forEach(function(modal) { | ||
window.deckModalObserver.observe(modal, { | window.deckModalObserver.observe(modal, { | ||
| 第183行: | 第243行: | ||
// 增强当前活动的模态框 | // 增强当前活动的模态框 | ||
function enhanceActiveModal(modal) { | function enhanceActiveModal(modal) { | ||
var cardId = modal.id ? modal.id.replace('-modal', '') : null; | var cardId = modal.id ? modal.id.replace('-modal', '') : null; | ||
if (!cardId) return; | if (!cardId) return; | ||
var deckCard = null; | var deckCard = null; | ||
var uniqueId = null; | var uniqueId = null; | ||
var unitIndex = null; | var unitIndex = null; | ||
document.querySelectorAll('.deck-area .deck-card-wrapper').forEach(function(wrapper) { | document.querySelectorAll('.deck-area .deck-card-wrapper').forEach(function(wrapper) { | ||
var wrapperCard = wrapper.querySelector('.card-small-wrapper'); | var wrapperCard = wrapper.querySelector('.card-small-wrapper'); | ||
| 第203行: | 第260行: | ||
if (!deckCard || !uniqueId || !unitIndex) { | if (!deckCard || !uniqueId || !unitIndex) { | ||
return; | return; | ||
} | } | ||
| 第209行: | 第265行: | ||
var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | ||
if (!cardData) { | if (!cardData) { | ||
return; | return; | ||
} | } | ||
if (modal.hasAttribute('data-deck-enhanced')) { | if (modal.hasAttribute('data-deck-enhanced')) { | ||
return; | return; | ||
| 第221行: | 第273行: | ||
modal.setAttribute('data-deck-enhanced', 'true'); | modal.setAttribute('data-deck-enhanced', 'true'); | ||
var inspirationButton = modal.querySelector('.inspiration-button'); | var inspirationButton = modal.querySelector('.inspiration-button'); | ||
if (inspirationButton) { | if (inspirationButton) { | ||
| 第231行: | 第282行: | ||
} | } | ||
var godButton = modal.querySelector('.god-inspiration-button'); | var godButton = modal.querySelector('.god-inspiration-button'); | ||
if (godButton) { | if (godButton) { | ||
| 第244行: | 第294行: | ||
// 关闭模态框并恢复滚动 | // 关闭模态框并恢复滚动 | ||
function closeModalAndRestoreScroll(modal) { | function closeModalAndRestoreScroll(modal) { | ||
modal.style.display = 'none'; | modal.style.display = 'none'; | ||
modal.removeAttribute('data-deck-enhanced'); | modal.removeAttribute('data-deck-enhanced'); | ||
document.body.style.overflow = ''; | document.body.style.overflow = ''; | ||
document.body.style.position = ''; | document.body.style.position = ''; | ||
document.documentElement.style.overflow = ''; | document.documentElement.style.overflow = ''; | ||
document.body.classList.remove('modal-open'); | document.body.classList.remove('modal-open'); | ||
document.documentElement.classList.remove('modal-open'); | document.documentElement.classList.remove('modal-open'); | ||
window.dispatchEvent(new Event('resize')); | window.dispatchEvent(new Event('resize')); | ||
} | } | ||
| 第270行: | 第311行: | ||
var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | ||
if (!cardData) return; | if (!cardData) return; | ||
var variants = inspirationView.querySelectorAll('.inspiration-variant'); | var variants = inspirationView.querySelectorAll('.inspiration-variant'); | ||
| 第282行: | 第321行: | ||
selectBtn.addEventListener('click', function() { | selectBtn.addEventListener('click', function() { | ||
replaceCard(uniqueId, unitIndex, '灵光一闪', index + 1); | replaceCard(uniqueId, unitIndex, '灵光一闪', index + 1); | ||
closeModalAndRestoreScroll(modal); | closeModalAndRestoreScroll(modal); | ||
| 第299行: | 第337行: | ||
var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | ||
if (!cardData) return; | if (!cardData) return; | ||
var godGroups = godView.querySelectorAll('.god-group'); | var godGroups = godView.querySelectorAll('.god-group'); | ||
| 第318行: | 第354行: | ||
selectBtn.addEventListener('click', function() { | selectBtn.addEventListener('click', function() { | ||
replaceCard(uniqueId, unitIndex, '神光一闪', groupName, index + 1); | replaceCard(uniqueId, unitIndex, '神光一闪', groupName, index + 1); | ||
closeModalAndRestoreScroll(modal); | closeModalAndRestoreScroll(modal); | ||
| 第343行: | 第378行: | ||
} | } | ||
cardData.variantType = variantType; | cardData.variantType = variantType; | ||
cardData.variantParam = param1; | cardData.variantParam = param1; | ||
cardData.variantIndex = param2; | cardData.variantIndex = param2; | ||
var oldContent = wrapper.innerHTML; | var oldContent = wrapper.innerHTML; | ||
wrapper.innerHTML = '<div style="color:#999;padding:20px;">加载中...</div>'; | wrapper.innerHTML = '<div style="color:#999;padding:20px;">加载中...</div>'; | ||
var invokeText = '{{#invoke:卡牌|main|' + cardData.module + '|' + cardData.cardName; | var invokeText = '{{#invoke:卡牌|main|' + cardData.module + '|' + cardData.cardName; | ||
if (variantType === '灵光一闪') { | if (variantType === '灵光一闪') { | ||
| 第363行: | 第393行: | ||
invokeText += '}}'; | invokeText += '}}'; | ||
var apiUrl = mw.util.wikiScript('api'); | var apiUrl = mw.util.wikiScript('api'); | ||
var params = { | var params = { | ||
| 第381行: | 第408行: | ||
wrapper.innerHTML = data.parse.text['*']; | wrapper.innerHTML = data.parse.text['*']; | ||
setTimeout(function() { | setTimeout(function() { | ||
var newCard = wrapper.querySelector('.card-small-wrapper'); | var newCard = wrapper.querySelector('.card-small-wrapper'); | ||
if (newCard) { | if (newCard) { | ||
// | // 确保wrapper样式 | ||
wrapper.style.flexShrink = '0'; | |||
wrapper.style.display = 'inline-block'; | |||
var deleteBtn = document.createElement('div'); | var deleteBtn = document.createElement('div'); | ||
deleteBtn.className = 'card-delete-btn'; | deleteBtn.className = 'card-delete-btn'; | ||
| 第395行: | 第424行: | ||
wrapper.remove(); | wrapper.remove(); | ||
delete characterUnits[unitIndex].selectedCards[uniqueId]; | delete characterUnits[unitIndex].selectedCards[uniqueId]; | ||
checkAndShowPlaceholder(unitIndex); | |||
}); | }); | ||
| 第401行: | 第431行: | ||
} | } | ||
setupGlobalModalListener(); | setupGlobalModalListener(); | ||
document.body.style.overflow = ''; | document.body.style.overflow = ''; | ||
document.documentElement.style.overflow = ''; | document.documentElement.style.overflow = ''; | ||
}, 100); | }, 100); | ||
} else { | } else { | ||
wrapper.innerHTML = oldContent; | wrapper.innerHTML = oldContent; | ||
} | } | ||
| 第416行: | 第442行: | ||
console.error('替换卡牌失败:', error); | console.error('替换卡牌失败:', error); | ||
wrapper.innerHTML = oldContent; | wrapper.innerHTML = oldContent; | ||
document.body.style.overflow = ''; | document.body.style.overflow = ''; | ||
document.documentElement.style.overflow = ''; | document.documentElement.style.overflow = ''; | ||
| 第426行: | 第451行: | ||
var characterOption = e.target.closest('.character-option'); | var characterOption = e.target.closest('.character-option'); | ||
if (characterOption && currentActiveUnit) { | if (characterOption && currentActiveUnit) { | ||
var characterName = characterOption.getAttribute('data-character-name') || | var characterName = characterOption.getAttribute('data-character-name') || | ||
characterOption.getAttribute('data-name') || | characterOption.getAttribute('data-name') || | ||
characterOption.getAttribute('title'); | characterOption.getAttribute('title'); | ||
var characterClass = characterOption.getAttribute('data-class') || | var characterClass = characterOption.getAttribute('data-class') || | ||
characterOption.getAttribute('data-职业'); | characterOption.getAttribute('data-职业'); | ||
| 第440行: | 第463行: | ||
} | } | ||
characterUnits[currentActiveUnit].characterClass = characterClass; | characterUnits[currentActiveUnit].characterClass = characterClass; | ||
var clonedCard = characterOption.cloneNode(true); | var clonedCard = characterOption.cloneNode(true); | ||
clonedCard.classList.remove('character-option'); | clonedCard.classList.remove('character-option'); | ||
| 第489行: | 第508行: | ||
var partnerImg = document.createElement('img'); | var partnerImg = document.createElement('img'); | ||
partnerImg.src = '/index.php?title=Special:Redirect/file/Portrait_character_wide_' + partnerId + '.png'; | partnerImg.src = '/index.php?title=Special:Redirect/file/Portrait_character_wide_' + partnerId + '.png'; | ||
partnerImg.style.width = ' | partnerImg.style.width = '159px'; | ||
partnerImg.style.height = '77px'; | partnerImg.style.height = '77px'; | ||
partnerImg.style.objectFit = 'cover'; | partnerImg.style.objectFit = 'cover'; | ||
| 第505行: | 第524行: | ||
// ========== 卡牌添加功能 ========== | // ========== 卡牌添加功能 ========== | ||
var currentDeckArea = null; | var currentDeckArea = null; | ||
var currentCardType = 'character'; | var currentCardType = 'character'; | ||
// 点击卡组区域打开卡牌选择 | // 点击卡组区域打开卡牌选择 | ||
document.querySelectorAll('.deck-area').forEach(function(deckArea) { | document.querySelectorAll('.deck-area').forEach(function(deckArea) { | ||
var originalClickHandler = function(e) { | var originalClickHandler = function(e) { | ||
if (e.target.closest('.deck-card-wrapper') || | if (e.target.closest('.deck-card-wrapper') || | ||
e.target.closest('.card-small-wrapper') || | e.target.closest('.card-small-wrapper') || | ||
| 第521行: | 第539行: | ||
currentDeckArea = this; | currentDeckArea = this; | ||
var unit = this.closest('.character-unit'); | var unit = this.closest('.character-unit'); | ||
var characterSlot = unit.querySelector('.character-slot'); | var characterSlot = unit.querySelector('.character-slot'); | ||
var hasCharacter = characterSlot.querySelector('img') !== null || | var hasCharacter = characterSlot.querySelector('img') !== null || | ||
characterSlot.innerHTML.indexOf('data-character-name') > -1 || | characterSlot.innerHTML.indexOf('data-character-name') > -1 || | ||
| 第540行: | 第556行: | ||
} | } | ||
currentCardType = 'character'; | currentCardType = 'character'; | ||
document.querySelectorAll('.card-type-tab').forEach(function(tab) { | document.querySelectorAll('.card-type-tab').forEach(function(tab) { | ||
| 第554行: | 第569行: | ||
} | } | ||
document.getElementById('card-modal').style.display = 'block'; | document.getElementById('card-modal').style.display = 'block'; | ||
loadCardList('character'); | loadCardList('character'); | ||
| 第568行: | 第582行: | ||
currentCardType = cardType; | currentCardType = cardType; | ||
document.querySelectorAll('.card-type-tab').forEach(function(t) { | document.querySelectorAll('.card-type-tab').forEach(function(t) { | ||
t.classList.remove('active'); | t.classList.remove('active'); | ||
| 第578行: | 第591行: | ||
this.style.fontWeight = 'bold'; | this.style.fontWeight = 'bold'; | ||
loadCardList(cardType); | loadCardList(cardType); | ||
}); | }); | ||
| 第592行: | 第604行: | ||
if (cardType === 'character') { | if (cardType === 'character') { | ||
var unitData = characterUnits[currentActiveUnit]; | var unitData = characterUnits[currentActiveUnit]; | ||
if (!unitData.characterName) { | if (!unitData.characterName) { | ||
| 第600行: | 第611行: | ||
invokeText = '{{#invoke:配队/卡牌|deck|' + unitData.characterName + '}}'; | invokeText = '{{#invoke:配队/卡牌|deck|' + unitData.characterName + '}}'; | ||
} else if (cardType === 'neutral') { | } else if (cardType === 'neutral') { | ||
var unitData = characterUnits[currentActiveUnit]; | var unitData = characterUnits[currentActiveUnit]; | ||
var characterClass = unitData.characterClass; | var characterClass = unitData.characterClass; | ||
| 第610行: | 第620行: | ||
} | } | ||
} else if (cardType === 'monster') { | } else if (cardType === 'monster') { | ||
invokeText = '{{#invoke:卡牌/怪物|all}}'; | invokeText = '{{#invoke:卡牌/怪物|all}}'; | ||
} | } | ||
| 第629行: | 第638行: | ||
listContainer.innerHTML = data.parse.text['*']; | listContainer.innerHTML = data.parse.text['*']; | ||
setTimeout(function() { | setTimeout(function() { | ||
addCardSelectionHandlers(cardType); | addCardSelectionHandlers(cardType); | ||
| 第643行: | 第651行: | ||
} | } | ||
// 添加卡牌选择处理器 | |||
function addCardSelectionHandlers(cardType) { | function addCardSelectionHandlers(cardType) { | ||
var listContainer = document.getElementById('card-selection-list'); | var listContainer = document.getElementById('card-selection-list'); | ||
| 第660行: | 第669行: | ||
}); | }); | ||
wrapper.addEventListener('click', function(e) { | wrapper.addEventListener('click', function(e) { | ||
e.stopPropagation(); | e.stopPropagation(); | ||
var cardName = this.getAttribute('data-card'); | var cardName = this.getAttribute('data-card'); | ||
var card = this.querySelector('.card-small-wrapper'); | var card = this.querySelector('.card-small-wrapper'); | ||
| 第677行: | 第684行: | ||
} | } | ||
var hasInspiration = card && card.querySelector('.inspiration-button'); | var hasInspiration = card && card.querySelector('.inspiration-button'); | ||
var hasGodInspiration = card && card.querySelector('.god-inspiration-button'); | var hasGodInspiration = card && card.querySelector('.god-inspiration-button'); | ||
if (hasInspiration || hasGodInspiration) { | if (hasInspiration || hasGodInspiration) { | ||
showVariantSelectionDialog(cardName, 'character'); | showVariantSelectionDialog(cardName, 'character'); | ||
} else { | } else { | ||
addCardToDeckByName(cardName, 'character'); | addCardToDeckByName(cardName, 'character'); | ||
} | } | ||
| 第691行: | 第695行: | ||
}); | }); | ||
} else { | } else { | ||
var cards = listContainer.querySelectorAll('.card-small-wrapper'); | var cards = listContainer.querySelectorAll('.card-small-wrapper'); | ||
| 第714行: | 第717行: | ||
} | } | ||
// | // 显示变体选择对话框 | ||
function showVariantSelectionDialog(cardName, cardType) { | function showVariantSelectionDialog(cardName, cardType) { | ||
var dialog = document.createElement('div'); | var dialog = document.createElement('div'); | ||
dialog.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:30px;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,0.3);z-index:10001;min-width:300px;'; | dialog.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:30px;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,0.3);z-index:10001;min-width:300px;'; | ||
| 第730行: | 第732行: | ||
dialog.innerHTML = html; | dialog.innerHTML = html; | ||
var overlay = document.createElement('div'); | var overlay = document.createElement('div'); | ||
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:10000;'; | overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:10000;'; | ||
| 第737行: | 第738行: | ||
document.body.appendChild(dialog); | document.body.appendChild(dialog); | ||
dialog.querySelectorAll('.variant-option-btn').forEach(function(btn) { | dialog.querySelectorAll('.variant-option-btn').forEach(function(btn) { | ||
btn.addEventListener('mouseenter', function() { | btn.addEventListener('mouseenter', function() { | ||
| 第749行: | 第749行: | ||
}); | }); | ||
dialog.addEventListener('click', function(e) { | dialog.addEventListener('click', function(e) { | ||
var btn = e.target.closest('.variant-option-btn'); | var btn = e.target.closest('.variant-option-btn'); | ||
| 第757行: | 第756行: | ||
if (action === 'base') { | if (action === 'base') { | ||
addCardToDeckByName(cardName, cardType); | addCardToDeckByName(cardName, cardType); | ||
document.body.removeChild(overlay); | document.body.removeChild(overlay); | ||
| 第763行: | 第761行: | ||
document.getElementById('card-modal').style.display = 'none'; | document.getElementById('card-modal').style.display = 'none'; | ||
} else if (action === 'view') { | } else if (action === 'view') { | ||
addCardToDeckByName(cardName, cardType, function() { | addCardToDeckByName(cardName, cardType, function() { | ||
document.body.removeChild(overlay); | document.body.removeChild(overlay); | ||
| 第769行: | 第766行: | ||
document.getElementById('card-modal').style.display = 'none'; | document.getElementById('card-modal').style.display = 'none'; | ||
setTimeout(function() { | setTimeout(function() { | ||
alert('卡牌已添加!现在您可以点击卡牌查看并选择变体。'); | alert('卡牌已添加!现在您可以点击卡牌查看并选择变体。'); | ||
| 第775行: | 第771行: | ||
}); | }); | ||
} else { | } else { | ||
document.body.removeChild(overlay); | document.body.removeChild(overlay); | ||
document.body.removeChild(dialog); | document.body.removeChild(dialog); | ||
| 第782行: | 第777行: | ||
} | } | ||
// 按名称添加卡牌到卡组 | |||
function addCardToDeckByName(cardName, cardType, callback) { | function addCardToDeckByName(cardName, cardType, callback) { | ||
if (!currentDeckArea || !currentActiveUnit) return; | if (!currentDeckArea || !currentActiveUnit) return; | ||
| 第787行: | 第783行: | ||
var unitData = characterUnits[currentActiveUnit]; | var unitData = characterUnits[currentActiveUnit]; | ||
var moduleName = ''; | var moduleName = ''; | ||
if (cardType === 'character') { | if (cardType === 'character') { | ||
moduleName = unitData.characterName; | moduleName = unitData.characterName; | ||
} else if (cardType === 'neutral') { | } else if (cardType === 'neutral') { | ||
moduleName = '中立'; | moduleName = '中立'; | ||
} else if (cardType === 'monster') { | } else if (cardType === 'monster') { | ||
moduleName = '怪物'; | moduleName = '怪物'; | ||
} | } | ||
var invokeText = ''; | var invokeText = ''; | ||
if (cardType === 'character') { | if (cardType === 'character') { | ||
invokeText = '{{#invoke:卡牌|main|' + moduleName + '|' + cardName + '}}'; | |||
} else if (cardType === 'neutral') { | } else if (cardType === 'neutral') { | ||
invokeText = '{{#invoke:卡牌/中立|main|' + cardName + '}}'; | invokeText = '{{#invoke:卡牌/中立|main|' + cardName + '}}'; | ||
| 第809行: | 第800行: | ||
invokeText = '{{#invoke:卡牌/怪物|main|' + cardName + '}}'; | invokeText = '{{#invoke:卡牌/怪物|main|' + cardName + '}}'; | ||
} | } | ||
var apiUrl = mw.util.wikiScript('api'); | var apiUrl = mw.util.wikiScript('api'); | ||
| 第824行: | 第814行: | ||
.then(data => { | .then(data => { | ||
if (data.parse && data.parse.text) { | if (data.parse && data.parse.text) { | ||
// | // 移除占位符 | ||
var placeholder = currentDeckArea.querySelector('.deck-placeholder'); | |||
if (placeholder) { | |||
placeholder.remove(); | |||
} | |||
var wrapper = document.createElement('div'); | var wrapper = document.createElement('div'); | ||
wrapper.className = 'deck-card-wrapper'; | wrapper.className = 'deck-card-wrapper'; | ||
| 第831行: | 第826行: | ||
wrapper.setAttribute('data-card', cardName); | wrapper.setAttribute('data-card', cardName); | ||
// | // 确保wrapper不会换行 | ||
wrapper.style.flexShrink = '0'; | |||
wrapper.style.display = 'inline-block'; | |||
var uniqueId = 'deck-card-' + currentActiveUnit + '-' + (++unitData.cardIdCounter); | var uniqueId = 'deck-card-' + currentActiveUnit + '-' + (++unitData.cardIdCounter); | ||
wrapper.setAttribute('data-unique-id', uniqueId); | wrapper.setAttribute('data-unique-id', uniqueId); | ||
wrapper.setAttribute('data-unit-index', currentActiveUnit); | wrapper.setAttribute('data-unit-index', currentActiveUnit); | ||
unitData.selectedCards[uniqueId] = { | unitData.selectedCards[uniqueId] = { | ||
module: moduleName, | module: moduleName, | ||
| 第845行: | 第842行: | ||
}; | }; | ||
currentDeckArea.appendChild(wrapper); | currentDeckArea.appendChild(wrapper); | ||
setTimeout(function() { | setTimeout(function() { | ||
var card = wrapper.querySelector('.card-small-wrapper'); | var card = wrapper.querySelector('.card-small-wrapper'); | ||
| 第861行: | 第856行: | ||
wrapper.remove(); | wrapper.remove(); | ||
delete unitData.selectedCards[uniqueId]; | delete unitData.selectedCards[uniqueId]; | ||
checkAndShowPlaceholder(currentActiveUnit); | |||
}); | }); | ||
| 第867行: | 第863行: | ||
} | } | ||
setupGlobalModalListener(); | setupGlobalModalListener(); | ||
if (callback) callback(); | if (callback) callback(); | ||
}, 100); | }, 100); | ||
| 第883行: | 第877行: | ||
} | } | ||
// | // 添加卡牌到卡组(从元素获取信息) | ||
function addCardToDeck(cardElement, cardType) { | function addCardToDeck(cardElement, cardType) { | ||
if (!currentDeckArea || !currentActiveUnit) return; | if (!currentDeckArea || !currentActiveUnit) return; | ||
var cardName = cardElement.getAttribute('data-card-name') || | var cardName = cardElement.getAttribute('data-card-name') || | ||
cardElement.getAttribute('data-card'); | cardElement.getAttribute('data-card'); | ||
if (!cardName) { | if (!cardName) { | ||
var parent = cardElement.closest('[data-card]'); | var parent = cardElement.closest('[data-card]'); | ||
| 第901行: | 第891行: | ||
} | } | ||
if (!cardName) { | if (!cardName) { | ||
var parent = cardElement.closest('[data-card-name]'); | var parent = cardElement.closest('[data-card-name]'); | ||
| 第909行: | 第898行: | ||
} | } | ||
if (!cardName) { | if (!cardName) { | ||
var wrapper = cardElement.closest('.deck-card-wrapper'); | var wrapper = cardElement.closest('.deck-card-wrapper'); | ||
| 第918行: | 第906行: | ||
if (!cardName) { | if (!cardName) { | ||
console.error(' | console.error('无法获取卡牌名称'); | ||
alert('错误:无法获取卡牌名称'); | alert('错误:无法获取卡牌名称'); | ||
return; | return; | ||
} | } | ||
addCardToDeckByName(cardName, cardType, function() { | addCardToDeckByName(cardName, cardType, function() { | ||
document.getElementById('card-modal').style.display = 'none'; | document.getElementById('card-modal').style.display = 'none'; | ||
}); | }); | ||
| 第949行: | 第933行: | ||
var equipmentType = this.getAttribute('data-equipment-type'); | var equipmentType = this.getAttribute('data-equipment-type'); | ||
var titleMap = { | var titleMap = { | ||
'weapon': '选择武器', | 'weapon': '选择武器', | ||
| 第957行: | 第940行: | ||
document.getElementById('equipment-modal-title').textContent = titleMap[equipmentType] || '选择装备'; | document.getElementById('equipment-modal-title').textContent = titleMap[equipmentType] || '选择装备'; | ||
loadEquipmentList(equipmentType); | loadEquipmentList(equipmentType); | ||
| 第986行: | 第968行: | ||
var category = categoryMap[equipmentType]; | var category = categoryMap[equipmentType]; | ||
var apiUrl = mw.util.wikiScript('api'); | var apiUrl = mw.util.wikiScript('api'); | ||
var askQuery = '{{#ask:[[分类:' + category + ']]|?名称|?稀有度|sort=稀有度,名称|order=desc,asc|format=template|template=配队/装备|limit=500}}'; | var askQuery = '{{#ask:[[分类:' + category + ']]|?名称|?稀有度|sort=稀有度,名称|order=desc,asc|format=template|template=配队/装备|limit=500}}'; | ||
| 第1,004行: | 第985行: | ||
listContainer.innerHTML = data.parse.text['*']; | listContainer.innerHTML = data.parse.text['*']; | ||
setTimeout(function() { | setTimeout(function() { | ||
addEquipmentSelectionHandlers(equipmentType); | addEquipmentSelectionHandlers(equipmentType); | ||
| 第1,043行: | 第1,023行: | ||
var slot = unit.querySelector('.equipment-slot[data-equipment-type="' + equipmentType + '"]'); | var slot = unit.querySelector('.equipment-slot[data-equipment-type="' + equipmentType + '"]'); | ||
var clonedImg = equipmentImg.cloneNode(true); | var clonedImg = equipmentImg.cloneNode(true); | ||
clonedImg.style.width = '100px'; | clonedImg.style.width = '100px'; | ||
| 第1,056行: | 第1,035行: | ||
} | } | ||
}); | }); | ||
}); | }); | ||
} | } | ||
| 第1,162行: | 第1,052行: | ||
<style> | <style> | ||
#team-simulator { | |||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; | |||
} | |||
#save-team-btn:hover { | |||
transform: translateY(-2px); | |||
box-shadow: 0 | box-shadow: 0 6px 12px rgba(0,0,0,0.15); | ||
} | } | ||
#save-team-btn:active { | |||
transform: translateY(0); | |||
} | } | ||
.character-unit { | .character-unit { | ||
background: white; | background: white; | ||
transition: all 0.3s; | |||
} | } | ||
.character-slot, .partner-slot { | .character-slot, .partner-slot { | ||
transition: all 0.3s; | transition: all 0.3s; | ||
overflow: hidden; | overflow: hidden; | ||
} | } | ||
.character-slot { | .character-slot:hover, .partner-slot:hover { | ||
border-color: #667eea; | |||
background: #f9f9ff; | |||
} | } | ||
. | .deck-area { | ||
transition: border-color 0.3s, background 0.3s; | |||
} | } | ||
. | .deck-area:hover { | ||
border-color: #667eea; | border-color: #667eea; | ||
} | } | ||
. | /* 确保卡牌wrapper不换行 */ | ||
.deck-card-wrapper { | |||
flex-shrink: 0; | |||
display: inline-block; | |||
} | |||
/* 确保中立和怪物卡牌也不换行 */ | |||
#card-selection-list .deck-card-wrapper, | |||
#card-selection-list .card-small-wrapper { | |||
flex-shrink: 0; | |||
display: inline-block; | |||
} | } | ||
.equipment-slot { | |||
. | |||
transition: all 0.3s; | transition: all 0.3s; | ||
} | } | ||
. | .equipment-slot:hover { | ||
border-color: #667eea; | border-color: #667eea; | ||
background: #f9f9ff; | background: #f9f9ff; | ||
} | } | ||
/* 模态框样式优化 */ | |||
#card-modal, #character-modal, #partner-modal, #equipment-modal { | |||
animation: fadeIn 0.3s ease; | |||
} | } | ||
@keyframes fadeIn { | |||
from { | |||
opacity: 0; | |||
} | |||
to { | |||
opacity: 1; | |||
} | |||
} | } | ||
/* 模态框内容动画 */ | |||
#card-modal > div, | |||
#character-modal > div, | |||
#partner-modal > div, | |||
#equipment-modal > div { | |||
animation: slideIn 0.3s ease; | |||
} | } | ||
@keyframes slideIn { | |||
from { | |||
transform: translate(-50%, -60%); | |||
opacity: 0; | |||
} | |||
to { | |||
transform: translate(-50%, -50%); | |||
opacity: 1; | |||
} | |||
} | } | ||
. | /* 卡牌类型标签样式 */ | ||
.card-type-tab { | |||
transition: all 0.3s; | |||
} | } | ||
. | .card-type-tab:hover { | ||
color: #667eea; | |||
background: rgba(102, 126, 234, 0.05); | |||
} | } | ||
. | .card-type-tab.active { | ||
color: | color: #667eea; | ||
} | } | ||
. | /* 角色和伙伴选项样式 */ | ||
.character-option, .partner-option { | |||
transition: all 0.3s; | |||
} | } | ||
.character-option:hover, .partner-option:hover { | |||
transform: translateY(-5px); | |||
box-shadow: 0 5px 20px rgba(102,126,234,0.4); | |||
} | } | ||
. | /* 装备选项样式 */ | ||
.equipment-option { | |||
cursor: pointer; | cursor: pointer; | ||
padding: 10px; | padding: 10px; | ||
border: 2px solid transparent; | border: 2px solid transparent; | ||
border-radius: | border-radius: 8px; | ||
transition: all 0.3s; | transition: all 0.3s; | ||
background: white; | background: white; | ||
} | } | ||
. | .equipment-option:hover { | ||
border-color: #667eea; | border-color: #667eea; | ||
transform: translateY(-5px); | transform: translateY(-5px); | ||
| 第1,341行: | 第1,183行: | ||
} | } | ||
. | /* 删除按钮样式优化 */ | ||
.card-delete-btn { | |||
transition: all 0.2s; | |||
user-select: none; | |||
} | |||
.card-delete-btn:hover { | |||
background: rgba(255,0,0,0.9); | |||
transform: scale(1.2); | |||
} | } | ||
/* | /* 占位符样式 */ | ||
. | .deck-placeholder { | ||
pointer-events: none; | |||
user-select: none; | |||
} | } | ||
. | /* 变体选择按钮样式 */ | ||
.select-variant-btn { | |||
transition: all 0.3s; | transition: all 0.3s; | ||
user-select: none; | |||
} | } | ||
. | .select-variant-btn:hover { | ||
transform: translateY(-2px); | |||
box-shadow: 0 5px 15px rgba(0,0,0,0.2); | |||
} | } | ||
. | .select-variant-btn:active { | ||
transform: translateY(0); | |||
} | } | ||
/* | /* 卡牌选择列表样式优化 */ | ||
#card-selection-list { | #card-selection-list { | ||
max-height: 60vh; | |||
overflow-y: auto; | |||
} | |||
/* 自定义滚动条 */ | |||
#card-selection-list::-webkit-scrollbar, | |||
#character-list::-webkit-scrollbar, | |||
#partner-list::-webkit-scrollbar, | |||
#equipment-list::-webkit-scrollbar { | |||
width: 8px; | |||
} | |||
#card-selection-list::-webkit-scrollbar-track, | |||
#character-list::-webkit-scrollbar-track, | |||
#partner-list::-webkit-scrollbar-track, | |||
#equipment-list::-webkit-scrollbar-track { | |||
background: #f1f1f1; | |||
border-radius: 4px; | |||
} | |||
#card-selection-list::-webkit-scrollbar-thumb, | |||
#character-list::-webkit-scrollbar-thumb, | |||
#partner-list::-webkit-scrollbar-thumb, | |||
#equipment-list::-webkit-scrollbar-thumb { | |||
background: #888; | |||
border-radius: 4px; | |||
} | |||
#card-selection-list::-webkit-scrollbar-thumb:hover, | |||
#character-list::-webkit-scrollbar-thumb:hover, | |||
#partner-list::-webkit-scrollbar-thumb:hover, | |||
#equipment-list::-webkit-scrollbar-thumb:hover { | |||
background: #555; | |||
} | |||
/* 响应式设计 */ | |||
@media (max-width: 1200px) { | |||
#team-content { | |||
max-width: 100%; | |||
padding: 10px; | |||
} | |||
.character-unit { | |||
padding: 15px; | |||
} | |||
} | |||
@media (max-width: 768px) { | |||
.character-unit > div { | |||
flex-direction: column; | |||
} | |||
.character-unit > div > div { | |||
width: 100% !important; | |||
} | |||
.deck-area { | |||
min-height: 200px; | |||
} | |||
#card-modal > div, | |||
#character-modal > div, | |||
#partner-modal > div, | |||
#equipment-modal > div { | |||
width: 95%; | |||
max-width: 95%; | |||
min-width: auto; | |||
padding: 15px; | |||
} | |||
.card-type-tab { | |||
padding: 8px 12px; | |||
font-size: 14px; | |||
} | |||
#save-team-btn { | |||
padding: 10px 20px; | |||
font-size: 14px; | |||
} | |||
} | |||
/* 卡牌hover效果 */ | |||
.deck-card-wrapper:hover { | |||
z-index: 10; | |||
} | |||
.card-small-wrapper { | |||
transition: transform 0.2s; | |||
} | |||
.deck-card-wrapper:hover .card-small-wrapper { | |||
transform: scale(1.05); | |||
} | } | ||
/* | /* 加载动画 */ | ||
@keyframes spin { | |||
0% { transform: rotate(0deg); } | |||
100% { transform: rotate(360deg); } | |||
} | } | ||
# | /* 关闭按钮样式 */ | ||
#close-card-modal, | |||
#close-character-modal, | |||
#close-partner-modal, | |||
#close-equipment-modal { | |||
transition: all 0.3s; | transition: all 0.3s; | ||
user-select: none; | |||
} | |||
#close-card-modal:hover, | |||
#close-character-modal:hover, | |||
#close-partner-modal:hover, | |||
#close-equipment-modal:hover { | |||
color: #ff6b6b; | |||
transform: rotate(90deg) scale(1.2); | |||
} | |||
/* 变体对话框按钮动画 */ | |||
.variant-option-btn { | |||
position: relative; | |||
overflow: hidden; | |||
} | |||
.variant-option-btn::before { | |||
content: ''; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
width: 0; | |||
height: 0; | |||
border-radius: 50%; | |||
background: rgba(255,255,255,0.3); | |||
transform: translate(-50%, -50%); | |||
transition: width 0.6s, height 0.6s; | |||
} | |||
.variant-option-btn:hover::before { | |||
width: 300px; | |||
height: 300px; | |||
} | |||
/* 确保弹窗内容居中 */ | |||
#card-modal > div, | |||
#character-modal > div, | |||
#partner-modal > div, | |||
#equipment-modal > div { | |||
box-sizing: border-box; | |||
} | } | ||
# | /* 网格布局优化 */ | ||
#character-list, | |||
#partner-list { | |||
display: grid; | |||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); | |||
gap: 15px; | |||
justify-items: center; | |||
} | } | ||
#equipment-list { | |||
# | display: grid; | ||
display: | grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); | ||
gap: 15px; | |||
justify-items: center; | |||
} | } | ||
/* 图片加载优化 */ | |||
img { | |||
image-rendering: -webkit-optimize-contrast; | |||
} | } | ||
/* 防止文本选择 */ | |||
.character-slot, | |||
.partner-slot, | |||
.deck-area, | |||
.equipment-slot, | |||
.card-type-tab, | |||
#save-team-btn { | |||
user-select: none; | |||
-webkit-user-select: none; | |||
-moz-user-select: none; | |||
-ms-user-select: none; | |||
} | } | ||
/* 工具提示样式(如果需要) */ | |||
[data-tooltip] { | |||
position: relative; | |||
} | } | ||
[data-tooltip]::after { | |||
content: attr(data-tooltip); | |||
position: absolute; | position: absolute; | ||
bottom: 100%; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
padding: 5px 10px; | |||
background: rgba( | background: rgba(0,0,0,0.8); | ||
color: white; | color: white; | ||
border-radius: | border-radius: 4px; | ||
font-size: 12px; | |||
white-space: nowrap; | |||
opacity: 0; | |||
pointer-events: none; | |||
transition: opacity 0.3s; | |||
} | |||
[data-tooltip]:hover::after { | |||
opacity: 1; | |||
} | |||
/* 确保deck-area内的flex布局正确 */ | |||
.deck-area { | |||
box-sizing: border-box; | |||
} | |||
.deck-area > * { | |||
box-sizing: border-box; | |||
} | |||
/* 修复可能的布局问题 */ | |||
.character-unit > div { | |||
box-sizing: border-box; | |||
} | } | ||
. | .character-unit > div > div { | ||
box-sizing: border-box; | |||
} | } | ||
/* | /* 打印样式优化 */ | ||
@media | @media print { | ||
. | #save-team-btn, | ||
.card-delete-btn, | |||
#card-modal, | |||
#character-modal, | |||
#partner-modal, | |||
#equipment-modal { | |||
display: none !important; | |||
} | } | ||
.character-unit { | .character-unit { | ||
page-break-inside: avoid; | |||
} | } | ||
} | |||
/* 无障碍支持 */ | |||
button, [role="button"], .character-option, .partner-option, .equipment-option, .card-type-tab { | |||
outline-offset: 2px; | |||
} | |||
button:focus, [role="button"]:focus, .character-option:focus, .partner-option:focus, .equipment-option:focus, .card-type-tab:focus { | |||
outline: 2px solid #667eea; | |||
} | |||
/* 暗色模式支持(如果需要) */ | |||
@media (prefers-color-scheme: dark) { | |||
/* 可以在这里添加暗色模式样式 */ | |||
} | } | ||
</style> | </style> | ||
2025年11月1日 (六) 16:41的版本
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<script> (function() {
// 等待DOM加载完成
function initTeamSimulator() {
// 为每个角色单元保存独立的状态
var characterUnits = {};
var currentActiveUnit = null;
// 初始化所有角色单元
document.querySelectorAll('.character-unit').forEach(function(unit) {
var unitIndex = unit.getAttribute('data-unit-index');
characterUnits[unitIndex] = {
characterName: null,
characterClass: null,
cardIdCounter: 0,
selectedCards: {}
};
});
// ========== 保存为图片功能 ==========
document.getElementById('save-team-btn').addEventListener('click', function() {
var btn = this;
var originalText = btn.textContent;
btn.textContent = '生成中...';
btn.style.pointerEvents = 'none';
var contentElement = document.getElementById('team-content');
// 临时隐藏删除按钮
var deleteButtons = contentElement.querySelectorAll('.card-delete-btn');
deleteButtons.forEach(function(btn) {
btn.style.display = 'none';
});
html2canvas(contentElement, {
backgroundColor: '#ffffff',
scale: 2,
logging: false,
useCORS: true,
allowTaint: true
}).then(function(canvas) {
// 恢复删除按钮
deleteButtons.forEach(function(btn) {
btn.style.display = 'flex';
});
// 下载图片
var link = document.createElement('a');
link.download = '配队方案_' + new Date().getTime() + '.png';
link.href = canvas.toDataURL('image/png');
link.click();
btn.textContent = originalText;
btn.style.pointerEvents = 'auto';
}).catch(function(error) {
console.error('保存失败:', error);
alert('保存失败,请重试');
// 恢复删除按钮
deleteButtons.forEach(function(btn) {
btn.style.display = 'flex';
});
btn.textContent = originalText;
btn.style.pointerEvents = 'auto';
});
});
// 点击角色槽位显示选择窗口
document.querySelectorAll('.character-slot').forEach(function(slot) {
slot.addEventListener('click', function() {
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
document.getElementById('character-modal').style.display = 'block';
});
});
// 关闭角色选择窗口
document.getElementById('close-character-modal').addEventListener('click', function() {
document.getElementById('character-modal').style.display = 'none';
});
// 点击遮罩层关闭窗口
document.getElementById('character-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
// 加载战斗员卡牌 - 支持多角色
function loadCharacterCards(characterName, unitIndex) {
if (!characterName) {
console.error('战斗员名称为空');
return;
}
var unitData = characterUnits[unitIndex];
unitData.characterName = characterName;
console.log('加载战斗员卡牌:', characterName, '单元:', unitIndex);
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]');
var deckArea = unit.querySelector('.deck-area');
// 显示加载状态
var placeholder = deckArea.querySelector('.deck-placeholder');
if (placeholder) {
placeholder.textContent = '加载中...';
placeholder.style.fontSize = '18px';
placeholder.style.color = '#999';
}
var apiUrl = mw.util.wikiScript('api');
var params = {
action: 'parse',
format: 'json',
text: '错误: 找不到模块 "Module:卡牌/' + characterName + '"',
contentmodel: 'wikitext',
disablelimitreport: true,
wrapoutputclass:
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
// 清空并添加卡牌
deckArea.innerHTML = data.parse.text['*'];
// 重置该单元的卡牌状态
unitData.selectedCards = {};
unitData.cardIdCounter = 0;
setTimeout(function() {
initializeCardFeatures(unitIndex);
}, 100);
} else {
if (placeholder) {
placeholder.textContent = '加载失败';
placeholder.style.color = 'red';
}
}
})
.catch(error => {
console.error('加载卡牌失败:', error);
if (placeholder) {
placeholder.textContent = '加载出错';
placeholder.style.color = 'red';
}
});
}
// 初始化卡牌功能
function initializeCardFeatures(unitIndex) {
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]');
var unitData = characterUnits[unitIndex];
var deckArea = unit.querySelector('.deck-area');
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper');
wrappers.forEach(function(wrapper) {
var card = wrapper.querySelector('.card-small-wrapper');
if (!card) return;
// 确保wrapper样式正确
wrapper.style.flexShrink = '0';
wrapper.style.display = 'inline-block';
var uniqueId = 'deck-card-' + unitIndex + '-' + (++unitData.cardIdCounter);
wrapper.setAttribute('data-unique-id', uniqueId);
wrapper.setAttribute('data-unit-index', unitIndex);
unitData.selectedCards[uniqueId] = {
module: wrapper.getAttribute('data-module') || unitData.characterName,
cardName: wrapper.getAttribute('data-card'),
variantType: null,
variantParam: null,
variantIndex: null
};
if (!card.querySelector('.card-delete-btn')) {
var deleteBtn = document.createElement('div');
deleteBtn.className = 'card-delete-btn';
deleteBtn.innerHTML = '×';
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;';
deleteBtn.addEventListener('click', function(e) {
e.stopPropagation();
wrapper.remove();
delete unitData.selectedCards[uniqueId];
// 如果没有卡牌了,显示占位符
checkAndShowPlaceholder(unitIndex);
});
card.style.position = 'relative';
card.appendChild(deleteBtn);
}
});
setupGlobalModalListener();
}
// 检查并显示占位符
function checkAndShowPlaceholder(unitIndex) {
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]');
var deckArea = unit.querySelector('.deck-area');
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper');
if (wrappers.length === 0) {
deckArea.innerHTML = '
';
}
}
// 设置全局模态框监听器
function setupGlobalModalListener() {
if (window.deckModalObserver) {
window.deckModalObserver.disconnect();
}
window.deckModalObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
var modal = mutation.target;
if (modal.classList.contains('card-modal') && modal.style.display !== 'none') {
setTimeout(function() {
enhanceActiveModal(modal);
}, 100);
}
}
});
});
document.querySelectorAll('.card-modal').forEach(function(modal) {
window.deckModalObserver.observe(modal, {
attributes: true,
attributeFilter: ['style']
});
});
}
// 增强当前活动的模态框
function enhanceActiveModal(modal) {
var cardId = modal.id ? modal.id.replace('-modal', ) : null;
if (!cardId) return;
var deckCard = null;
var uniqueId = null;
var unitIndex = null;
document.querySelectorAll('.deck-area .deck-card-wrapper').forEach(function(wrapper) {
var wrapperCard = wrapper.querySelector('.card-small-wrapper');
if (wrapperCard && wrapperCard.getAttribute('data-card-id') === cardId) {
deckCard = wrapper;
uniqueId = wrapper.getAttribute('data-unique-id');
unitIndex = wrapper.getAttribute('data-unit-index');
}
});
if (!deckCard || !uniqueId || !unitIndex) {
return;
}
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) {
return;
}
if (modal.hasAttribute('data-deck-enhanced')) {
return;
}
modal.setAttribute('data-deck-enhanced', 'true');
var inspirationButton = modal.querySelector('.inspiration-button');
if (inspirationButton) {
inspirationButton.addEventListener('click', function() {
setTimeout(function() {
enhanceInspirationView(modal, uniqueId, unitIndex);
}, 100);
});
}
var godButton = modal.querySelector('.god-inspiration-button');
if (godButton) {
godButton.addEventListener('click', function() {
setTimeout(function() {
enhanceGodView(modal, uniqueId, unitIndex);
}, 100);
});
}
}
// 关闭模态框并恢复滚动
function closeModalAndRestoreScroll(modal) {
modal.style.display = 'none';
modal.removeAttribute('data-deck-enhanced');
document.body.style.overflow = ;
document.body.style.position = ;
document.documentElement.style.overflow = ;
document.body.classList.remove('modal-open');
document.documentElement.classList.remove('modal-open');
window.dispatchEvent(new Event('resize'));
}
// 增强灵光一闪视图
function enhanceInspirationView(modal, uniqueId, unitIndex) {
var inspirationView = modal.querySelector('.inspiration-view');
if (!inspirationView) return;
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) return;
var variants = inspirationView.querySelectorAll('.inspiration-variant');
variants.forEach(function(variant, index) {
if (!variant.querySelector('.select-variant-btn')) {
var selectBtn = document.createElement('div');
selectBtn.className = 'select-variant-btn';
selectBtn.innerHTML = '选择此变体';
selectBtn.style.cssText = 'margin-top:10px;padding:8px 15px;background:linear-gradient(135deg,#28a745 0%,#218838 100%);color:white;font-size:14px;font-weight:bold;border-radius:6px;cursor:pointer;text-align:center;';
selectBtn.addEventListener('click', function() {
replaceCard(uniqueId, unitIndex, '灵光一闪', index + 1);
closeModalAndRestoreScroll(modal);
});
variant.appendChild(selectBtn);
}
});
}
// 增强神光一闪视图
function enhanceGodView(modal, uniqueId, unitIndex) {
var godView = modal.querySelector('.god-inspiration-view');
if (!godView) return;
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) return;
var godGroups = godView.querySelectorAll('.god-group');
godGroups.forEach(function(group) {
var groupNameEl = group.querySelector('div[style*="color:#ffd36a"]');
if (!groupNameEl) return;
var groupName = groupNameEl.textContent.trim();
var variants = group.querySelectorAll('.god-variant-card');
variants.forEach(function(variant, index) {
if (!variant.querySelector('.select-variant-btn')) {
var selectBtn = document.createElement('div');
selectBtn.className = 'select-variant-btn';
selectBtn.innerHTML = '选择';
selectBtn.style.cssText = 'margin-top:5px;padding:6px 12px;background:linear-gradient(135deg,#28a745 0%,#218838 100%);color:white;font-size:12px;font-weight:bold;border-radius:4px;cursor:pointer;text-align:center;';
selectBtn.addEventListener('click', function() {
replaceCard(uniqueId, unitIndex, '神光一闪', groupName, index + 1);
closeModalAndRestoreScroll(modal);
});
variant.appendChild(selectBtn);
}
});
});
}
// 替换卡牌
function replaceCard(uniqueId, unitIndex, variantType, param1, param2) {
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) {
console.error('找不到卡牌数据:', uniqueId);
return;
}
var wrapper = document.querySelector('[data-unique-id="' + uniqueId + '"]');
if (!wrapper) {
console.error('找不到卡牌容器:', uniqueId);
return;
}
cardData.variantType = variantType;
cardData.variantParam = param1;
cardData.variantIndex = param2;
var oldContent = wrapper.innerHTML;
wrapper.innerHTML = '
';
var invokeText = '错误: 找不到模块 "Module:卡牌/' + cardData.module + '"';
var apiUrl = mw.util.wikiScript('api');
var params = {
action: 'parse',
format: 'json',
text: invokeText,
contentmodel: 'wikitext',
disablelimitreport: true
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
wrapper.innerHTML = data.parse.text['*'];
setTimeout(function() {
var newCard = wrapper.querySelector('.card-small-wrapper');
if (newCard) {
// 确保wrapper样式
wrapper.style.flexShrink = '0';
wrapper.style.display = 'inline-block';
var deleteBtn = document.createElement('div');
deleteBtn.className = 'card-delete-btn';
deleteBtn.innerHTML = '×';
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;';
deleteBtn.addEventListener('click', function(e) {
e.stopPropagation();
wrapper.remove();
delete characterUnits[unitIndex].selectedCards[uniqueId];
checkAndShowPlaceholder(unitIndex);
});
newCard.style.position = 'relative';
newCard.appendChild(deleteBtn);
}
setupGlobalModalListener();
document.body.style.overflow = ;
document.documentElement.style.overflow = ;
}, 100);
} else {
wrapper.innerHTML = oldContent;
}
})
.catch(error => {
console.error('替换卡牌失败:', error);
wrapper.innerHTML = oldContent;
document.body.style.overflow = ;
document.documentElement.style.overflow = ;
});
}
// 选择角色
document.getElementById('character-list').addEventListener('click', function(e) {
var characterOption = e.target.closest('.character-option');
if (characterOption && currentActiveUnit) {
var characterName = characterOption.getAttribute('data-character-name') ||
characterOption.getAttribute('data-name') ||
characterOption.getAttribute('title');
var characterClass = characterOption.getAttribute('data-class') ||
characterOption.getAttribute('data-职业');
if (!characterName) {
var nameEl = characterOption.querySelector('.character-name, [class*="name"]');
if (nameEl) characterName = nameEl.textContent.trim();
}
characterUnits[currentActiveUnit].characterClass = characterClass;
var clonedCard = characterOption.cloneNode(true);
clonedCard.classList.remove('character-option');
clonedCard.style.cursor = 'default';
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]');
var characterSlot = unit.querySelector('.character-slot');
characterSlot.innerHTML = ;
characterSlot.appendChild(clonedCard);
characterSlot.style.border = 'none';
document.getElementById('character-modal').style.display = 'none';
if (characterName) {
loadCharacterCards(characterName, currentActiveUnit);
}
}
});
// 选择伙伴
document.querySelectorAll('.partner-slot').forEach(function(slot) {
slot.addEventListener('click', function() {
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
document.getElementById('partner-modal').style.display = 'block';
});
});
document.getElementById('close-partner-modal').addEventListener('click', function() {
document.getElementById('partner-modal').style.display = 'none';
});
document.getElementById('partner-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
document.getElementById('partner-list').addEventListener('click', function(e) {
var partnerOption = e.target.closest('.partner-option');
if (partnerOption && currentActiveUnit) {
var partnerId = partnerOption.dataset.partnerId || partnerOption.getAttribute('data-partner-id');
var partnerImg = document.createElement('img');
partnerImg.src = '/index.php?title=Special:Redirect/file/Portrait_character_wide_' + partnerId + '.png';
partnerImg.style.width = '159px';
partnerImg.style.height = '77px';
partnerImg.style.objectFit = 'cover';
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]');
var partnerSlot = unit.querySelector('.partner-slot');
partnerSlot.innerHTML = ;
partnerSlot.appendChild(partnerImg);
partnerSlot.style.border = 'none';
document.getElementById('partner-modal').style.display = 'none';
}
});
// ========== 卡牌添加功能 ==========
var currentDeckArea = null;
var currentCardType = 'character';
// 点击卡组区域打开卡牌选择
document.querySelectorAll('.deck-area').forEach(function(deckArea) {
var originalClickHandler = function(e) {
if (e.target.closest('.deck-card-wrapper') ||
e.target.closest('.card-small-wrapper') ||
e.target.closest('.card-delete-btn') ||
e.target.classList.contains('card-delete-btn')) {
return;
}
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
currentDeckArea = this;
var unit = this.closest('.character-unit');
var characterSlot = unit.querySelector('.character-slot');
var hasCharacter = characterSlot.querySelector('img') !== null ||
characterSlot.innerHTML.indexOf('data-character-name') > -1 ||
!characterSlot.querySelector('.placeholder');
var unitData = characterUnits[currentActiveUnit];
if (!unitData.characterName) {
hasCharacter = false;
}
if (!hasCharacter) {
alert('请先选择战斗员!');
return;
}
currentCardType = 'character';
document.querySelectorAll('.card-type-tab').forEach(function(tab) {
tab.classList.remove('active');
tab.style.borderBottomColor = 'transparent';
tab.style.fontWeight = 'normal';
});
var characterTab = document.querySelector('.card-type-tab[data-type="character"]');
if (characterTab) {
characterTab.classList.add('active');
characterTab.style.borderBottomColor = '#667eea';
characterTab.style.fontWeight = 'bold';
}
document.getElementById('card-modal').style.display = 'block';
loadCardList('character');
};
deckArea.addEventListener('click', originalClickHandler);
});
// 卡牌类型标签切换
document.querySelectorAll('.card-type-tab').forEach(function(tab) {
tab.addEventListener('click', function() {
var cardType = this.getAttribute('data-type');
currentCardType = cardType;
document.querySelectorAll('.card-type-tab').forEach(function(t) {
t.classList.remove('active');
t.style.borderBottomColor = 'transparent';
t.style.fontWeight = 'normal';
});
this.classList.add('active');
this.style.borderBottomColor = '#667eea';
this.style.fontWeight = 'bold';
loadCardList(cardType);
});
});
// 加载卡牌列表
function loadCardList(cardType) {
var listContainer = document.getElementById('card-selection-list');
listContainer.innerHTML = '
';
var apiUrl = mw.util.wikiScript('api');
var invokeText = ;
if (cardType === 'character') {
var unitData = characterUnits[currentActiveUnit];
if (!unitData.characterName) {
listContainer.innerHTML = '
';
return;
}
invokeText = '错误: 找不到模块 "Module:卡牌/' + unitData.characterName + '"';
} else if (cardType === 'neutral') {
var unitData = characterUnits[currentActiveUnit];
var characterClass = unitData.characterClass;
if (characterClass) {
invokeText = '错误: 没有找到职业为 "' + characterClass + '" 的中立卡牌';
} else {
invokeText = '
';
}
} else if (cardType === 'monster') {
invokeText = '
';
}
var params = {
action: 'parse',
format: 'json',
text: invokeText,
contentmodel: 'wikitext',
disablelimitreport: true,
wrapoutputclass:
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
listContainer.innerHTML = data.parse.text['*'];
setTimeout(function() {
addCardSelectionHandlers(cardType);
}, 100);
} else {
listContainer.innerHTML = '
';
}
})
.catch(error => {
console.error('加载卡牌失败:', error);
listContainer.innerHTML = '
';
});
}
// 添加卡牌选择处理器
function addCardSelectionHandlers(cardType) {
var listContainer = document.getElementById('card-selection-list');
if (cardType === 'character') {
var wrappers = listContainer.querySelectorAll('.deck-card-wrapper');
wrappers.forEach(function(wrapper) {
wrapper.style.cursor = 'pointer';
wrapper.style.transition = 'transform 0.2s';
wrapper.addEventListener('mouseenter', function() {
this.style.transform = 'scale(1.05)';
});
wrapper.addEventListener('mouseleave', function() {
this.style.transform = 'scale(1)';
});
wrapper.addEventListener('click', function(e) {
e.stopPropagation();
var cardName = this.getAttribute('data-card');
var card = this.querySelector('.card-small-wrapper');
if (!cardName && card) {
cardName = card.getAttribute('data-card');
}
if (!cardName) {
console.error('无法获取卡牌名称');
return;
}
var hasInspiration = card && card.querySelector('.inspiration-button');
var hasGodInspiration = card && card.querySelector('.god-inspiration-button');
if (hasInspiration || hasGodInspiration) {
showVariantSelectionDialog(cardName, 'character');
} else {
addCardToDeckByName(cardName, 'character');
}
});
});
} else {
var cards = listContainer.querySelectorAll('.card-small-wrapper');
cards.forEach(function(card) {
card.style.cursor = 'pointer';
card.style.transition = 'transform 0.2s';
card.addEventListener('mouseenter', function() {
this.style.transform = 'scale(1.05)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'scale(1)';
});
card.addEventListener('click', function(e) {
e.stopPropagation();
addCardToDeck(this, cardType);
});
});
}
}
// 显示变体选择对话框
function showVariantSelectionDialog(cardName, cardType) {
var dialog = document.createElement('div');
dialog.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:30px;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,0.3);z-index:10001;min-width:300px;';
var html = '
选择添加方式
'; html += '
卡牌: ' + cardName + '
'; html += '
';
dialog.innerHTML = html;
var overlay = document.createElement('div');
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:10000;';
document.body.appendChild(overlay);
document.body.appendChild(dialog);
dialog.querySelectorAll('.variant-option-btn').forEach(function(btn) {
btn.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-2px)';
this.style.boxShadow = '0 5px 15px rgba(0,0,0,0.2)';
});
btn.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
this.style.boxShadow = 'none';
});
});
dialog.addEventListener('click', function(e) {
var btn = e.target.closest('.variant-option-btn');
if (!btn) return;
var action = btn.getAttribute('data-action');
if (action === 'base') {
addCardToDeckByName(cardName, cardType);
document.body.removeChild(overlay);
document.body.removeChild(dialog);
document.getElementById('card-modal').style.display = 'none';
} else if (action === 'view') {
addCardToDeckByName(cardName, cardType, function() {
document.body.removeChild(overlay);
document.body.removeChild(dialog);
document.getElementById('card-modal').style.display = 'none';
setTimeout(function() {
alert('卡牌已添加!现在您可以点击卡牌查看并选择变体。');
}, 300);
});
} else {
document.body.removeChild(overlay);
document.body.removeChild(dialog);
}
});
}
// 按名称添加卡牌到卡组
function addCardToDeckByName(cardName, cardType, callback) {
if (!currentDeckArea || !currentActiveUnit) return;
var unitData = characterUnits[currentActiveUnit];
var moduleName = ;
if (cardType === 'character') {
moduleName = unitData.characterName;
} else if (cardType === 'neutral') {
moduleName = '中立';
} else if (cardType === 'monster') {
moduleName = '怪物';
}
var invokeText = ;
if (cardType === 'character') {
invokeText = '错误: 找不到模块 "Module:卡牌/' + moduleName + '"';
} else if (cardType === 'neutral') {
invokeText = '错误: 找不到中立卡牌 "' + cardName + '"';
} else if (cardType === 'monster') {
invokeText = '错误: 找不到怪物 "' + cardName + '"';
}
var apiUrl = mw.util.wikiScript('api');
var params = {
action: 'parse',
format: 'json',
text: invokeText,
contentmodel: 'wikitext',
disablelimitreport: true
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
// 移除占位符
var placeholder = currentDeckArea.querySelector('.deck-placeholder');
if (placeholder) {
placeholder.remove();
}
var wrapper = document.createElement('div');
wrapper.className = 'deck-card-wrapper';
wrapper.innerHTML = data.parse.text['*'];
wrapper.setAttribute('data-module', moduleName);
wrapper.setAttribute('data-card', cardName);
// 确保wrapper不会换行
wrapper.style.flexShrink = '0';
wrapper.style.display = 'inline-block';
var uniqueId = 'deck-card-' + currentActiveUnit + '-' + (++unitData.cardIdCounter);
wrapper.setAttribute('data-unique-id', uniqueId);
wrapper.setAttribute('data-unit-index', currentActiveUnit);
unitData.selectedCards[uniqueId] = {
module: moduleName,
cardName: cardName,
variantType: null,
variantParam: null,
variantIndex: null
};
currentDeckArea.appendChild(wrapper);
setTimeout(function() {
var card = wrapper.querySelector('.card-small-wrapper');
if (card) {
var deleteBtn = document.createElement('div');
deleteBtn.className = 'card-delete-btn';
deleteBtn.innerHTML = '×';
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;';
deleteBtn.addEventListener('click', function(e) {
e.stopPropagation();
wrapper.remove();
delete unitData.selectedCards[uniqueId];
checkAndShowPlaceholder(currentActiveUnit);
});
card.style.position = 'relative';
card.appendChild(deleteBtn);
}
setupGlobalModalListener();
if (callback) callback();
}, 100);
} else {
alert('添加卡牌失败');
}
})
.catch(error => {
console.error('添加卡牌失败:', error);
alert('添加卡牌出错:' + error.message);
});
}
// 添加卡牌到卡组(从元素获取信息)
function addCardToDeck(cardElement, cardType) {
if (!currentDeckArea || !currentActiveUnit) return;
var cardName = cardElement.getAttribute('data-card-name') ||
cardElement.getAttribute('data-card');
if (!cardName) {
var parent = cardElement.closest('[data-card]');
if (parent) {
cardName = parent.getAttribute('data-card');
}
}
if (!cardName) {
var parent = cardElement.closest('[data-card-name]');
if (parent) {
cardName = parent.getAttribute('data-card-name');
}
}
if (!cardName) {
var wrapper = cardElement.closest('.deck-card-wrapper');
if (wrapper) {
cardName = wrapper.getAttribute('data-card');
}
}
if (!cardName) {
console.error('无法获取卡牌名称');
alert('错误:无法获取卡牌名称');
return;
}
addCardToDeckByName(cardName, cardType, function() {
document.getElementById('card-modal').style.display = 'none';
});
}
// 关闭卡牌选择窗口
document.getElementById('close-card-modal').addEventListener('click', function() {
document.getElementById('card-modal').style.display = 'none';
});
document.getElementById('card-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
// ========== 装备选择功能 ==========
document.querySelectorAll('.equipment-slot').forEach(function(slot) {
slot.addEventListener('click', function() {
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
var equipmentType = this.getAttribute('data-equipment-type');
var titleMap = {
'weapon': '选择武器',
'armor': '选择装甲',
'ring': '选择戒指'
};
document.getElementById('equipment-modal-title').textContent = titleMap[equipmentType] || '选择装备';
loadEquipmentList(equipmentType);
document.getElementById('equipment-modal').style.display = 'block';
});
});
document.getElementById('close-equipment-modal').addEventListener('click', function() {
document.getElementById('equipment-modal').style.display = 'none';
});
document.getElementById('equipment-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
function loadEquipmentList(equipmentType) {
var listContainer = document.getElementById('equipment-list');
listContainer.innerHTML = '
';
var categoryMap = {
'weapon': '武器',
'armor': '装甲',
'ring': '戒指'
};
var category = categoryMap[equipmentType];
var apiUrl = mw.util.wikiScript('api');
var askQuery = ;
var params = {
action: 'parse',
format: 'json',
text: askQuery,
contentmodel: 'wikitext',
disablelimitreport: true
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
listContainer.innerHTML = data.parse.text['*'];
setTimeout(function() {
addEquipmentSelectionHandlers(equipmentType);
}, 100);
} else {
listContainer.innerHTML = '
';
}
})
.catch(error => {
console.error('加载装备失败:', error);
listContainer.innerHTML = '
';
});
}
function addEquipmentSelectionHandlers(equipmentType) {
var equipmentOptions = document.querySelectorAll('#equipment-list .equipment-option');
equipmentOptions.forEach(function(option) {
option.style.cursor = 'pointer';
option.style.transition = 'all 0.3s';
option.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-5px)';
this.style.boxShadow = '0 5px 20px rgba(102,126,234,0.4)';
});
option.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
this.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
});
option.addEventListener('click', function() {
var equipmentId = this.getAttribute('data-equipment-id');
var equipmentImg = this.querySelector('img');
if (equipmentImg && currentActiveUnit) {
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]');
var slot = unit.querySelector('.equipment-slot[data-equipment-type="' + equipmentType + '"]');
var clonedImg = equipmentImg.cloneNode(true);
clonedImg.style.width = '100px';
clonedImg.style.height = '100px';
clonedImg.style.objectFit = 'contain';
slot.innerHTML = ;
slot.appendChild(clonedImg);
slot.style.border = 'none';
document.getElementById('equipment-modal').style.display = 'none';
}
});
});
}
// 初始化:设置默认角色1为激活单元
currentActiveUnit = '0';
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTeamSimulator);
} else {
initTeamSimulator();
}
})(); </script>
<style>
- team-simulator {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
- save-team-btn:hover {
transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0,0,0,0.15);
}
- save-team-btn:active {
transform: translateY(0);
}
.character-unit {
background: white; transition: all 0.3s;
}
.character-slot, .partner-slot {
transition: all 0.3s; overflow: hidden;
}
.character-slot:hover, .partner-slot:hover {
border-color: #667eea; background: #f9f9ff;
}
.deck-area {
transition: border-color 0.3s, background 0.3s;
}
.deck-area:hover {
border-color: #667eea;
}
/* 确保卡牌wrapper不换行 */ .deck-card-wrapper {
flex-shrink: 0; display: inline-block;
}
/* 确保中立和怪物卡牌也不换行 */
- card-selection-list .deck-card-wrapper,
- card-selection-list .card-small-wrapper {
flex-shrink: 0; display: inline-block;
}
.equipment-slot {
transition: all 0.3s;
}
.equipment-slot:hover {
border-color: #667eea; background: #f9f9ff;
}
/* 模态框样式优化 */
- card-modal, #character-modal, #partner-modal, #equipment-modal {
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 模态框内容动画 */
- card-modal > div,
- character-modal > div,
- partner-modal > div,
- equipment-modal > div {
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
transform: translate(-50%, -60%);
opacity: 0;
}
to {
transform: translate(-50%, -50%);
opacity: 1;
}
}
/* 卡牌类型标签样式 */ .card-type-tab {
transition: all 0.3s;
}
.card-type-tab:hover {
color: #667eea; background: rgba(102, 126, 234, 0.05);
}
.card-type-tab.active {
color: #667eea;
}
/* 角色和伙伴选项样式 */ .character-option, .partner-option {
transition: all 0.3s;
}
.character-option:hover, .partner-option:hover {
transform: translateY(-5px); box-shadow: 0 5px 20px rgba(102,126,234,0.4);
}
/* 装备选项样式 */ .equipment-option {
cursor: pointer; padding: 10px; border: 2px solid transparent; border-radius: 8px; transition: all 0.3s; background: white;
}
.equipment-option:hover {
border-color: #667eea; transform: translateY(-5px); box-shadow: 0 5px 20px rgba(102,126,234,0.4);
}
/* 删除按钮样式优化 */ .card-delete-btn {
transition: all 0.2s; user-select: none;
}
.card-delete-btn:hover {
background: rgba(255,0,0,0.9); transform: scale(1.2);
}
/* 占位符样式 */ .deck-placeholder {
pointer-events: none; user-select: none;
}
/* 变体选择按钮样式 */ .select-variant-btn {
transition: all 0.3s; user-select: none;
}
.select-variant-btn:hover {
transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.select-variant-btn:active {
transform: translateY(0);
}
/* 卡牌选择列表样式优化 */
- card-selection-list {
max-height: 60vh; overflow-y: auto;
}
/* 自定义滚动条 */
- card-selection-list::-webkit-scrollbar,
- character-list::-webkit-scrollbar,
- partner-list::-webkit-scrollbar,
- equipment-list::-webkit-scrollbar {
width: 8px;
}
- card-selection-list::-webkit-scrollbar-track,
- character-list::-webkit-scrollbar-track,
- partner-list::-webkit-scrollbar-track,
- equipment-list::-webkit-scrollbar-track {
background: #f1f1f1; border-radius: 4px;
}
- card-selection-list::-webkit-scrollbar-thumb,
- character-list::-webkit-scrollbar-thumb,
- partner-list::-webkit-scrollbar-thumb,
- equipment-list::-webkit-scrollbar-thumb {
background: #888; border-radius: 4px;
}
- card-selection-list::-webkit-scrollbar-thumb:hover,
- character-list::-webkit-scrollbar-thumb:hover,
- partner-list::-webkit-scrollbar-thumb:hover,
- equipment-list::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* 响应式设计 */ @media (max-width: 1200px) {
#team-content {
max-width: 100%;
padding: 10px;
}
.character-unit {
padding: 15px;
}
}
@media (max-width: 768px) {
.character-unit > div {
flex-direction: column;
}
.character-unit > div > div {
width: 100% !important;
}
.deck-area {
min-height: 200px;
}
#card-modal > div,
#character-modal > div,
#partner-modal > div,
#equipment-modal > div {
width: 95%;
max-width: 95%;
min-width: auto;
padding: 15px;
}
.card-type-tab {
padding: 8px 12px;
font-size: 14px;
}
#save-team-btn {
padding: 10px 20px;
font-size: 14px;
}
}
/* 卡牌hover效果 */ .deck-card-wrapper:hover {
z-index: 10;
}
.card-small-wrapper {
transition: transform 0.2s;
}
.deck-card-wrapper:hover .card-small-wrapper {
transform: scale(1.05);
}
/* 加载动画 */ @keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 关闭按钮样式 */
- close-card-modal,
- close-character-modal,
- close-partner-modal,
- close-equipment-modal {
transition: all 0.3s; user-select: none;
}
- close-card-modal:hover,
- close-character-modal:hover,
- close-partner-modal:hover,
- close-equipment-modal:hover {
color: #ff6b6b; transform: rotate(90deg) scale(1.2);
}
/* 变体对话框按钮动画 */ .variant-option-btn {
position: relative; overflow: hidden;
}
.variant-option-btn::before {
content: ; position: absolute; top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; background: rgba(255,255,255,0.3); transform: translate(-50%, -50%); transition: width 0.6s, height 0.6s;
}
.variant-option-btn:hover::before {
width: 300px; height: 300px;
}
/* 确保弹窗内容居中 */
- card-modal > div,
- character-modal > div,
- partner-modal > div,
- equipment-modal > div {
box-sizing: border-box;
}
/* 网格布局优化 */
- character-list,
- partner-list {
display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 15px; justify-items: center;
}
- equipment-list {
display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 15px; justify-items: center;
}
/* 图片加载优化 */ img {
image-rendering: -webkit-optimize-contrast;
}
/* 防止文本选择 */ .character-slot, .partner-slot, .deck-area, .equipment-slot, .card-type-tab,
- save-team-btn {
user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;
}
/* 工具提示样式(如果需要) */ [data-tooltip] {
position: relative;
}
[data-tooltip]::after {
content: attr(data-tooltip); position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); padding: 5px 10px; background: rgba(0,0,0,0.8); color: white; border-radius: 4px; font-size: 12px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity 0.3s;
}
[data-tooltip]:hover::after {
opacity: 1;
}
/* 确保deck-area内的flex布局正确 */ .deck-area {
box-sizing: border-box;
}
.deck-area > * {
box-sizing: border-box;
}
/* 修复可能的布局问题 */ .character-unit > div {
box-sizing: border-box;
}
.character-unit > div > div {
box-sizing: border-box;
}
/* 打印样式优化 */ @media print {
#save-team-btn,
.card-delete-btn,
#card-modal,
#character-modal,
#partner-modal,
#equipment-modal {
display: none !important;
}
.character-unit {
page-break-inside: avoid;
}
}
/* 无障碍支持 */ button, [role="button"], .character-option, .partner-option, .equipment-option, .card-type-tab {
outline-offset: 2px;
}
button:focus, [role="button"]:focus, .character-option:focus, .partner-option:focus, .equipment-option:focus, .card-type-tab:focus {
outline: 2px solid #667eea;
}
/* 暗色模式支持(如果需要) */ @media (prefers-color-scheme: dark) {
/* 可以在这里添加暗色模式样式 */
} </style>









































