Usuário Discussão:Ttuzu
Revisão de 22h39min de 10 de junho de 2025 por Ttuzu (discussão | contribs) (→Personagem:Franky (Timeskip): nova seção)
(function () {
const personaData = document.getElementById('persona-data');
if (!personaData) {
console.error('Persona widget: não se encontrou #persona-data!');
return;
}
// Extração de dados const nome = personaData.dataset.nome || ; const tier = personaData.dataset.tier || ; const classe = personaData.dataset.classe || ; const image = personaData.dataset.image || ; let habilidades = []; let skins = [];
// Função auxiliar para parsear strings raw em objetos
const parseRawString = (rawString) => {
const data = [];
if (!rawString) return data;
const lines = rawString.split('||').map(line => line.trim()).filter(Boolean);
lines.forEach(line => {
const parts = line.split('\n').map(p => p.trim()).filter(Boolean);
const item = {};
parts.forEach(part => {
if (part.startsWith()) {
// Ignorar comentários
return;
}
const eqIndex = part.indexOf('=');
if (eqIndex > -1) {
const key = part.substring(0, eqIndex).trim();
const value = part.substring(eqIndex + 1).trim();
item[key] = value;
}
});
if (Object.keys(item).length > 0) {
data.push(item);
}
});
return data;
};
habilidades = parseRawString(personaData.dataset.habilidadesraw); skins = parseRawString(personaData.dataset.skinsraw);
// Referências aos elementos HTML
const tabBtns = document.querySelectorAll('.persona-tabs .tab-btn');
const cuadrosContainer = document.querySelector('.cuadros-container');
const abilityNameText = document.querySelector('.descripcion-container .ability-name-text');
const abilityLevelText = document.querySelector('.descripcion-container .ability-level-text');
const abilityDesc = document.querySelector('.descripcion-container .ability-desc');
const abilityVideo = document.querySelector('.descripcion-container .ability-video');
const abilityVideoSource = abilityVideo.querySelector('source');
const abilityAttributesContainer = document.querySelector('.descripcion-container .ability-attributes');
const artPersonagem = document.querySelector('.art-personagem');
const personaName = document.querySelector('.persona-name');
const personaTier = document.querySelector('.persona-tier');
const personaClass = document.querySelector('.persona-class');
// Preencher informações do header do personagem
if (artPersonagem) artPersonagem.src = image;
if (personaName) personaName.textContent = nome;
if (personaTier) personaTier.textContent = `Tier: ${tier}`;
if (personaClass) personaClass.textContent = `Classe: ${classe}`;
// Estado atual let currentActiveTab = 'habilidades'; let currentActiveIndex = 0; // Índice da habilidade/skin ativa
// Função para renderizar os ícones (habilidades ou skins)
const renderIcons = (items, type) => {
cuadrosContainer.innerHTML = ; // Limpar antes de renderizar
items.forEach((item, index) => {
const cuadro = document.createElement('div');
cuadro.classList.add('cuadro');
cuadro.style.backgroundImage = `url('${item.icon || item.image}')`;
cuadro.dataset.index = index;
cuadro.dataset.type = type;
cuadro.addEventListener('click', () => {
selectItem(index, type);
});
cuadrosContainer.appendChild(cuadro);
});
};
// Função para exibir detalhes da habilidade/skin
const displayItemDetails = (item, type) => {
// Limpa atributos anteriores
abilityAttributesContainer.innerHTML = ;
if (type === 'habilidades') {
abilityNameText.textContent = item.nome || ;
abilityLevelText.textContent = `Level: ${item.level || }`;
abilityDesc.textContent = item.desc || ;
// Renderizar atributos dinamicamente
if (item.atr) {
const atrParts = item.atr.split(',').map(p => p.trim());
for (let i = 0; i < atrParts.length; i += 2) {
const iconPath = atrParts[i];
const value = atrParts[i + 1];
if (iconPath && value !== undefined && value !== null) { // Verifique se o valor não é null/undefined
const attributeDiv = document.createElement('div');
const attributeImg = document.createElement('img');
attributeImg.src = iconPath;
attributeImg.alt = "Atributo";
attributeDiv.appendChild(attributeImg);
attributeDiv.appendChild(document.createTextNode(value));
abilityAttributesContainer.appendChild(attributeDiv);
}
}
}
if (item.video) {
abilityVideoSource.src = item.video;
abilityVideo.load();
abilityVideo.style.display = 'block';
} else {
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
} else { // Skins
abilityNameText.textContent = item.nome || ;
abilityLevelText.textContent = ;
abilityDesc.textContent = item.desc || ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
};
// Função para selecionar um item (habilidade ou skin)
const selectItem = (index, type) => {
const items = type === 'habilidades' ? habilidades : skins;
const selectedItem = items[index];
// Atualizar classe 'active' nos ícones
document.querySelectorAll('.cuadro').forEach(cuadro => {
cuadro.classList.remove('active');
});
const activeCuadro = cuadrosContainer.querySelector(`.cuadro[data-index="${index}"][data-type="${type}"]`);
if (activeCuadro) {
activeCuadro.classList.add('active');
}
displayItemDetails(selectedItem, type);
currentActiveIndex = index;
currentActiveTab = type;
};
// Event Listeners para as abas
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
const tabType = btn.dataset.tab;
// Remover 'active' de todas as abas
tabBtns.forEach(b => b.classList.remove('active'));
// Adicionar 'active' à aba clicada
btn.classList.add('active');
if (tabType === 'habilidades') {
renderIcons(habilidades, 'habilidades');
if (habilidades.length > 0) {
selectItem(0, 'habilidades');
} else {
abilityNameText.textContent = 'Nenhuma Habilidade';
abilityLevelText.textContent = ;
abilityDesc.textContent = ;
abilityAttributesContainer.innerHTML = ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
} else { // Skins
renderIcons(skins, 'skins');
if (skins.length > 0) {
selectItem(0, 'skins');
} else {
abilityNameText.textContent = 'Nenhuma Skin';
abilityLevelText.textContent = ;
abilityDesc.textContent = ;
abilityAttributesContainer.innerHTML = ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
}
});
});
// Inicialização: renderizar habilidades e selecionar a primeira por padrão
if (habilidades.length > 0) {
renderIcons(habilidades, 'habilidades');
selectItem(0, 'habilidades');
} else if (skins.length > 0) {
document.querySelector('.tab-btn[data-tab="skins"]').click();
} else {
cuadrosContainer.innerHTML = '
Nenhum conteúdo disponível.
';
abilityNameText.textContent = 'Nenhum Conteúdo';
abilityLevelText.textContent = ;
abilityDesc.textContent = ;
abilityAttributesContainer.innerHTML = ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
})();
Widget:Persona
(function () {
const personaData = document.getElementById('persona-data');
if (!personaData) {
console.error('Persona widget: não se encontrou #persona-data!');
return;
}
// Extração de dados const nome = personaData.dataset.nome || ; const tier = personaData.dataset.tier || ; const classe = personaData.dataset.classe || ; const image = personaData.dataset.image || ; let habilidades = []; let skins = [];
// Função auxiliar para parsear strings raw em objetos
const parseRawString = (rawString) => {
const data = [];
if (!rawString) return data;
const lines = rawString.split('||').map(line => line.trim()).filter(Boolean);
lines.forEach(line => {
const parts = line.split('\n').map(p => p.trim()).filter(Boolean);
const item = {};
parts.forEach(part => {
if (part.startsWith()) {
// Ignorar comentários
return;
}
const eqIndex = part.indexOf('=');
if (eqIndex > -1) {
const key = part.substring(0, eqIndex).trim();
const value = part.substring(eqIndex + 1).trim();
item[key] = value;
}
});
if (Object.keys(item).length > 0) {
data.push(item);
}
});
return data;
};
habilidades = parseRawString(personaData.dataset.habilidadesraw); skins = parseRawString(personaData.dataset.skinsraw);
// Referências aos elementos HTML
const tabBtns = document.querySelectorAll('.persona-tabs .tab-btn');
const cuadrosContainer = document.querySelector('.cuadros-container');
const abilityNameText = document.querySelector('.descripcion-container .ability-name-text');
const abilityLevelText = document.querySelector('.descripcion-container .ability-level-text');
const abilityDesc = document.querySelector('.descripcion-container .ability-desc');
const abilityVideo = document.querySelector('.descripcion-container .ability-video');
const abilityVideoSource = abilityVideo.querySelector('source');
const abilityAttributesContainer = document.querySelector('.descripcion-container .ability-attributes');
const artPersonagem = document.querySelector('.art-personagem');
const personaName = document.querySelector('.persona-name');
const personaTier = document.querySelector('.persona-tier');
const personaClass = document.querySelector('.persona-class');
// Preencher informações do header do personagem
if (artPersonagem) artPersonagem.src = image;
if (personaName) personaName.textContent = nome;
if (personaTier) personaTier.textContent = `Tier: ${tier}`;
if (personaClass) personaClass.textContent = `Classe: ${classe}`;
// Estado atual let currentActiveTab = 'habilidades'; let currentActiveIndex = 0; // Índice da habilidade/skin ativa
// Função para renderizar os ícones (habilidades ou skins)
const renderIcons = (items, type) => {
cuadrosContainer.innerHTML = ; // Limpar antes de renderizar
items.forEach((item, index) => {
const cuadro = document.createElement('div');
cuadro.classList.add('cuadro');
cuadro.style.backgroundImage = `url('${item.icon || item.image}')`;
cuadro.dataset.index = index;
cuadro.dataset.type = type;
cuadro.addEventListener('click', () => {
selectItem(index, type);
});
cuadrosContainer.appendChild(cuadro);
});
};
// Função para exibir detalhes da habilidade/skin
const displayItemDetails = (item, type) => {
// Limpa atributos anteriores
abilityAttributesContainer.innerHTML = ;
if (type === 'habilidades') {
abilityNameText.textContent = item.nome || ;
abilityLevelText.textContent = `Level: ${item.level || }`;
abilityDesc.textContent = item.desc || ;
// Renderizar atributos dinamicamente
if (item.atr) {
const atrParts = item.atr.split(',').map(p => p.trim());
for (let i = 0; i < atrParts.length; i += 2) {
const iconPath = atrParts[i];
const value = atrParts[i + 1];
if (iconPath && value !== undefined && value !== null) { // Verifique se o valor não é null/undefined
const attributeDiv = document.createElement('div');
const attributeImg = document.createElement('img');
attributeImg.src = iconPath;
attributeImg.alt = "Atributo";
attributeDiv.appendChild(attributeImg);
attributeDiv.appendChild(document.createTextNode(value));
abilityAttributesContainer.appendChild(attributeDiv);
}
}
}
if (item.video) {
abilityVideoSource.src = item.video;
abilityVideo.load();
abilityVideo.style.display = 'block';
} else {
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
} else { // Skins
abilityNameText.textContent = item.nome || ;
abilityLevelText.textContent = ;
abilityDesc.textContent = item.desc || ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
};
// Função para selecionar um item (habilidade ou skin)
const selectItem = (index, type) => {
const items = type === 'habilidades' ? habilidades : skins;
const selectedItem = items[index];
// Atualizar classe 'active' nos ícones
document.querySelectorAll('.cuadro').forEach(cuadro => {
cuadro.classList.remove('active');
});
const activeCuadro = cuadrosContainer.querySelector(`.cuadro[data-index="${index}"][data-type="${type}"]`);
if (activeCuadro) {
activeCuadro.classList.add('active');
}
displayItemDetails(selectedItem, type);
currentActiveIndex = index;
currentActiveTab = type;
};
// Event Listeners para as abas
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
const tabType = btn.dataset.tab;
// Remover 'active' de todas as abas
tabBtns.forEach(b => b.classList.remove('active'));
// Adicionar 'active' à aba clicada
btn.classList.add('active');
if (tabType === 'habilidades') {
renderIcons(habilidades, 'habilidades');
if (habilidades.length > 0) {
selectItem(0, 'habilidades');
} else {
abilityNameText.textContent = 'Nenhuma Habilidade';
abilityLevelText.textContent = ;
abilityDesc.textContent = ;
abilityAttributesContainer.innerHTML = ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
} else { // Skins
renderIcons(skins, 'skins');
if (skins.length > 0) {
selectItem(0, 'skins');
} else {
abilityNameText.textContent = 'Nenhuma Skin';
abilityLevelText.textContent = ;
abilityDesc.textContent = ;
abilityAttributesContainer.innerHTML = ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
}
});
});
// Inicialização: renderizar habilidades e selecionar a primeira por padrão
if (habilidades.length > 0) {
renderIcons(habilidades, 'habilidades');
selectItem(0, 'habilidades');
} else if (skins.length > 0) {
document.querySelector('.tab-btn[data-tab="skins"]').click();
} else {
cuadrosContainer.innerHTML = '
Nenhum conteúdo disponível.
';
abilityNameText.textContent = 'Nenhum Conteúdo';
abilityLevelText.textContent = ;
abilityDesc.textContent = ;
abilityAttributesContainer.innerHTML = ;
abilityVideoSource.src = ;
abilityVideo.style.display = 'none';
}
})();
Predefinição:Persona
Predefinição:Documentação da Predefinição 'Persona' Esta predefinição gera uma ficha interativa de personagem, conectada a um widget em JavaScript que exibe habilidades e skins de forma dinâmica.
Exemplo para Copiar e Colar
{{Persona
|Nome=Franky (Timeskip)
|tier=Diamante
|classe=Atirador/Tanque
|image=Caminho/Para/ImagemDoFranky.png
|habilidadesRaw=
nome=Rocket Launcher
icon=/caminho/para/icone_rocket_launcher.png
level=70
desc=Usando a tecnologia que adquiriu em Bajimroa Island, Franky usa seus grandes ombros, dos quais ele libera uma linha (Raffle Franky 1/?) revelando três pequenos, porém poderosos, mísseis que serão lançados no oponente. Causa dano em uma grande área e para o oponente. Oponentes que estiverem no caminho dos mísseis recebem apenas 75% de dano e não são punidos.
atr=/caminho/para/icone_cooldown.png,35 SEG,/caminho/para/icone_custo.png,-,/caminho/para/icone_alcance.png,40,/caminho/para/icone_dano.png,35
video=/caminho/para/video_rocket_launcher.webm
||
nome=Punch de Aço
icon=/caminho/para/icone_punch.png
level=60
desc=Franky desfere um soco poderoso, causando dano massivo e atordoando o alvo por um breve período.
atr=/caminho/para/icone_cooldown.png,20 SEG,/caminho/para/icone_custo.png,50,/caminho/para/icone_alcance.png,5,/caminho/para/icone_dano.png,120
video=/caminho/para/video_punch.webm
|skinsRaw=
nome=Skin Padrão
image=/caminho/para/skin_padrao.png
desc=Aparência original de Franky.
||
nome=Skin de Férias
image=/caminho/para/skin_ferias.png
desc=Franky pronto para relaxar na praia.
}}