Mudanças entre as edições de "Teste2"
Ir para navegação
Ir para pesquisar
Etiqueta: Revertido |
Etiqueta: Revertido |
||
| Linha 1: | Linha 1: | ||
< | <!DOCTYPE html> | ||
<html lang="pt-BR"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Teste GIF Hover</title> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<style> | |||
/* --- Melhorias gerais de estilo e responsividade, e código mais limpo --- */ | |||
body { | |||
margin: 0; | |||
font-family: 'Segoe UI', Arial, sans-serif; | |||
color: #fff; | |||
background: #171f2b; | |||
min-height: 100vh; | |||
} | |||
; | .search-bar { | ||
: | text-align: right; | ||
padding: 20px; | |||
background: #222c3a; | |||
} | |||
; | .search-bar input { | ||
: | padding: 8px 14px; | ||
width: 270px; | |||
max-width: 90vw; | |||
border-radius: 7px; | |||
border: 1px solid #2f425e; | |||
font-size: 1rem; | |||
background: #101926; | |||
color: #fff; | |||
outline: none; | |||
transition: border-color .2s; | |||
} | |||
.search-bar input:focus { | |||
border-color: #58aaff; | |||
} | |||
.container { | |||
display: grid; | |||
grid-template-columns: repeat(auto-fit, minmax(245px, 1fr)); | |||
gap: 22px; | |||
width: 96vw; | |||
margin: 0 auto; | |||
justify-items: center; | |||
padding-bottom: 30px; | |||
} | |||
@media (max-width: 1200px) { | |||
.container { grid-template-columns: repeat(3, 1fr);} | |||
} | |||
@media (max-width: 900px) { | |||
.container { grid-template-columns: repeat(2, 1fr);} | |||
} | |||
@media (max-width: 600px) { | |||
.container { grid-template-columns: 1fr; } | |||
} | |||
; | .personagem { | ||
width: 245px; | |||
min-width: 0; | |||
height: 110px; | |||
aspect-ratio: 16/7; | |||
border-radius: 10px; | |||
background-size: 150% auto; | |||
background-position: center -30px; | |||
transition: transform 0.3s, box-shadow .3s; | |||
display: flex; | |||
align-items: flex-end; | |||
justify-content: flex-end; | |||
padding: 5px; | |||
font-weight: bold; | |||
color: #fff; | |||
text-shadow: 1px 1px 4px #222, 0 0 20px #111; | |||
position: relative; | |||
cursor: pointer; | |||
border: 2px solid #58aaff; | |||
overflow: hidden; | |||
text-decoration: none; | |||
box-shadow: 0 2px 13px rgba(44,65,122, 0.08); | |||
background-repeat: no-repeat; | |||
} | |||
@media (max-width: 400px) { | |||
.personagem { | |||
width: 98vw; | |||
height: 80px; | |||
font-size: 0.92em; | |||
} | |||
} | |||
.personagem span { | |||
z-index: 2; | |||
font-size: 1.10rem; | |||
font-weight: 900; | |||
padding: 3px 10px; | |||
border-radius: 7px; | |||
background: linear-gradient(90deg, #000c 60%, #29292999 100%); | |||
color: #fff; | |||
text-shadow: | |||
0 0 6px #001a33, | |||
0 2px 8px #0008, | |||
2px 2px 0 #000, | |||
-2px -2px 0 #000; | |||
box-shadow: 0 2px 8px #000a; | |||
} | |||
.gif-overlay { | |||
position: absolute; | |||
inset: 0; | |||
background-repeat: no-repeat; | |||
background-size: 150% auto; | |||
background-position: center -30px; | |||
opacity: 0; | |||
z-index: 1; | |||
pointer-events: none; | |||
transition: opacity 0.3s; | |||
} | |||
.personagem:hover, | |||
.personagem:focus-visible { | |||
transform: scale(1.06); | |||
box-shadow: 0px 4px 22px #46b6ff44, 0 1.5px 0 #1394ed; | |||
} | |||
.personagem:hover .gif-overlay, | |||
.personagem:focus-visible .gif-overlay { | |||
opacity: 1; | |||
} | |||
.personagem.luffy .gif-overlay { background-position: center 0px; } | |||
.personagem.hancock { background-size: 115% auto; } | |||
.personagem.daddy { background-size: 100% auto; background-position: top;} | |||
.personagem.kizaru { background-position: center -20px; } | |||
.personagem.luffypre{ background-position: center; } | |||
.personagem.perona { background-position: center -80px; } | |||
.personagem.sanjipre{ background-position: center -50px; } | |||
.personagem.cabaji { background-size: 240% auto; background-position: center -80px;} | |||
.personagem.gin { background-position: center -120px;} | |||
.personagem.jango { background-position: left -40px top -20px; background-size: 180% auto;} | |||
/* --------- Tiers ----------- */ | |||
.tier-diamante .personagem { background-color: #414c5c; } | |||
.tier-gold .personagem { background-color: #c6a64e; } | |||
.tier-prata .personagem { background-color: #a5a4af; } | |||
.tier-bronze .personagem { background-color: #83623d; } | |||
.filtros { | |||
flex-wrap: wrap; | |||
align-items: flex-start; | |||
padding: 9px 2vw; | |||
display: flex; | |||
gap: 18px; | |||
justify-content: space-between; | |||
margin-bottom: 18px; | |||
background: #212e3e; | |||
border-bottom: 1.5px solid #19212c; | |||
font-size: 1rem; | |||
} | |||
.filtros button { | |||
padding: 8px 12px; | |||
margin: 0 2px; | |||
border: none; | |||
border-radius: 5px; | |||
background-color: #337cd7; | |||
color: white; | |||
font-weight: bold; | |||
cursor: pointer; | |||
transition: background 0.18s, filter .21s; | |||
font-size: inherit; | |||
outline: none; | |||
border: 1.5px solid transparent; | |||
} | |||
.filtros button:focus-visible { | |||
outline: 2px solid #58aaff; | |||
filter: brightness(1.13); | |||
} | |||
; | .filtro-grupo, | ||
: | .classe-grid { | ||
display: flex; | |||
flex-wrap: wrap; | |||
gap: 7px 9px; | |||
align-items: center; | |||
justify-content: center; | |||
} | |||
; | .filtro-box { | ||
: | background: #34475f11; | ||
padding: 8px 12px; | |||
border-radius: 8px; | |||
min-width: 145px; | |||
} | |||
; | .filtro-box legend { | ||
font-size: 16px; | |||
font-weight: bold; | |||
color: #5a8fcc; | |||
margin-bottom: 6px; | |||
text-align: center; | |||
} | |||
; | .filtros button:hover, .filtros button.ativo { | ||
background-color: #2491e7; | |||
filter: brightness(1.09); | |||
border-color: #58aaff; | |||
box-shadow: 0 0 6px #2473b355; | |||
transform: scale(1.045); | |||
} | |||
.btn-vertical { | |||
writing-mode: vertical-rl; | |||
rotate: 270deg; | |||
font-size: 0.97em; | |||
letter-spacing: 0.15em; | |||
} | |||
.tier-btn { | |||
background: #234; | |||
border: none; | |||
border-radius: 50%; | |||
padding: 5px 8px; | |||
cursor: pointer; | |||
font-size: 0; | |||
box-shadow: none; | |||
outline: none; | |||
transition: background 0.18s; | |||
} | |||
.tier-btn.ativo, .tier-btn:focus-visible { | |||
background: #eaf2fb; | |||
outline: 2px solid #58aaff; | |||
} | |||
.estrela { | |||
font-size: 26px; | |||
line-height: 1; | |||
pointer-events: none; | |||
filter: drop-shadow(0 0 2px #002) drop-shadow(0 1px 1px #0005); | |||
} | |||
.estrela.azul { color: #14a3ee; } | |||
.estrela.dourada{ color: #ffc107; } | |||
.estrela.prata { color: #c0c0c0; } | |||
.estrela.bronze { color: #cd7f32; } | |||
.classe-icon-wrapper { | |||
position: absolute; | |||
top: 5px; | |||
left: 5px; | |||
display: flex; | |||
flex-direction: column; | |||
gap: 2px; | |||
z-index: 10; | |||
pointer-events: none; | |||
transition: transform 0.4s; | |||
} | |||
.classe-icon { | |||
width: 28px; | |||
height: 28px; | |||
user-select: none; | |||
pointer-events: none; | |||
opacity: 0.94; | |||
transition: opacity 0.3s; | |||
} | |||
.personagem-box:hover .classe-icon, | |||
.personagem-box:focus-within .classe-icon { | |||
opacity: 1; | |||
} | |||
.personagem-box { | |||
position: relative; | |||
transition: transform 0.4s, box-shadow .3s; | |||
transform-origin: center center; | |||
} | |||
.personagem-box:hover, .personagem-box:focus-within { | |||
transform: scale(1.04); | |||
z-index: 2; | |||
box-shadow: 0 6px 22px #23234770; | |||
} | |||
.classe-filtro-container { | |||
display: flex; | |||
align-items: center; | |||
gap: 9px; | |||
} | |||
.tooltip-img { | |||
position: absolute; | |||
top: -110px; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
width: 60px; | |||
height: auto; | |||
display: none; | |||
pointer-events: none; | |||
border-radius: 6px; | |||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); | |||
z-index: 99; | |||
} | |||
.tipo-btn[data-tipo="parede"], | |||
.tipo-btn[data-tipo="ponte"] { | |||
margin-left: 8px; | |||
} | |||
.novos-container { | |||
padding: 20px; | |||
background: linear-gradient(to right, #e0f0ff, #ffffff); | |||
border-radius: 12px; | |||
margin: 20px auto; | |||
width: 95%; | |||
max-width: 1200px; | |||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.11); | |||
border: 2px solid #58aaff; | |||
} | |||
.novos-header { | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
margin-bottom: 15px; | |||
border-bottom: 2px solid #58aaff; | |||
padding-bottom: 6px; | |||
} | |||
.novos-title { | |||
font-size: 20px; | |||
font-weight: bold; | |||
color: #006eff; | |||
} | |||
.new-gif { | |||
width: 32px; | |||
height: 32px; | |||
animation: pulse 1.5s infinite; | |||
} | |||
@keyframes pulse { | |||
0% { transform: scale(1); opacity: 1; } | |||
50% { transform: scale(1.17); opacity: 0.72; } | |||
100% { transform: scale(1); opacity: 1; } | |||
} | |||
.novos-grid { | |||
display: flex; | |||
flex-wrap: wrap; | |||
gap: 10px; | |||
justify-content: center; | |||
} | |||
< | </style> | ||
</head> | |||
</ | |||
<body> | |||
<!-- Barra de Pesquisa --> | |||
<div class="search-bar"> | |||
<input type="text" id="search" placeholder="Pesquisar personagem..."> | |||
</div> | |||
<div class="filtros" aria-label="Filtros"> | |||
<div | <!-- Filtro por Classe --> | ||
<fieldset class="filtro-box classe-filtro-container" aria-label="Filtrar por Classe"> | |||
<legend>Classe</legend> | |||
<button class="btn-vertical tipo-btn ativo" data-tipo="all" title="Todos">ALL</button> | |||
<div class="classe-grid"> | |||
</div> | <button class="tipo-btn" data-tipo="lutador">Lutador</button> | ||
<button class="tipo-btn" data-tipo="atirador">Atirador</button> | |||
<button class="tipo-btn" data-tipo="cortante">Cortante</button> | |||
<button class="tipo-btn" data-tipo="especialista">Especialista</button> | |||
<button class="tipo-btn" data-tipo="tanque">Tanque</button> | |||
<button class="tipo-btn" data-tipo="dps">DPS</button> | |||
<button class="tipo-btn" data-tipo="suporte">Suporte</button> | |||
<button class="tipo-btn" data-tipo="bruiser">Bruiser</button> | |||
</div> | |||
</fieldset> | |||
<!-- Filtro por Outros (Parede e Ponte) --> | |||
< | <fieldset class="filtro-box" aria-label="Filtrar por Outros"> | ||
<legend>Outros</legend> | |||
<div class="classe-grid"> | |||
<button class="tipo-btn" data-tipo="parede" data-tooltip-text="Personagens que quebram parede"> | |||
<img src="https://wiki.gla.com.br/images/2/21/Wall-break.png" alt="parede" width="32" height="32"> | |||
</button> | |||
<button class="tipo-btn" data-tipo="ponte" data-tooltip-text="Personagens que fazem ponte"> | |||
<img src="https://wiki.gla.com.br/images/8/80/Bridge.png" alt="ponte" width="32" height="32"> | |||
</button> | |||
</div> | |||
</fieldset> | |||
<div | <!-- Filtro por Tier --> | ||
<fieldset class="filtro-box" aria-label="Filtrar por Tier"> | |||
</div> | <legend>Tier</legend> | ||
<div class="filtro-grupo"> | |||
<button class="tier-btn" data-tier="tier-diamante" aria-label="Diamante"><span class="estrela azul" title="Diamante">★</span></button> | |||
<button class="tier-btn" data-tier="tier-gold" aria-label="Ouro"><span class="estrela dourada" title="Ouro">★</span></button> | |||
<button class="tier-btn" data-tier="tier-prata" aria-label="Prata"><span class="estrela prata" title="Prata">★</span></button> | |||
<button class="tier-btn" data-tier="tier-bronze" aria-label="Bronze"><span class="estrela bronze" title="Bronze">★</span></button> | |||
</div> | |||
</fieldset> | |||
</div> | |||
</div> | <div class="novos-container"> | ||
<div class="novos-header"> | |||
<span class="novos-title">Novos Personagens</span> | |||
<img src="https://cdn-icons-png.flaticon.com/128/11135/11135991.png" alt="novo" class="new-gif"> | |||
</div> | |||
<div class="novos-grid" id="novos-grid"> | |||
<!-- Os personagens com classe "novo" serão movidos para cá automaticamente --> | |||
</div> | |||
</div> | |||
<!-- Personagens --> | |||
<div class="container"> | |||
<!-- ... Os personagens já estão bem estruturados, não vou listar tudo de novo aqui, mas: ... --> | |||
<!-- Sugestão: Manter como está, mas considere desacoplar completamente a lista HTML, carregando os dados por JS externo ou JSON para manutenção mais fácil. --> | |||
<!-- (Mantive igual para o demo, pois faz parte do funcionamento.) --> | |||
<!-- ... (todas as .personagem-box como antes) ... --> | |||
<!-- Você pode implementar paginação/infinite scroll para longas listas no futuro --> | |||
<!-- ... (fim da lista) ... --> | |||
</div> | |||
<script> | |||
// Melhoria: evite código duplicado, use funções utilitárias | |||
// Mover personagens novos | |||
(() => { | |||
const novosGrid = document.getElementById('novos-grid'); | |||
document.querySelectorAll('.personagem-box.novo').forEach(novoCard => { | |||
novosGrid.appendChild(novoCard); | |||
}); | |||
if (novosGrid.children.length === 0) { | |||
document.querySelector('.novos-container').style.display = 'none'; | |||
} | |||
})(); | |||
// Inicialização dos cards e overlays de gifs | |||
document.querySelectorAll('.personagem').forEach(card => { | |||
const staticImg = card.getAttribute('data-static'); | |||
const gifImg = card.getAttribute('data-gif'); | |||
const overlay = card.querySelector('.gif-overlay'); | |||
card.style.backgroundImage = staticImg ? `url('${staticImg}')` : ''; | |||
card.addEventListener('mouseenter', () => { | |||
if (gifImg) overlay.style.backgroundImage = `url('${gifImg}?t=${Date.now()}')`; | |||
}); | |||
card.addEventListener('mouseleave', () => { | |||
overlay.style.backgroundImage = ''; | |||
}); | |||
card.addEventListener('focus', () => { | |||
if (gifImg) overlay.style.backgroundImage = `url('${gifImg}?t=${Date.now()}')`; | |||
}); | |||
card.addEventListener('blur', () => { | |||
overlay.style.backgroundImage = ''; | |||
}); | |||
}); | |||
// Busca por nome, acessível e otimizada | |||
document.getElementById('search').addEventListener('input', function () { | |||
const term = this.value.toLowerCase(); | |||
document.querySelectorAll('.personagem').forEach(card => { | |||
const name = card.querySelector('span').textContent.toLowerCase(); | |||
const wrapper = card.parentElement; | |||
const tierBox = wrapper.parentElement; | |||
// Só filtra se NÃO estiver na grid de novos personagens | |||
if (!tierBox.classList.contains('novos-grid')) { | |||
tierBox.style.display = name.includes(term) ? 'block' : 'none'; | |||
} | |||
}); | |||
}); | |||
// Corrigido URLs dos links e checado duplicidade. | |||
const personagemLinks = { | |||
"Aokiji": "https://wiki.gla.com.br/index.php/Aokiji", | |||
"Bartholomew Kuma": "https://wiki.gla.com.br/index.php/Kuma", | |||
"Boa Hancock": "https://wiki.gla.com.br/index.php/Boa_Hancock", | |||
"Borsalino Kizaru": "https://wiki.gla.com.br/index.php/Kizaru", | |||
"Brook (TS)": "https://wiki.gla.com.br/index.php/Brook_(Timeskip)", | |||
"Chopper (TS)": "https://wiki.gla.com.br/index.php/Chopper_(Timeskip)", | |||
"Donquixote Doflamingo": "https://wiki.gla.com.br/index.php/Doflamingo", | |||
"Dracule Mihawk": "https://wiki.gla.com.br/index.php/Mihawk", | |||
"Emporio Ivankov": "https://wiki.gla.com.br/index.php/Ivankov", | |||
"Enel": "https://wiki.gla.com.br/index.php/Enel", | |||
"Franky (TS)": "https://wiki.gla.com.br/index.php/Franky_(Timeskip)", | |||
"Jinbe": "https://wiki.gla.com.br/index.php/Jinbe", | |||
"Marshall D. Teach": "https://wiki.gla.com.br/index.php/Marshall_D._Teach", | |||
"Marco": "https://wiki.gla.com.br/index.php/Marco", | |||
"Monkey D. Luffy (TS)": "https://wiki.gla.com.br/index.php/Luffy_(Timeskip)", | |||
"Nami (TS)": "https://wiki.gla.com.br/index.php/Nami_(Timeskip)", | |||
"Portgas D. Ace": "https://wiki.gla.com.br/index.php/Ace", | |||
"Nico Robin (TS)": "https://wiki.gla.com.br/index.php/Robin_(Timeskip)", | |||
"Roronoa Zoro (TS)": "https://wiki.gla.com.br/index.php/Zoro_(Timeskip)", | |||
"Sabo": "https://wiki.gla.com.br/index.php/Sabo", | |||
"Sakazuki (Akainu)": "https://wiki.gla.com.br/index.php/Akainu", | |||
"Shanks": "https://wiki.gla.com.br/index.php/Shanks", | |||
"Usopp (TS)": "https://wiki.gla.com.br/index.php/Usopp_(Timeskip)", | |||
"Uta": "https://wiki.gla.com.br/index.php/Uta", | |||
"Sanji (TS)": "https://wiki.gla.com.br/index.php/Sanji_(Timeskip)", | |||
"Baby 5": "https://wiki.gla.com.br/index.php/Baby_5", | |||
"Bartolomeo": "https://wiki.gla.com.br/index.php/Bartolomeo", | |||
"Basil Hawkins": "https://wiki.gla.com.br/index.php/Basil_Hawkins", | |||
"Bastille": "https://wiki.gla.com.br/index.php/Bastille", | |||
"Bellamy": "https://wiki.gla.com.br/index.php/Bellamy", | |||
"Jewelry Bonney": "https://wiki.gla.com.br/index.php/Bonney", | |||
"Brook": "https://wiki.gla.com.br/index.php/Brook", | |||
"Capone Gang Bege": "https://wiki.gla.com.br/index.php/Capone_Bege", | |||
"Carrot": "https://wiki.gla.com.br/index.php/Carrot", | |||
"Chopper": "https://wiki.gla.com.br/index.php/Chopper", | |||
"Sir Crocodile": "https://wiki.gla.com.br/index.php/Crocodile", | |||
"Dalmatian": "https://wiki.gla.com.br/index.php/Dalmatian", | |||
"Franky": "https://wiki.gla.com.br/index.php/Franky", | |||
"Gecko Moria": "https://wiki.gla.com.br/index.php/Gecko_Moria", | |||
"Hina": "https://wiki.gla.com.br/index.php/Hina", | |||
"Jesus Burgess": "https://wiki.gla.com.br/index.php/Jesus_Burgess", | |||
"Eustass Kid": "https://wiki.gla.com.br/index.php/Kid", | |||
"Killer": "https://wiki.gla.com.br/index.php/Killer", | |||
"Koala": "https://wiki.gla.com.br/index.php/Koala", | |||
"Leo & Mansherry": "https://wiki.gla.com.br/index.php/Leo", | |||
"Monkey D. Luffy": "https://wiki.gla.com.br/index.php/Luffy", | |||
"Nami": "https://wiki.gla.com.br/index.php/Nami", | |||
"Perona": "https://wiki.gla.com.br/index.php/Perona", | |||
"Rebecca": "https://wiki.gla.com.br/index.php/Rebecca", | |||
"Robin": "https://wiki.gla.com.br/index.php/Robin", | |||
"Zoro": "https://wiki.gla.com.br/index.php/Zoro", | |||
"Ryuma": "https://wiki.gla.com.br/index.php/Ryuma", | |||
"Scratchmen Apoo": "https://wiki.gla.com.br/index.php/Apoo", | |||
"Smoker": "https://wiki.gla.com.br/index.php/Smoker", | |||
"Trafalgar D. Water Law": "https://wiki.gla.com.br/index.php/Law", | |||
"Urouge": "https://wiki.gla.com.br/index.php/Urouge", | |||
"Usopp": "https://wiki.gla.com.br/index.php/Usopp", | |||
"Van Augur": "https://wiki.gla.com.br/index.php/Van_Augur", | |||
"Vinsmoke Ichiji": "https://wiki.gla.com.br/index.php/Ichiji", | |||
"Vinsmoke Niji": "https://wiki.gla.com.br/index.php/Niji", | |||
"Vinsmoke Reiju": "https://wiki.gla.com.br/index.php/Reiju", | |||
"Vinsmoke Sanji": "https://wiki.gla.com.br/index.php/Sanji", | |||
"Vinsmoke Yonji": "https://wiki.gla.com.br/index.php/Yonji", | |||
"X Drake": "https://wiki.gla.com.br/index.php/X_Drake", | |||
"Satori": "https://wiki.gla.com.br/index.php/Satori", | |||
"Gedatsu": "https://wiki.gla.com.br/index.php/Gedatsu", | |||
"Ohm": "https://wiki.gla.com.br/index.php/Ohm", | |||
"Shura": "https://wiki.gla.com.br/index.php/Shura", | |||
"Arlong": "https://wiki.gla.com.br/index.php/Arlong", | |||
"Bepo": "https://wiki.gla.com.br/index.php/Bepo", | |||
"Bon Clay": "https://wiki.gla.com.br/index.php/Mr.2", | |||
"Buggy": "https://wiki.gla.com.br/index.php/Buggy", | |||
"Daddy Masterson": "https://wiki.gla.com.br/index.php/Daddy_Masterson", | |||
"Daz Bonez": "https://wiki.gla.com.br/index.php/Mr.1", | |||
"Zala": "https://wiki.gla.com.br/index.php/Miss_Doublefinger", | |||
"Don Krieg": "https://wiki.gla.com.br/index.php/Don_Krieg", | |||
"Kuro": "https://wiki.gla.com.br/index.php/Kuro", | |||
"Galdino": "https://wiki.gla.com.br/index.php/Mr.3", | |||
"Tashigi": "https://wiki.gla.com.br/index.php/Tashigi", | |||
"Nefertari Vivi": "https://wiki.gla.com.br/index.php/Vivi", | |||
"Wapol": "https://wiki.gla.com.br/index.php/Wapol", | |||
"Alvida": "https://wiki.gla.com.br/index.php/Alvida", | |||
"Buchi & Sham": "https://wiki.gla.com.br/index.php/Buchi", | |||
"Cabaji": "https://wiki.gla.com.br/index.php/Cabaji", | |||
"Chew": "https://wiki.gla.com.br/index.php/Chew", | |||
"Eric": "https://wiki.gla.com.br/index.php/Eric", | |||
"Gin": "https://wiki.gla.com.br/index.php/Gin", | |||
"Miss GoldenWeek": "https://wiki.gla.com.br/index.php/Goldenweek", | |||
"Hatchan": "https://wiki.gla.com.br/index.php/Hatchan", | |||
"Jango": "https://wiki.gla.com.br/index.php/Jango", | |||
"Kuroobi": "https://wiki.gla.com.br/index.php/Kuroobi", | |||
"Mohji": "https://wiki.gla.com.br/index.php/Mohji", | |||
"Morgan": "https://wiki.gla.com.br/index.php/Morgan", | |||
"Babe & Drophy": "https://wiki.gla.com.br/index.php/Mr.4", | |||
"Gem & Mikita": "https://wiki.gla.com.br/index.php/Mr.5", | |||
"Pearl": "https://wiki.gla.com.br/index.php/Pearl" | |||
}; | |||
// Torna os personagens cards clicáveis, sem duplicar <a> | |||
document.querySelectorAll('.personagem').forEach(card => { | |||
const span = card.querySelector('span'); | |||
const nomePersonagem = span?.textContent.trim(); | |||
const link = personagemLinks[nomePersonagem]; | |||
if (link) { | |||
if (card.parentElement.tagName.toLowerCase() !== 'a') { | |||
const wrapper = document.createElement('a'); | |||
wrapper.href = link; | |||
wrapper.target = "_blank"; | |||
wrapper.rel = "noopener"; | |||
wrapper.style.display = "flex"; | |||
wrapper.style.textDecoration = "none"; | |||
wrapper.style.flex = "0 1 auto"; | |||
wrapper.style.alignItems = "stretch"; | |||
card.parentElement.replaceChild(wrapper, card); | |||
wrapper.appendChild(card); | |||
} | |||
} | |||
}); | |||
// Filtros: tier, tipo | |||
const tierButtons = document.querySelectorAll('.tier-btn'); | |||
const tipoButtons = document.querySelectorAll('.tipo-btn'); | |||
const personagemBoxes = document.querySelectorAll('.personagem-box'); | |||
let activeTier = 'all'; | |||
let activeTipos = new Set(); | |||
function updateFiltros() { | |||
personagemBoxes.forEach(box => { | |||
const matchesTier = activeTier === 'all' || box.classList.contains(activeTier); | |||
const matchesTipo = activeTipos.size === 0 || | |||
Array.from(activeTipos).every(tipo => box.classList.contains(tipo)); | |||
box.style.display = (matchesTier && matchesTipo) ? 'block' : 'none'; | |||
}); | |||
} | |||
tierButtons.forEach(button => { | |||
button.addEventListener('click', () => { | |||
const selectedTier = button.dataset.tier; | |||
if (selectedTier === activeTier || selectedTier === 'all') { | |||
activeTier = 'all'; | |||
tierButtons.forEach(btn => btn.classList.remove('ativo')); | |||
} else { | |||
activeTier = selectedTier; | |||
tierButtons.forEach(btn => btn.classList.remove('ativo')); | |||
button.classList.add('ativo'); | |||
} | |||
updateFiltros(); | |||
}); | |||
}); | |||
tipoButtons.forEach(button => { | |||
button.addEventListener('click', () => { | |||
const selectedTipo = button.dataset.tipo; | |||
if (selectedTipo === 'all') { | |||
activeTipos.clear(); | |||
tipoButtons.forEach(btn => | |||
btn.dataset.tipo === 'all' | |||
? btn.classList.add('ativo') | |||
: btn.classList.remove('ativo') | |||
); | |||
} else { | |||
if (activeTipos.has(selectedTipo)) { | |||
activeTipos.delete(selectedTipo); | |||
button.classList.remove('ativo'); | |||
} else { | |||
activeTipos.add(selectedTipo); | |||
button.classList.add('ativo'); | |||
} | |||
tipoButtons.forEach(btn => { | |||
if (btn.dataset.tipo === 'all') btn.classList.remove('ativo'); | |||
}); | |||
if (activeTipos.size === 0) { | |||
tipoButtons.forEach(btn => | |||
btn.dataset.tipo === 'all' | |||
? btn.classList.add('ativo') | |||
: null | |||
); | |||
} | |||
} | |||
updateFiltros(); | |||
}); | |||
}); | |||
// Adiciona ícones de classes dinamicamente (mais eficiente e sem repetição) | |||
const iconesClasse = { | |||
lutador: 'https://wiki.gla.com.br/images/e/e6/Fighter.png', | |||
especialista: 'https://wiki.gla.com.br/images/f/f6/Especialist.png', | |||
tanque: 'https://wiki.gla.com.br/images/9/9d/Tank.png', | |||
suporte: 'https://wiki.gla.com.br/images/a/ab/Support.png', | |||
bruiser: 'https://wiki.gla.com.br/images/e/e4/Bruiser.png', | |||
atirador: 'https://wiki.gla.com.br/images/e/ed/Shooter.png', | |||
dps: 'https://wiki.gla.com.br/images/6/60/Dps.png', | |||
cortante: 'https://wiki.gla.com.br/images/9/9a/Slasher.png', | |||
fruta: 'https://wiki.gla.com.br/images/e/e4/Devil-fruit.png', | |||
}; | |||
document.querySelectorAll('.personagem-box').forEach(box => { | |||
// Evita adicionar múltiplos wrappers (caso do hot-reload ou rerun) | |||
if (box.querySelector('.classe-icon-wrapper')) return; | |||
const classes = box.className.split(/\s+/); | |||
const icones = classes | |||
.filter(classe => iconesClasse.hasOwnProperty(classe)) | |||
.map(classe => { | |||
const img = document.createElement('img'); | |||
img.src = iconesClasse[classe]; | |||
img.alt = classe; | |||
img.className = 'classe-icon'; | |||
return img; | |||
}); | |||
if (icones.length > 0) { | |||
const wrapper = document.createElement('div'); | |||
wrapper.className = 'classe-icon-wrapper'; | |||
icones.forEach(icon => wrapper.appendChild(icon)); | |||
box.appendChild(wrapper); | |||
} | |||
}); | |||
// Tooltips melhorados e mais leves | |||
document.querySelectorAll('[data-tooltip-img], [data-tooltip-text]').forEach(btn => { | |||
let tooltip; | |||
if (btn.dataset.tooltipImg) { | |||
tooltip = document.createElement('img'); | |||
tooltip.src = btn.dataset.tooltipImg; | |||
tooltip.className = 'tooltip-img'; | |||
} | |||
if (btn.dataset.tooltipText) { | |||
tooltip = document.createElement('div'); | |||
tooltip.textContent = btn.dataset.tooltipText; | |||
tooltip.className = 'tooltip-img'; | |||
tooltip.style.background = '#222'; | |||
tooltip.style.color = '#fff'; | |||
tooltip.style.padding = '6px 10px'; | |||
tooltip.style.fontSize = '14px'; | |||
tooltip.style.textAlign = 'center'; | |||
tooltip.style.minWidth = '140px'; | |||
tooltip.style.maxWidth = '220px'; | |||
tooltip.style.wordBreak = "break-word"; | |||
} | |||
if (tooltip) { | |||
btn.style.position = 'relative'; | |||
btn.appendChild(tooltip); | |||
btn.addEventListener('mouseenter', () => tooltip.style.display = 'block'); | |||
btn.addEventListener('mouseleave', () => tooltip.style.display = 'none'); | |||
btn.addEventListener('focus', () => tooltip.style.display = 'block'); | |||
btn.addEventListener('blur', () => tooltip.style.display = 'none'); | |||
} | |||
}); | |||
// Sugestão de melhoria extra: | |||
// Poderia carregar a lista de personagens dinamicamente por JSON para separação do conteúdo/HTML | |||
// Poderia adicionar um "role" e "tabindex" nos cards para acessibilidade | |||
// Poderia criar um fallback para caso o gif não carregue, etc. | |||
</script> | |||
</body> | |||
</html> | |||
Edição das 17h45min de 4 de novembro de 2025
<!DOCTYPE html> <html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Teste GIF Hover</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* --- Melhorias gerais de estilo e responsividade, e código mais limpo --- */
body {
margin: 0;
font-family: 'Segoe UI', Arial, sans-serif;
color: #fff;
background: #171f2b;
min-height: 100vh;
}
.search-bar {
text-align: right;
padding: 20px;
background: #222c3a;
}
.search-bar input {
padding: 8px 14px;
width: 270px;
max-width: 90vw;
border-radius: 7px;
border: 1px solid #2f425e;
font-size: 1rem;
background: #101926;
color: #fff;
outline: none;
transition: border-color .2s;
}
.search-bar input:focus {
border-color: #58aaff;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(245px, 1fr));
gap: 22px;
width: 96vw;
margin: 0 auto;
justify-items: center;
padding-bottom: 30px;
}
@media (max-width: 1200px) {
.container { grid-template-columns: repeat(3, 1fr);}
}
@media (max-width: 900px) {
.container { grid-template-columns: repeat(2, 1fr);}
}
@media (max-width: 600px) {
.container { grid-template-columns: 1fr; }
}
.personagem {
width: 245px;
min-width: 0;
height: 110px;
aspect-ratio: 16/7;
border-radius: 10px;
background-size: 150% auto;
background-position: center -30px;
transition: transform 0.3s, box-shadow .3s;
display: flex;
align-items: flex-end;
justify-content: flex-end;
padding: 5px;
font-weight: bold;
color: #fff;
text-shadow: 1px 1px 4px #222, 0 0 20px #111;
position: relative;
cursor: pointer;
border: 2px solid #58aaff;
overflow: hidden;
text-decoration: none;
box-shadow: 0 2px 13px rgba(44,65,122, 0.08);
background-repeat: no-repeat;
}
@media (max-width: 400px) {
.personagem {
width: 98vw;
height: 80px;
font-size: 0.92em;
}
}
.personagem span {
z-index: 2;
font-size: 1.10rem;
font-weight: 900;
padding: 3px 10px;
border-radius: 7px;
background: linear-gradient(90deg, #000c 60%, #29292999 100%);
color: #fff;
text-shadow:
0 0 6px #001a33,
0 2px 8px #0008,
2px 2px 0 #000,
-2px -2px 0 #000;
box-shadow: 0 2px 8px #000a;
}
.gif-overlay {
position: absolute;
inset: 0;
background-repeat: no-repeat;
background-size: 150% auto;
background-position: center -30px;
opacity: 0;
z-index: 1;
pointer-events: none;
transition: opacity 0.3s;
}
.personagem:hover,
.personagem:focus-visible {
transform: scale(1.06);
box-shadow: 0px 4px 22px #46b6ff44, 0 1.5px 0 #1394ed;
}
.personagem:hover .gif-overlay,
.personagem:focus-visible .gif-overlay {
opacity: 1;
}
.personagem.luffy .gif-overlay { background-position: center 0px; }
.personagem.hancock { background-size: 115% auto; }
.personagem.daddy { background-size: 100% auto; background-position: top;}
.personagem.kizaru { background-position: center -20px; }
.personagem.luffypre{ background-position: center; }
.personagem.perona { background-position: center -80px; }
.personagem.sanjipre{ background-position: center -50px; }
.personagem.cabaji { background-size: 240% auto; background-position: center -80px;}
.personagem.gin { background-position: center -120px;}
.personagem.jango { background-position: left -40px top -20px; background-size: 180% auto;}
/* --------- Tiers ----------- */
.tier-diamante .personagem { background-color: #414c5c; }
.tier-gold .personagem { background-color: #c6a64e; }
.tier-prata .personagem { background-color: #a5a4af; }
.tier-bronze .personagem { background-color: #83623d; }
.filtros {
flex-wrap: wrap;
align-items: flex-start;
padding: 9px 2vw;
display: flex;
gap: 18px;
justify-content: space-between;
margin-bottom: 18px;
background: #212e3e;
border-bottom: 1.5px solid #19212c;
font-size: 1rem;
}
.filtros button {
padding: 8px 12px;
margin: 0 2px;
border: none;
border-radius: 5px;
background-color: #337cd7;
color: white;
font-weight: bold;
cursor: pointer;
transition: background 0.18s, filter .21s;
font-size: inherit;
outline: none;
border: 1.5px solid transparent;
}
.filtros button:focus-visible {
outline: 2px solid #58aaff;
filter: brightness(1.13);
}
.filtro-grupo,
.classe-grid {
display: flex;
flex-wrap: wrap;
gap: 7px 9px;
align-items: center;
justify-content: center;
}
.filtro-box {
background: #34475f11;
padding: 8px 12px;
border-radius: 8px;
min-width: 145px;
}
.filtro-box legend {
font-size: 16px;
font-weight: bold;
color: #5a8fcc;
margin-bottom: 6px;
text-align: center;
}
.filtros button:hover, .filtros button.ativo {
background-color: #2491e7;
filter: brightness(1.09);
border-color: #58aaff;
box-shadow: 0 0 6px #2473b355;
transform: scale(1.045);
}
.btn-vertical {
writing-mode: vertical-rl;
rotate: 270deg;
font-size: 0.97em;
letter-spacing: 0.15em;
}
.tier-btn {
background: #234;
border: none;
border-radius: 50%;
padding: 5px 8px;
cursor: pointer;
font-size: 0;
box-shadow: none;
outline: none;
transition: background 0.18s;
}
.tier-btn.ativo, .tier-btn:focus-visible {
background: #eaf2fb;
outline: 2px solid #58aaff;
}
.estrela {
font-size: 26px;
line-height: 1;
pointer-events: none;
filter: drop-shadow(0 0 2px #002) drop-shadow(0 1px 1px #0005);
}
.estrela.azul { color: #14a3ee; }
.estrela.dourada{ color: #ffc107; }
.estrela.prata { color: #c0c0c0; }
.estrela.bronze { color: #cd7f32; }
.classe-icon-wrapper {
position: absolute;
top: 5px;
left: 5px;
display: flex;
flex-direction: column;
gap: 2px;
z-index: 10;
pointer-events: none;
transition: transform 0.4s;
}
.classe-icon {
width: 28px;
height: 28px;
user-select: none;
pointer-events: none;
opacity: 0.94;
transition: opacity 0.3s;
}
.personagem-box:hover .classe-icon,
.personagem-box:focus-within .classe-icon {
opacity: 1;
}
.personagem-box {
position: relative;
transition: transform 0.4s, box-shadow .3s;
transform-origin: center center;
}
.personagem-box:hover, .personagem-box:focus-within {
transform: scale(1.04);
z-index: 2;
box-shadow: 0 6px 22px #23234770;
}
.classe-filtro-container {
display: flex;
align-items: center;
gap: 9px;
}
.tooltip-img {
position: absolute;
top: -110px;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: auto;
display: none;
pointer-events: none;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
z-index: 99;
}
.tipo-btn[data-tipo="parede"],
.tipo-btn[data-tipo="ponte"] {
margin-left: 8px;
}
.novos-container {
padding: 20px;
background: linear-gradient(to right, #e0f0ff, #ffffff);
border-radius: 12px;
margin: 20px auto;
width: 95%;
max-width: 1200px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.11);
border: 2px solid #58aaff;
}
.novos-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
border-bottom: 2px solid #58aaff;
padding-bottom: 6px;
}
.novos-title {
font-size: 20px;
font-weight: bold;
color: #006eff;
}
.new-gif {
width: 32px;
height: 32px;
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.17); opacity: 0.72; }
100% { transform: scale(1); opacity: 1; }
}
.novos-grid {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}
</style>
</head>
<body>
<fieldset class="filtro-box classe-filtro-container" aria-label="Filtrar por Classe">
<legend>Classe</legend>
<button class="btn-vertical tipo-btn ativo" data-tipo="all" title="Todos">ALL</button>
<button class="tipo-btn" data-tipo="lutador">Lutador</button>
<button class="tipo-btn" data-tipo="atirador">Atirador</button>
<button class="tipo-btn" data-tipo="cortante">Cortante</button>
<button class="tipo-btn" data-tipo="especialista">Especialista</button>
<button class="tipo-btn" data-tipo="tanque">Tanque</button>
<button class="tipo-btn" data-tipo="dps">DPS</button>
<button class="tipo-btn" data-tipo="suporte">Suporte</button>
<button class="tipo-btn" data-tipo="bruiser">Bruiser</button>
</fieldset>
<fieldset class="filtro-box" aria-label="Filtrar por Outros">
<legend>Outros</legend>
<button class="tipo-btn" data-tipo="parede" data-tooltip-text="Personagens que quebram parede">
<img src="https://wiki.gla.com.br/images/2/21/Wall-break.png" alt="parede" width="32" height="32">
</button>
<button class="tipo-btn" data-tipo="ponte" data-tooltip-text="Personagens que fazem ponte">
<img src="https://wiki.gla.com.br/images/8/80/Bridge.png" alt="ponte" width="32" height="32">
</button>
</fieldset>
<fieldset class="filtro-box" aria-label="Filtrar por Tier">
<legend>Tier</legend>
<button class="tier-btn" data-tier="tier-diamante" aria-label="Diamante">★</button> <button class="tier-btn" data-tier="tier-gold" aria-label="Ouro">★</button> <button class="tier-btn" data-tier="tier-prata" aria-label="Prata">★</button> <button class="tier-btn" data-tier="tier-bronze" aria-label="Bronze">★</button>
</fieldset>
Novos Personagens <img src="https://cdn-icons-png.flaticon.com/128/11135/11135991.png" alt="novo" class="new-gif">
<script> // Melhoria: evite código duplicado, use funções utilitárias
// Mover personagens novos
(() => {
const novosGrid = document.getElementById('novos-grid');
document.querySelectorAll('.personagem-box.novo').forEach(novoCard => {
novosGrid.appendChild(novoCard);
});
if (novosGrid.children.length === 0) {
document.querySelector('.novos-container').style.display = 'none';
}
})();
// Inicialização dos cards e overlays de gifs
document.querySelectorAll('.personagem').forEach(card => {
const staticImg = card.getAttribute('data-static');
const gifImg = card.getAttribute('data-gif');
const overlay = card.querySelector('.gif-overlay');
card.style.backgroundImage = staticImg ? `url('${staticImg}')` : ;
card.addEventListener('mouseenter', () => {
if (gifImg) overlay.style.backgroundImage = `url('${gifImg}?t=${Date.now()}')`;
});
card.addEventListener('mouseleave', () => {
overlay.style.backgroundImage = ;
});
card.addEventListener('focus', () => {
if (gifImg) overlay.style.backgroundImage = `url('${gifImg}?t=${Date.now()}')`;
});
card.addEventListener('blur', () => {
overlay.style.backgroundImage = ;
});
});
// Busca por nome, acessível e otimizada
document.getElementById('search').addEventListener('input', function () {
const term = this.value.toLowerCase();
document.querySelectorAll('.personagem').forEach(card => {
const name = card.querySelector('span').textContent.toLowerCase();
const wrapper = card.parentElement;
const tierBox = wrapper.parentElement;
// Só filtra se NÃO estiver na grid de novos personagens
if (!tierBox.classList.contains('novos-grid')) {
tierBox.style.display = name.includes(term) ? 'block' : 'none';
}
});
});
// Corrigido URLs dos links e checado duplicidade.
const personagemLinks = {
"Aokiji": "https://wiki.gla.com.br/index.php/Aokiji",
"Bartholomew Kuma": "https://wiki.gla.com.br/index.php/Kuma",
"Boa Hancock": "https://wiki.gla.com.br/index.php/Boa_Hancock",
"Borsalino Kizaru": "https://wiki.gla.com.br/index.php/Kizaru",
"Brook (TS)": "https://wiki.gla.com.br/index.php/Brook_(Timeskip)",
"Chopper (TS)": "https://wiki.gla.com.br/index.php/Chopper_(Timeskip)",
"Donquixote Doflamingo": "https://wiki.gla.com.br/index.php/Doflamingo",
"Dracule Mihawk": "https://wiki.gla.com.br/index.php/Mihawk",
"Emporio Ivankov": "https://wiki.gla.com.br/index.php/Ivankov",
"Enel": "https://wiki.gla.com.br/index.php/Enel",
"Franky (TS)": "https://wiki.gla.com.br/index.php/Franky_(Timeskip)",
"Jinbe": "https://wiki.gla.com.br/index.php/Jinbe",
"Marshall D. Teach": "https://wiki.gla.com.br/index.php/Marshall_D._Teach",
"Marco": "https://wiki.gla.com.br/index.php/Marco",
"Monkey D. Luffy (TS)": "https://wiki.gla.com.br/index.php/Luffy_(Timeskip)",
"Nami (TS)": "https://wiki.gla.com.br/index.php/Nami_(Timeskip)",
"Portgas D. Ace": "https://wiki.gla.com.br/index.php/Ace",
"Nico Robin (TS)": "https://wiki.gla.com.br/index.php/Robin_(Timeskip)",
"Roronoa Zoro (TS)": "https://wiki.gla.com.br/index.php/Zoro_(Timeskip)",
"Sabo": "https://wiki.gla.com.br/index.php/Sabo",
"Sakazuki (Akainu)": "https://wiki.gla.com.br/index.php/Akainu",
"Shanks": "https://wiki.gla.com.br/index.php/Shanks",
"Usopp (TS)": "https://wiki.gla.com.br/index.php/Usopp_(Timeskip)",
"Uta": "https://wiki.gla.com.br/index.php/Uta",
"Sanji (TS)": "https://wiki.gla.com.br/index.php/Sanji_(Timeskip)",
"Baby 5": "https://wiki.gla.com.br/index.php/Baby_5",
"Bartolomeo": "https://wiki.gla.com.br/index.php/Bartolomeo",
"Basil Hawkins": "https://wiki.gla.com.br/index.php/Basil_Hawkins",
"Bastille": "https://wiki.gla.com.br/index.php/Bastille",
"Bellamy": "https://wiki.gla.com.br/index.php/Bellamy",
"Jewelry Bonney": "https://wiki.gla.com.br/index.php/Bonney",
"Brook": "https://wiki.gla.com.br/index.php/Brook",
"Capone Gang Bege": "https://wiki.gla.com.br/index.php/Capone_Bege",
"Carrot": "https://wiki.gla.com.br/index.php/Carrot",
"Chopper": "https://wiki.gla.com.br/index.php/Chopper",
"Sir Crocodile": "https://wiki.gla.com.br/index.php/Crocodile",
"Dalmatian": "https://wiki.gla.com.br/index.php/Dalmatian",
"Franky": "https://wiki.gla.com.br/index.php/Franky",
"Gecko Moria": "https://wiki.gla.com.br/index.php/Gecko_Moria",
"Hina": "https://wiki.gla.com.br/index.php/Hina",
"Jesus Burgess": "https://wiki.gla.com.br/index.php/Jesus_Burgess",
"Eustass Kid": "https://wiki.gla.com.br/index.php/Kid",
"Killer": "https://wiki.gla.com.br/index.php/Killer",
"Koala": "https://wiki.gla.com.br/index.php/Koala",
"Leo & Mansherry": "https://wiki.gla.com.br/index.php/Leo",
"Monkey D. Luffy": "https://wiki.gla.com.br/index.php/Luffy",
"Nami": "https://wiki.gla.com.br/index.php/Nami",
"Perona": "https://wiki.gla.com.br/index.php/Perona",
"Rebecca": "https://wiki.gla.com.br/index.php/Rebecca",
"Robin": "https://wiki.gla.com.br/index.php/Robin",
"Zoro": "https://wiki.gla.com.br/index.php/Zoro",
"Ryuma": "https://wiki.gla.com.br/index.php/Ryuma",
"Scratchmen Apoo": "https://wiki.gla.com.br/index.php/Apoo",
"Smoker": "https://wiki.gla.com.br/index.php/Smoker",
"Trafalgar D. Water Law": "https://wiki.gla.com.br/index.php/Law",
"Urouge": "https://wiki.gla.com.br/index.php/Urouge",
"Usopp": "https://wiki.gla.com.br/index.php/Usopp",
"Van Augur": "https://wiki.gla.com.br/index.php/Van_Augur",
"Vinsmoke Ichiji": "https://wiki.gla.com.br/index.php/Ichiji",
"Vinsmoke Niji": "https://wiki.gla.com.br/index.php/Niji",
"Vinsmoke Reiju": "https://wiki.gla.com.br/index.php/Reiju",
"Vinsmoke Sanji": "https://wiki.gla.com.br/index.php/Sanji",
"Vinsmoke Yonji": "https://wiki.gla.com.br/index.php/Yonji",
"X Drake": "https://wiki.gla.com.br/index.php/X_Drake",
"Satori": "https://wiki.gla.com.br/index.php/Satori",
"Gedatsu": "https://wiki.gla.com.br/index.php/Gedatsu",
"Ohm": "https://wiki.gla.com.br/index.php/Ohm",
"Shura": "https://wiki.gla.com.br/index.php/Shura",
"Arlong": "https://wiki.gla.com.br/index.php/Arlong",
"Bepo": "https://wiki.gla.com.br/index.php/Bepo",
"Bon Clay": "https://wiki.gla.com.br/index.php/Mr.2",
"Buggy": "https://wiki.gla.com.br/index.php/Buggy",
"Daddy Masterson": "https://wiki.gla.com.br/index.php/Daddy_Masterson",
"Daz Bonez": "https://wiki.gla.com.br/index.php/Mr.1",
"Zala": "https://wiki.gla.com.br/index.php/Miss_Doublefinger",
"Don Krieg": "https://wiki.gla.com.br/index.php/Don_Krieg",
"Kuro": "https://wiki.gla.com.br/index.php/Kuro",
"Galdino": "https://wiki.gla.com.br/index.php/Mr.3",
"Tashigi": "https://wiki.gla.com.br/index.php/Tashigi",
"Nefertari Vivi": "https://wiki.gla.com.br/index.php/Vivi",
"Wapol": "https://wiki.gla.com.br/index.php/Wapol",
"Alvida": "https://wiki.gla.com.br/index.php/Alvida",
"Buchi & Sham": "https://wiki.gla.com.br/index.php/Buchi",
"Cabaji": "https://wiki.gla.com.br/index.php/Cabaji",
"Chew": "https://wiki.gla.com.br/index.php/Chew",
"Eric": "https://wiki.gla.com.br/index.php/Eric",
"Gin": "https://wiki.gla.com.br/index.php/Gin",
"Miss GoldenWeek": "https://wiki.gla.com.br/index.php/Goldenweek",
"Hatchan": "https://wiki.gla.com.br/index.php/Hatchan",
"Jango": "https://wiki.gla.com.br/index.php/Jango",
"Kuroobi": "https://wiki.gla.com.br/index.php/Kuroobi",
"Mohji": "https://wiki.gla.com.br/index.php/Mohji",
"Morgan": "https://wiki.gla.com.br/index.php/Morgan",
"Babe & Drophy": "https://wiki.gla.com.br/index.php/Mr.4",
"Gem & Mikita": "https://wiki.gla.com.br/index.php/Mr.5",
"Pearl": "https://wiki.gla.com.br/index.php/Pearl"
};
// Torna os personagens cards clicáveis, sem duplicar <a>
document.querySelectorAll('.personagem').forEach(card => {
const span = card.querySelector('span');
const nomePersonagem = span?.textContent.trim();
const link = personagemLinks[nomePersonagem];
if (link) {
if (card.parentElement.tagName.toLowerCase() !== 'a') {
const wrapper = document.createElement('a');
wrapper.href = link;
wrapper.target = "_blank";
wrapper.rel = "noopener";
wrapper.style.display = "flex";
wrapper.style.textDecoration = "none";
wrapper.style.flex = "0 1 auto";
wrapper.style.alignItems = "stretch";
card.parentElement.replaceChild(wrapper, card);
wrapper.appendChild(card);
}
}
});
// Filtros: tier, tipo
const tierButtons = document.querySelectorAll('.tier-btn');
const tipoButtons = document.querySelectorAll('.tipo-btn');
const personagemBoxes = document.querySelectorAll('.personagem-box');
let activeTier = 'all';
let activeTipos = new Set();
function updateFiltros() {
personagemBoxes.forEach(box => {
const matchesTier = activeTier === 'all' || box.classList.contains(activeTier);
const matchesTipo = activeTipos.size === 0 ||
Array.from(activeTipos).every(tipo => box.classList.contains(tipo));
box.style.display = (matchesTier && matchesTipo) ? 'block' : 'none';
});
}
tierButtons.forEach(button => {
button.addEventListener('click', () => {
const selectedTier = button.dataset.tier;
if (selectedTier === activeTier || selectedTier === 'all') {
activeTier = 'all';
tierButtons.forEach(btn => btn.classList.remove('ativo'));
} else {
activeTier = selectedTier;
tierButtons.forEach(btn => btn.classList.remove('ativo'));
button.classList.add('ativo');
}
updateFiltros();
});
});
tipoButtons.forEach(button => {
button.addEventListener('click', () => {
const selectedTipo = button.dataset.tipo;
if (selectedTipo === 'all') {
activeTipos.clear();
tipoButtons.forEach(btn =>
btn.dataset.tipo === 'all'
? btn.classList.add('ativo')
: btn.classList.remove('ativo')
);
} else {
if (activeTipos.has(selectedTipo)) {
activeTipos.delete(selectedTipo);
button.classList.remove('ativo');
} else {
activeTipos.add(selectedTipo);
button.classList.add('ativo');
}
tipoButtons.forEach(btn => {
if (btn.dataset.tipo === 'all') btn.classList.remove('ativo');
});
if (activeTipos.size === 0) {
tipoButtons.forEach(btn =>
btn.dataset.tipo === 'all'
? btn.classList.add('ativo')
: null
);
}
}
updateFiltros();
});
});
// Adiciona ícones de classes dinamicamente (mais eficiente e sem repetição)
const iconesClasse = {
lutador: 'https://wiki.gla.com.br/images/e/e6/Fighter.png',
especialista: 'https://wiki.gla.com.br/images/f/f6/Especialist.png',
tanque: 'https://wiki.gla.com.br/images/9/9d/Tank.png',
suporte: 'https://wiki.gla.com.br/images/a/ab/Support.png',
bruiser: 'https://wiki.gla.com.br/images/e/e4/Bruiser.png',
atirador: 'https://wiki.gla.com.br/images/e/ed/Shooter.png',
dps: 'https://wiki.gla.com.br/images/6/60/Dps.png',
cortante: 'https://wiki.gla.com.br/images/9/9a/Slasher.png',
fruta: 'https://wiki.gla.com.br/images/e/e4/Devil-fruit.png',
};
document.querySelectorAll('.personagem-box').forEach(box => {
// Evita adicionar múltiplos wrappers (caso do hot-reload ou rerun)
if (box.querySelector('.classe-icon-wrapper')) return;
const classes = box.className.split(/\s+/);
const icones = classes
.filter(classe => iconesClasse.hasOwnProperty(classe))
.map(classe => {
const img = document.createElement('img');
img.src = iconesClasse[classe];
img.alt = classe;
img.className = 'classe-icon';
return img;
});
if (icones.length > 0) {
const wrapper = document.createElement('div');
wrapper.className = 'classe-icon-wrapper';
icones.forEach(icon => wrapper.appendChild(icon));
box.appendChild(wrapper);
}
});
// Tooltips melhorados e mais leves
document.querySelectorAll('[data-tooltip-img], [data-tooltip-text]').forEach(btn => {
let tooltip;
if (btn.dataset.tooltipImg) {
tooltip = document.createElement('img');
tooltip.src = btn.dataset.tooltipImg;
tooltip.className = 'tooltip-img';
}
if (btn.dataset.tooltipText) {
tooltip = document.createElement('div');
tooltip.textContent = btn.dataset.tooltipText;
tooltip.className = 'tooltip-img';
tooltip.style.background = '#222';
tooltip.style.color = '#fff';
tooltip.style.padding = '6px 10px';
tooltip.style.fontSize = '14px';
tooltip.style.textAlign = 'center';
tooltip.style.minWidth = '140px';
tooltip.style.maxWidth = '220px';
tooltip.style.wordBreak = "break-word";
}
if (tooltip) {
btn.style.position = 'relative';
btn.appendChild(tooltip);
btn.addEventListener('mouseenter', () => tooltip.style.display = 'block');
btn.addEventListener('mouseleave', () => tooltip.style.display = 'none');
btn.addEventListener('focus', () => tooltip.style.display = 'block');
btn.addEventListener('blur', () => tooltip.style.display = 'none');
}
});
// Sugestão de melhoria extra: // Poderia carregar a lista de personagens dinamicamente por JSON para separação do conteúdo/HTML // Poderia adicionar um "role" e "tabindex" nos cards para acessibilidade // Poderia criar um fallback para caso o gif não carregue, etc. </script>
</body> </html>