配队模拟器:修订间差异
来自卡厄思梦境WIKI
小无编辑摘要 |
无编辑摘要 |
||
| 第1行: | 第1行: | ||
<script> | <script> | ||
(function() { | (function() { | ||
// 等待DOM加载完成 | // 等待DOM加载完成 | ||
function initTeamSimulator() { | function initTeamSimulator() { | ||
// | // 为每个角色单元保存独立的状态 | ||
var | var characterUnits = {}; | ||
var | var currentActiveUnit = null; | ||
var selectedCards | |||
// 初始化所有角色单元 | |||
document.querySelectorAll('.character-unit').forEach(function(unit) { | |||
var unitIndex = unit.getAttribute('data-unit-index'); | |||
characterUnits[unitIndex] = { | |||
characterName: null, | |||
cardIdCounter: 0, | |||
selectedCards: {} | |||
}; | |||
}); | |||
// 点击角色槽位显示选择窗口 | // 点击角色槽位显示选择窗口 - 支持多角色 | ||
document. | 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'; | |||
}); | |||
}); | }); | ||
| 第25行: | 第38行: | ||
}); | }); | ||
// 加载战斗员卡牌 | // 加载战斗员卡牌 - 支持多角色 | ||
function loadCharacterCards(characterName) { | function loadCharacterCards(characterName, unitIndex) { | ||
if (!characterName) { | if (!characterName) { | ||
console.error('战斗员名称为空'); | console.error('战斗员名称为空'); | ||
| 第32行: | 第45行: | ||
} | } | ||
var unitData = characterUnits[unitIndex]; | |||
console.log('加载战斗员卡牌:', characterName); | unitData.characterName = characterName; | ||
console.log('加载战斗员卡牌:', characterName, '单元:', unitIndex); | |||
// | // 找到对应单元的卡组区域 | ||
var deckArea = | var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | ||
var deckArea = unit.querySelector('.deck-area'); | |||
deckArea.innerHTML = '<div style="color:#999;font-size:18px;">加载中...</div>'; | deckArea.innerHTML = '<div style="color:#999;font-size:18px;">加载中...</div>'; | ||
| 第58行: | 第73行: | ||
deckArea.style.padding = '10px'; | deckArea.style.padding = '10px'; | ||
// | // 重置该单元的卡牌状态 | ||
selectedCards = {}; | unitData.selectedCards = {}; | ||
cardIdCounter = 0; | unitData.cardIdCounter = 0; | ||
// 为每张卡牌添加功能 | // 为每张卡牌添加功能 | ||
setTimeout(function() { | setTimeout(function() { | ||
initializeCardFeatures(); | initializeCardFeatures(unitIndex); | ||
}, 100); | }, 100); | ||
} else { | } else { | ||
| 第76行: | 第91行: | ||
} | } | ||
// 初始化卡牌功能 | // 初始化卡牌功能 - 支持多角色 | ||
function initializeCardFeatures() { | function initializeCardFeatures(unitIndex) { | ||
var wrappers = | var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | ||
var unitData = characterUnits[unitIndex]; | |||
var wrappers = unit.querySelectorAll('.deck-area .deck-card-wrapper'); | |||
wrappers.forEach(function(wrapper) { | wrappers.forEach(function(wrapper) { | ||
| 第84行: | 第101行: | ||
if (!card) return; | if (!card) return; | ||
// | // 给每个wrapper分配唯一ID(包含单元索引) | ||
var uniqueId = 'deck-card-' + (++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); | |||
// 记录原始状态 | // 记录原始状态 | ||
selectedCards[uniqueId] = { | unitData.selectedCards[uniqueId] = { | ||
module: wrapper.getAttribute('data-module') || | module: wrapper.getAttribute('data-module') || unitData.characterName, | ||
cardName: wrapper.getAttribute('data-card'), | cardName: wrapper.getAttribute('data-card'), | ||
variantType: null, | variantType: null, | ||
| 第107行: | 第125行: | ||
e.stopPropagation(); | e.stopPropagation(); | ||
wrapper.remove(); | wrapper.remove(); | ||
delete selectedCards[uniqueId]; | delete unitData.selectedCards[uniqueId]; | ||
}); | }); | ||
| 第159行: | 第177行: | ||
var deckCard = null; | var deckCard = null; | ||
var uniqueId = null; | var uniqueId = null; | ||
var unitIndex = null; | |||
// 遍历所有deck中的卡牌,找到匹配的那个 | // 遍历所有deck中的卡牌,找到匹配的那个 | ||
document.querySelectorAll(' | document.querySelectorAll('.deck-area .deck-card-wrapper').forEach(function(wrapper) { | ||
var wrapperCard = wrapper.querySelector('.card-small-wrapper'); | var wrapperCard = wrapper.querySelector('.card-small-wrapper'); | ||
if (wrapperCard && wrapperCard.getAttribute('data-card-id') === cardId) { | if (wrapperCard && wrapperCard.getAttribute('data-card-id') === cardId) { | ||
deckCard = wrapper; | deckCard = wrapper; | ||
uniqueId = wrapper.getAttribute('data-unique-id'); | uniqueId = wrapper.getAttribute('data-unique-id'); | ||
unitIndex = wrapper.getAttribute('data-unit-index'); | |||
} | } | ||
}); | }); | ||
if (!deckCard || !uniqueId) { | if (!deckCard || !uniqueId || !unitIndex) { | ||
console.log('未找到对应的deck卡牌'); | console.log('未找到对应的deck卡牌'); | ||
return; | return; | ||
} | } | ||
var cardData = selectedCards[uniqueId]; | var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | ||
if (!cardData) { | if (!cardData) { | ||
console.log('未找到卡牌数据:', uniqueId); | console.log('未找到卡牌数据:', uniqueId); | ||
| 第193行: | 第213行: | ||
inspirationButton.addEventListener('click', function() { | inspirationButton.addEventListener('click', function() { | ||
setTimeout(function() { | setTimeout(function() { | ||
enhanceInspirationView(modal, uniqueId); | enhanceInspirationView(modal, uniqueId, unitIndex); | ||
}, 100); | }, 100); | ||
}); | }); | ||
| 第203行: | 第223行: | ||
godButton.addEventListener('click', function() { | godButton.addEventListener('click', function() { | ||
setTimeout(function() { | setTimeout(function() { | ||
enhanceGodView(modal, uniqueId); | enhanceGodView(modal, uniqueId, unitIndex); | ||
}, 100); | }, 100); | ||
}); | }); | ||
| 第231行: | 第251行: | ||
// 增强灵光一闪视图 | // 增强灵光一闪视图 | ||
function enhanceInspirationView(modal, uniqueId) { | function enhanceInspirationView(modal, uniqueId, unitIndex) { | ||
var inspirationView = modal.querySelector('.inspiration-view'); | var inspirationView = modal.querySelector('.inspiration-view'); | ||
if (!inspirationView) return; | if (!inspirationView) return; | ||
var cardData = selectedCards[uniqueId]; | var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | ||
if (!cardData) return; | if (!cardData) return; | ||
| 第250行: | 第270行: | ||
selectBtn.addEventListener('click', function() { | selectBtn.addEventListener('click', function() { | ||
console.log('选择灵光一闪变体', index + 1, '对于卡牌:', cardData.cardName); | console.log('选择灵光一闪变体', index + 1, '对于卡牌:', cardData.cardName); | ||
replaceCard(uniqueId, '灵光一闪', index + 1); | replaceCard(uniqueId, unitIndex, '灵光一闪', index + 1); | ||
closeModalAndRestoreScroll(modal); | closeModalAndRestoreScroll(modal); | ||
}); | }); | ||
| 第260行: | 第280行: | ||
// 增强神光一闪视图 | // 增强神光一闪视图 | ||
function enhanceGodView(modal, uniqueId) { | function enhanceGodView(modal, uniqueId, unitIndex) { | ||
var godView = modal.querySelector('.god-inspiration-view'); | var godView = modal.querySelector('.god-inspiration-view'); | ||
if (!godView) return; | if (!godView) return; | ||
var cardData = selectedCards[uniqueId]; | var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | ||
if (!cardData) return; | if (!cardData) return; | ||
| 第286行: | 第306行: | ||
selectBtn.addEventListener('click', function() { | selectBtn.addEventListener('click', function() { | ||
console.log('选择神光一闪变体', groupName, index + 1, '对于卡牌:', cardData.cardName); | console.log('选择神光一闪变体', groupName, index + 1, '对于卡牌:', cardData.cardName); | ||
replaceCard(uniqueId, '神光一闪', groupName, index + 1); | replaceCard(uniqueId, unitIndex, '神光一闪', groupName, index + 1); | ||
closeModalAndRestoreScroll(modal); | closeModalAndRestoreScroll(modal); | ||
}); | }); | ||
| 第297行: | 第317行: | ||
// 替换卡牌 | // 替换卡牌 | ||
function replaceCard(uniqueId, variantType, param1, param2) { | function replaceCard(uniqueId, unitIndex, variantType, param1, param2) { | ||
var cardData = selectedCards[uniqueId]; | var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | ||
if (!cardData) { | if (!cardData) { | ||
console.error('找不到卡牌数据:', uniqueId); | console.error('找不到卡牌数据:', uniqueId); | ||
| 第361行: | 第381行: | ||
e.stopPropagation(); | e.stopPropagation(); | ||
wrapper.remove(); | wrapper.remove(); | ||
delete selectedCards[uniqueId]; | delete characterUnits[unitIndex].selectedCards[uniqueId]; | ||
}); | }); | ||
| 第389行: | 第409行: | ||
} | } | ||
// 选择角色 - | // 选择角色 - 使用事件委托,支持多角色 | ||
document.getElementById('character-list').addEventListener('click', function(e) { | document.getElementById('character-list').addEventListener('click', function(e) { | ||
var characterOption = e.target.closest('.character-option'); | var characterOption = e.target.closest('.character-option'); | ||
if (characterOption) { | if (characterOption && currentActiveUnit) { | ||
// 获取战斗员名称 | // 获取战斗员名称 | ||
var characterName = characterOption.getAttribute('data-character-name') || | var characterName = characterOption.getAttribute('data-character-name') || | ||
| 第403行: | 第423行: | ||
} | } | ||
console.log('选中的战斗员:', characterName); | console.log('选中的战斗员:', characterName, '单元:', currentActiveUnit); | ||
// 克隆卡片显示 | // 克隆卡片显示 | ||
| 第410行: | 第430行: | ||
clonedCard.style.cursor = 'default'; | clonedCard.style.cursor = 'default'; | ||
var characterSlot = | var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]'); | ||
var characterSlot = unit.querySelector('.character-slot'); | |||
characterSlot.innerHTML = ''; | characterSlot.innerHTML = ''; | ||
characterSlot.appendChild(clonedCard); | characterSlot.appendChild(clonedCard); | ||
| 第418行: | 第439行: | ||
if (characterName) { | if (characterName) { | ||
loadCharacterCards(characterName); | loadCharacterCards(characterName, currentActiveUnit); | ||
} | } | ||
} | } | ||
}); | }); | ||
// 伙伴相关代码 | // 伙伴相关代码 - 支持多角色 | ||
document. | 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'; | |||
}); | |||
}); | }); | ||
| 第440行: | 第464行: | ||
document.getElementById('partner-list').addEventListener('click', function(e) { | document.getElementById('partner-list').addEventListener('click', function(e) { | ||
var partnerOption = e.target.closest('.partner-option'); | var partnerOption = e.target.closest('.partner-option'); | ||
if (partnerOption) { | if (partnerOption && currentActiveUnit) { | ||
var partnerId = partnerOption.dataset.partnerId || partnerOption.getAttribute('data-partner-id'); | var partnerId = partnerOption.dataset.partnerId || partnerOption.getAttribute('data-partner-id'); | ||
| 第449行: | 第473行: | ||
partnerImg.style.objectFit = 'cover'; | partnerImg.style.objectFit = 'cover'; | ||
var partnerSlot = | var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]'); | ||
var partnerSlot = unit.querySelector('.partner-slot'); | |||
partnerSlot.innerHTML = ''; | partnerSlot.innerHTML = ''; | ||
partnerSlot.appendChild(partnerImg); | partnerSlot.appendChild(partnerImg); | ||
| 第458行: | 第483行: | ||
}); | }); | ||
// 装备相关代码 | // 装备相关代码 - 支持多角色 | ||
// 装备类型映射 | // 装备类型映射 | ||
var equipmentTypes = { | var equipmentTypes = { | ||
'weapon | 'weapon': { type: '武器', title: '选择武器' }, | ||
'armor | 'armor': { type: '装甲', title: '选择装甲' }, | ||
'ring | 'ring': { type: '戒指', title: '选择戒指' } | ||
}; | }; | ||
| 第470行: | 第495行: | ||
// 装备槽位点击事件 | // 装备槽位点击事件 | ||
document.querySelectorAll('.equipment-slot').forEach(function(slot) { | |||
slot.addEventListener('click', function() { | |||
currentEquipmentSlot = | currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index'); | ||
loadEquipmentList(equipmentTypes[ | currentEquipmentSlot = this; | ||
var equipmentType = this.getAttribute('data-equipment-type'); | |||
loadEquipmentList(equipmentTypes[equipmentType]); | |||
}); | }); | ||
}); | }); | ||
| 第582行: | 第609行: | ||
// 放置到对应槽位 | // 放置到对应槽位 | ||
currentEquipmentSlot.innerHTML = ''; | |||
currentEquipmentSlot.appendChild(clonedCard); | |||
currentEquipmentSlot.style.border = 'none'; | |||
currentEquipmentSlot.style.padding = '0'; | |||
// 关闭模态框 | // 关闭模态框 | ||
| 第606行: | 第632行: | ||
} | } | ||
}); | }); | ||
// ========== 保存为图片功能 ========== | |||
document.getElementById('save-team-btn').addEventListener('click', function() { | |||
saveTeamAsImage(); | |||
}); | |||
function saveTeamAsImage() { | |||
var button = document.getElementById('save-team-btn'); | |||
var originalText = button.textContent; | |||
button.textContent = '正在生成图片...'; | |||
button.style.pointerEvents = 'none'; | |||
button.style.opacity = '0.6'; | |||
// 动态加载html2canvas库 | |||
if (typeof html2canvas === 'undefined') { | |||
var script = document.createElement('script'); | |||
script.src = 'https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js'; | |||
script.onload = function() { | |||
captureTeam(button, originalText); | |||
}; | |||
script.onerror = function() { | |||
alert('加载图片生成库失败,请检查网络连接'); | |||
button.textContent = originalText; | |||
button.style.pointerEvents = ''; | |||
button.style.opacity = ''; | |||
}; | |||
document.head.appendChild(script); | |||
} else { | |||
captureTeam(button, originalText); | |||
} | |||
} | |||
function captureTeam(button, originalText) { | |||
var teamContent = document.getElementById('team-content'); | |||
// 临时隐藏删除按钮 | |||
var deleteButtons = teamContent.querySelectorAll('.card-delete-btn'); | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = 'none'; | |||
}); | |||
html2canvas(teamContent, { | |||
backgroundColor: '#ffffff', | |||
scale: 2, | |||
logging: false, | |||
useCORS: true, | |||
allowTaint: true | |||
}).then(function(canvas) { | |||
// 恢复删除按钮 | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = ''; | |||
}); | |||
// 转换为图片并下载 | |||
canvas.toBlob(function(blob) { | |||
var url = URL.createObjectURL(blob); | |||
var link = document.createElement('a'); | |||
var timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5); | |||
link.download = '队伍配置_' + timestamp + '.png'; | |||
link.href = url; | |||
link.click(); | |||
URL.revokeObjectURL(url); | |||
button.textContent = originalText; | |||
button.style.pointerEvents = ''; | |||
button.style.opacity = ''; | |||
}); | |||
}).catch(function(error) { | |||
console.error('生成图片失败:', error); | |||
alert('生成图片失败: ' + error.message); | |||
// 恢复删除按钮 | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = ''; | |||
}); | |||
button.textContent = originalText; | |||
button.style.pointerEvents = ''; | |||
button.style.opacity = ''; | |||
}); | |||
} | |||
// 页面卸载时清理 | // 页面卸载时清理 | ||
| 第645行: | 第752行: | ||
<style> | <style> | ||
.character-option { | |||
cursor: pointer; | |||
transition: transform 0.2s; | |||
} | |||
.character-option:hover { | .character-option:hover { | ||
transform: scale(1.05); | transform: scale(1.05); | ||
| 第778行: | 第890行: | ||
.god-inspiration-view > *:first-child { | .god-inspiration-view > *:first-child { | ||
margin-top: 0; | margin-top: 0; | ||
} | |||
/* 保存按钮hover效果 */ | |||
#save-team-btn:hover { | |||
transform: translateY(-2px); | |||
box-shadow: 0 6px 12px rgba(0,0,0,0.2); | |||
opacity: 0.95; | |||
} | |||
#save-team-btn:active { | |||
transform: translateY(0); | |||
box-shadow: 0 4px 6px rgba(0,0,0,0.1); | |||
} | |||
/* 角色单元样式 */ | |||
.character-unit { | |||
transition: box-shadow 0.3s; | |||
} | |||
.character-unit:hover { | |||
box-shadow: 0 2px 8px rgba(0,0,0,0.1); | |||
} | } | ||
</style> | </style> | ||
2025年10月19日 (日) 17:49的版本
<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,
cardIdCounter: 0,
selectedCards: {}
};
});
// 点击角色槽位显示选择窗口 - 支持多角色
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');
deckArea.innerHTML = '
';
// 通过API调用模块获取卡牌HTML
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['*'];
deckArea.style.border = 'none';
deckArea.style.padding = '10px';
// 重置该单元的卡牌状态
unitData.selectedCards = {};
unitData.cardIdCounter = 0;
// 为每张卡牌添加功能
setTimeout(function() {
initializeCardFeatures(unitIndex);
}, 100);
} else {
deckArea.innerHTML = '
';
}
})
.catch(error => {
console.error('加载卡牌失败:', error);
deckArea.innerHTML = '
';
});
}
// 初始化卡牌功能 - 支持多角色
function initializeCardFeatures(unitIndex) {
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]');
var unitData = characterUnits[unitIndex];
var wrappers = unit.querySelectorAll('.deck-area .deck-card-wrapper');
wrappers.forEach(function(wrapper) {
var card = wrapper.querySelector('.card-small-wrapper');
if (!card) return;
// 给每个wrapper分配唯一ID(包含单元索引)
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];
});
card.style.position = 'relative';
card.appendChild(deleteBtn);
}
});
// 全局监听卡牌模态框的显示
setupGlobalModalListener();
}
// 设置全局模态框监听器
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;
// 查找对应的deck卡牌
var deckCard = null;
var uniqueId = null;
var unitIndex = null;
// 遍历所有deck中的卡牌,找到匹配的那个
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) {
console.log('未找到对应的deck卡牌');
return;
}
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) {
console.log('未找到卡牌数据:', uniqueId);
return;
}
console.log('增强模态框,卡牌:', cardData.cardName);
// 标记已处理
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';
// 移除可能存在的data属性
modal.removeAttribute('data-deck-enhanced');
// 确保body可以滚动
document.body.style.overflow = ;
document.body.style.position = ;
document.documentElement.style.overflow = ;
// 移除可能存在的其他样式
document.body.classList.remove('modal-open');
document.documentElement.classList.remove('modal-open');
// 触发resize事件,有些框架依赖这个
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;
console.log('增强灵光一闪视图,卡牌:', cardData.cardName);
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() {
console.log('选择灵光一闪变体', index + 1, '对于卡牌:', cardData.cardName);
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;
console.log('增强神光一闪视图,卡牌:', cardData.cardName);
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() {
console.log('选择神光一闪变体', groupName, index + 1, '对于卡牌:', cardData.cardName);
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;
}
console.log('替换卡牌:', cardData.cardName, '变体类型:', variantType, '参数:', param1, param2);
// 更新记录
cardData.variantType = variantType;
cardData.variantParam = param1;
cardData.variantIndex = param2;
// 显示加载中
var oldContent = wrapper.innerHTML;
wrapper.innerHTML = '
';
// 构建invoke调用
var invokeText = '错误: 找不到模块 "Module:卡牌/' + cardData.module + '"';
console.log('调用文本:', invokeText);
// 通过API获取新卡牌HTML
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) {
// 添加删除按钮
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];
});
newCard.style.position = 'relative';
newCard.appendChild(deleteBtn);
}
// 重新设置全局监听
setupGlobalModalListener();
// 确保滚动恢复
document.body.style.overflow = ;
document.documentElement.style.overflow = ;
}, 100);
} else {
console.error('API返回数据无效');
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');
if (!characterName) {
var nameEl = characterOption.querySelector('.character-name, [class*="name"]');
if (nameEl) characterName = nameEl.textContent.trim();
}
console.log('选中的战斗员:', characterName, '单元:', currentActiveUnit);
// 克隆卡片显示
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 = '150px';
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 equipmentTypes = {
'weapon': { type: '武器', title: '选择武器' },
'armor': { type: '装甲', title: '选择装甲' },
'ring': { type: '戒指', title: '选择戒指' }
};
// 当前选择的装备槽位
var currentEquipmentSlot = null;
// 装备槽位点击事件
document.querySelectorAll('.equipment-slot').forEach(function(slot) {
slot.addEventListener('click', function() {
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
currentEquipmentSlot = this;
var equipmentType = this.getAttribute('data-equipment-type');
loadEquipmentList(equipmentTypes[equipmentType]);
});
});
// 加载装备列表
function loadEquipmentList(equipmentInfo) {
// 设置标题
document.getElementById('equipment-modal-title').textContent = equipmentInfo.title;
// 显示加载中
var equipmentList = document.getElementById('equipment-list');
equipmentList.innerHTML = '
';
// 显示模态框
document.getElementById('equipment-modal').style.display = 'block';
// 通过API调用模块获取装备HTML
var apiUrl = mw.util.wikiScript('api');
var params = {
action: 'parse',
format: 'json',
text: '
',
contentmodel: 'wikitext',
disablelimitreport: true,
wrapoutputclass:
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
equipmentList.innerHTML = data.parse.text['*'];
// 为每个装备添加点击事件
setTimeout(function() {
addEquipmentClickHandlers();
}, 100);
} else {
equipmentList.innerHTML = '
';
}
})
.catch(error => {
console.error('加载装备失败:', error);
equipmentList.innerHTML = '
';
});
}
// 为装备添加点击事件
function addEquipmentClickHandlers() {
var equipmentCards = document.querySelectorAll('#equipment-list > div > div[style*="position:relative"]');
equipmentCards.forEach(function(card) {
card.style.cursor = 'pointer';
card.addEventListener('click', function() {
selectEquipment(card);
});
});
}
// 选择装备
function selectEquipment(equipmentCard) {
if (!currentEquipmentSlot) return;
// 克隆装备卡片
var clonedCard = equipmentCard.cloneNode(true);
clonedCard.style.cursor = 'default';
clonedCard.style.margin = '0';
// 调整尺寸以适应槽位
clonedCard.style.width = '100px';
clonedCard.style.height = '100px';
// 调整内部元素尺寸
var innerElements = clonedCard.querySelectorAll('div');
innerElements.forEach(function(el) {
if (el.style.width === '124px') el.style.width = '100px';
if (el.style.height === '124px') el.style.height = '100px';
if (el.style.width === '112px') el.style.width = '88px';
if (el.style.height === '112px') el.style.height = '88px';
if (el.style.width === '110px') el.style.width = '86px';
if (el.style.height === '110px') el.style.height = '86px';
if (el.style.top === '7px') el.style.top = '6px';
if (el.style.left === '7px') el.style.left = '6px';
if (el.style.top === '6px') el.style.top = '5px';
if (el.style.left === '6px') el.style.left = '5px';
});
// 调整图片大小
var imgs = clonedCard.querySelectorAll('img');
imgs.forEach(function(img) {
if (img.style.width === '124px' || img.width === 124) {
img.style.width = '100px';
img.style.height = '100px';
}
if (img.style.width === '112px' || img.width === 112) {
img.style.width = '88px';
img.style.height = '88px';
}
});
// 隐藏或缩小装备名称
var nameDiv = clonedCard.querySelector('div[style*="bottom"]');
if (nameDiv) {
nameDiv.style.fontSize = '10px';
nameDiv.style.bottom = '2px';
nameDiv.style.left = '2px';
}
// 放置到对应槽位
currentEquipmentSlot.innerHTML = ;
currentEquipmentSlot.appendChild(clonedCard);
currentEquipmentSlot.style.border = 'none';
currentEquipmentSlot.style.padding = '0';
// 关闭模态框
document.getElementById('equipment-modal').style.display = 'none';
currentEquipmentSlot = null;
}
// 关闭装备选择窗口
document.getElementById('close-equipment-modal').addEventListener('click', function() {
document.getElementById('equipment-modal').style.display = 'none';
currentEquipmentSlot = null;
});
// 点击遮罩层关闭装备窗口
document.getElementById('equipment-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
currentEquipmentSlot = null;
}
});
// ========== 保存为图片功能 ==========
document.getElementById('save-team-btn').addEventListener('click', function() {
saveTeamAsImage();
});
function saveTeamAsImage() {
var button = document.getElementById('save-team-btn');
var originalText = button.textContent;
button.textContent = '正在生成图片...';
button.style.pointerEvents = 'none';
button.style.opacity = '0.6';
// 动态加载html2canvas库
if (typeof html2canvas === 'undefined') {
var script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js';
script.onload = function() {
captureTeam(button, originalText);
};
script.onerror = function() {
alert('加载图片生成库失败,请检查网络连接');
button.textContent = originalText;
button.style.pointerEvents = ;
button.style.opacity = ;
};
document.head.appendChild(script);
} else {
captureTeam(button, originalText);
}
}
function captureTeam(button, originalText) {
var teamContent = document.getElementById('team-content');
// 临时隐藏删除按钮
var deleteButtons = teamContent.querySelectorAll('.card-delete-btn');
deleteButtons.forEach(function(btn) {
btn.style.display = 'none';
});
html2canvas(teamContent, {
backgroundColor: '#ffffff',
scale: 2,
logging: false,
useCORS: true,
allowTaint: true
}).then(function(canvas) {
// 恢复删除按钮
deleteButtons.forEach(function(btn) {
btn.style.display = ;
});
// 转换为图片并下载
canvas.toBlob(function(blob) {
var url = URL.createObjectURL(blob);
var link = document.createElement('a');
var timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
link.download = '队伍配置_' + timestamp + '.png';
link.href = url;
link.click();
URL.revokeObjectURL(url);
button.textContent = originalText;
button.style.pointerEvents = ;
button.style.opacity = ;
});
}).catch(function(error) {
console.error('生成图片失败:', error);
alert('生成图片失败: ' + error.message);
// 恢复删除按钮
deleteButtons.forEach(function(btn) {
btn.style.display = ;
});
button.textContent = originalText;
button.style.pointerEvents = ;
button.style.opacity = ;
});
}
// 页面卸载时清理
window.addEventListener('beforeunload', function() {
if (window.deckModalObserver) {
window.deckModalObserver.disconnect();
}
// 确保恢复滚动
document.body.style.overflow = ;
document.documentElement.style.overflow = ;
});
// 监听所有模态框关闭,确保滚动恢复
setInterval(function() {
var hasOpenModal = false;
document.querySelectorAll('.card-modal, #character-modal, #partner-modal, #equipment-modal').forEach(function(modal) {
if (modal.style.display !== 'none' && modal.style.display !== ) {
hasOpenModal = true;
}
});
if (!hasOpenModal) {
// 没有打开的模态框,确保滚动正常
document.body.style.overflow = ;
document.documentElement.style.overflow = ;
document.body.style.position = ;
}
}, 500);
}
// 确保DOM加载完成后执行
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTeamSimulator);
} else {
initTeamSimulator();
}
})(); </script>
<style> .character-option {
cursor: pointer; transition: transform 0.2s;
}
.character-option:hover {
transform: scale(1.05); box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.partner-option {
cursor: pointer; transition: transform 0.2s;
}
.partner-option:hover {
transform: scale(1.05); box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.card-delete-btn:hover {
background: rgba(255,0,0,1) !important; transform: scale(1.1);
}
.select-variant-btn {
transition: all 0.3s;
}
.select-variant-btn:hover {
opacity: 0.9; transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0,0,0,0.3);
}
/* 防止模态框影响滚动 */ body.modal-open {
overflow: auto !important; position: static !important;
}
html.modal-open {
overflow: auto !important;
}
/* 确保模态框正确显示 */ .card-modal {
position: fixed !important; overflow: auto !important;
}
/* 修复可能的滚动问题 */
- team-simulator {
position: relative; overflow: visible;
}
.deck-card-wrapper {
position: relative;
}
/* 确保选择按钮在正确的层级 */ .select-variant-btn {
position: relative; z-index: 10;
}
/* 修复灵光一闪和神光一闪视图的居中问题 */ .inspiration-view, .god-inspiration-view {
max-height: 100vh; overflow-y: auto; display: flex; flex-direction: column; align-items: center; padding: 20px 10px;
}
/* 确保变体容器正确布局 */ .inspiration-variants-container, .god-groups-container {
width: 100%; display: flex; flex-direction: column; align-items: center; gap: 20px;
}
/* 灵光一闪变体容器 */ .inspiration-variant {
width: 100%; max-width: 600px; display: flex; flex-direction: column; align-items: center;
}
/* 神光一闪组容器 */ .god-group {
width: 100%; max-width: 800px; display: flex; flex-direction: column; align-items: center;
}
/* 神光一闪变体卡片容器 */ .god-variants-row {
display: flex; flex-wrap: wrap; justify-content: center; gap: 15px; margin-top: 10px;
}
.god-variant-card {
display: flex; flex-direction: column; align-items: center;
}
/* 修复返回按钮不遮挡内容 */ .card-modal-content {
position: relative; padding-top: 60px !important; /* 为返回按钮留出空间 */
}
.card-modal .modal-back-button {
position: absolute; top: 10px; left: 10px; z-index: 1001;
}
/* 确保卡牌列表不被遮挡 */ .inspiration-view > *:first-child, .god-inspiration-view > *:first-child {
margin-top: 0;
}
/* 保存按钮hover效果 */
- save-team-btn:hover {
transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0,0,0,0.2); opacity: 0.95;
}
- save-team-btn:active {
transform: translateY(0); box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
/* 角色单元样式 */ .character-unit {
transition: box-shadow 0.3s;
}
.character-unit:hover {
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
} </style>