Mudanças entre as edições de "Widget:Character.Skins"
Ir para navegação
Ir para pesquisar
m (fix) |
m |
||
| Linha 232: | Linha 232: | ||
.content-card .card-skins { | .content-card .card-skins { | ||
overflow: visible; | overflow: visible; | ||
min-height: auto; | min-height: 0; | ||
height: auto; | |||
} | |||
#skins .content-card { | |||
overflow: visible; | |||
min-height: 0; | |||
height: auto; | |||
} | } | ||
| Linha 441: | Linha 448: | ||
flex-wrap: wrap; | flex-wrap: wrap; | ||
gap: 20px; | gap: 20px; | ||
} | |||
#skins .content-card { | |||
overflow: visible !important; | |||
min-height: 0 !important; | |||
height: auto !important; | |||
} | |||
#skins .content-card .card-skins { | |||
overflow: visible !important; | |||
min-height: 0 !important; | |||
height: auto !important; | |||
} | } | ||
} | } | ||
</style> | </style> | ||
Edição das 19h55min de 24 de dezembro de 2025
<script>
(function initSkinPodiumUI() {
const podium = document.querySelector('.skins-podium');
if (!podium || podium.dataset.wired) return;
podium.dataset.wired = '1';
// ---------- Tooltip único ----------
function ensureTip() {
let tip = document.querySelector('.skin-tooltip');
if (!tip) {
tip = document.createElement('div');
tip.className = 'skin-tooltip';
tip.setAttribute('role', 'tooltip');
tip.setAttribute('aria-hidden', 'true');
tip.style.position = 'fixed';
tip.style.transform = 'translate(-9999px,-9999px)';
tip.style.opacity = '0';
tip.style.transition = 'opacity .12s ease';
document.body.appendChild(tip);
}
return tip;
}
const tip = ensureTip();
let hoveredSlot = null;
function place(card) {
if (!card || tip.getAttribute('aria-hidden') === 'true') return;
tip.style.transform = 'translate(-9999px,-9999px)';
const tr = tip.getBoundingClientRect();
// Pega a posição da imagem do tile (piso) para centralizar
const platformImg = card.querySelector('.podium-platform-top img');
let platformRect = card.getBoundingClientRect();
if (platformImg) {
platformRect = platformImg.getBoundingClientRect();
} else {
const platform = card.querySelector('.podium-platform');
if (platform) {
platformRect = platform.getBoundingClientRect();
}
}
// Centraliza horizontalmente baseado na imagem do tile
let leftPos = Math.round(platformRect.left + (platformRect.width - tr.width) / 2);
leftPos = Math.max(8, Math.min(leftPos, window.innerWidth - tr.width - 8));
// Posiciona logo abaixo da imagem do tile
let top = Math.round(platformRect.bottom + 15);
if (top + tr.height > window.innerHeight - 8) {
top = Math.round(platformRect.top - tr.height - 15);
if (top < 8) top = 8;
}
tip.style.transform = `translate(${leftPos}px, ${top}px)`;
}
function show(card) {
const tooltipText = card.getAttribute('data-skin-tooltip') || ;
tip.innerHTML = tooltipText;
tip.setAttribute('aria-hidden', 'false');
place(card);
tip.style.opacity = '1';
}
function hide() {
tip.setAttribute('aria-hidden', 'true');
tip.style.opacity = '0';
tip.style.transform = 'translate(-9999px,-9999px)';
}
// Função para restaurar z-index original baseado na posição do slot
function restoreOriginalZIndex(slot) {
if (!slot) return;
const allSlots = Array.from(podium.querySelectorAll('.podium-slot'));
const slotIndex = allSlots.indexOf(slot);
// Z-index invertido: esquerda (0) = mais alto, direita = mais baixo
const originalZIndex = allSlots.length - slotIndex;
const originalSpriteZIndex = (allSlots.length - slotIndex) * 1000;
slot.style.zIndex = originalZIndex.toString();
const spriteContainer = slot.querySelector('.podium-sprite-container');
if (spriteContainer) spriteContainer.style.zIndex = originalSpriteZIndex.toString();
}
function setHovered(card) {
if (hoveredSlot === card) return;
if (hoveredSlot) {
hoveredSlot.classList.remove('hovered');
restoreOriginalZIndex(hoveredSlot);
}
podium.classList.remove('hovering');
podium.querySelectorAll('.podium-slot.dim').forEach(n => n.classList.remove('dim'));
if (!card) {
hoveredSlot = null;
hide();
return;
}
hoveredSlot = card;
hoveredSlot.classList.add('hovered');
podium.classList.add('hovering');
podium.querySelectorAll('.podium-slot').forEach(n => {
if (n !== hoveredSlot) n.classList.add('dim');
});
// Qualquer skin com hover fica acima de tudo
card.style.zIndex = '9999';
const spriteContainer = card.querySelector('.podium-sprite-container');
if (spriteContainer) spriteContainer.style.zIndex = '9999';
show(card);
}
// Função para verificar se o pixel na posição do mouse é transparente
function isPixelTransparent(img, x, y) {
if (!img.complete || img.naturalWidth === 0) return true;
try {
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const rect = img.getBoundingClientRect();
const scaleX = img.naturalWidth / rect.width;
const scaleY = img.naturalHeight / rect.height;
const imgX = Math.floor((x - rect.left) * scaleX);
const imgY = Math.floor((y - rect.top) * scaleY);
if (imgX < 0 || imgX >= img.naturalWidth || imgY < 0 || imgY >= img.naturalHeight) {
return true;
}
const pixelData = ctx.getImageData(imgX, imgY, 1, 1).data;
return pixelData[3] < 10;
} catch (e) {
return false;
}
}
// ---------- Abrir YouTube (sem duplicar) ----------
podium.addEventListener('click', (ev) => {
const card = ev.target?.closest('.podium-slot[data-youtube]');
if (!card) return;
const url = (card.dataset.youtube || ).trim();
if (!url) return;
if (card.dataset._opening === '1') return;
card.dataset._opening = '1';
ev.preventDefault();
ev.stopPropagation();
ev.stopImmediatePropagation();
try { window.open(url, '_blank', 'noopener,noreferrer'); }
catch (e) { location.href = url; }
setTimeout(() => { delete card.dataset._opening; }, 500);
}, { capture: true });
podium.addEventListener('keydown', (ev) => {
if (ev.key !== 'Enter' && ev.key !== ' ') return;
const card = ev.target?.closest('.podium-slot[data-youtube]');
if (!card) return;
const url = (card.dataset.youtube || ).trim();
if (!url) return;
if (card.dataset._opening === '1') return;
card.dataset._opening = '1';
ev.preventDefault();
ev.stopPropagation();
ev.stopImmediatePropagation();
try { window.open(url, '_blank', 'noopener,noreferrer'); }
catch (e) { location.href = url; }
setTimeout(() => { delete card.dataset._opening; }, 500);
}, { capture: true });
// ---------- Hitbox pixel-perfect de hover ----------
const slots = podium.querySelectorAll('.podium-slot');
slots.forEach(slot => {
const spriteImg = slot.querySelector('.podium-sprite img');
if (spriteImg) {
spriteImg.addEventListener('pointerenter', (ev) => {
if (!slot.hasAttribute('data-skin-tooltip')) return;
if (!isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
setHovered(slot);
}
}, { passive: true });
spriteImg.addEventListener('pointermove', (ev) => {
if (!slot.hasAttribute('data-skin-tooltip')) return;
if (isPixelTransparent(spriteImg, ev.clientX, ev.clientY)) {
if (hoveredSlot === slot) setHovered(null);
} else {
if (hoveredSlot !== slot) setHovered(slot);
}
}, { passive: true });
spriteImg.addEventListener('pointerleave', (ev) => {
const toCard = ev.relatedTarget?.closest?.('.podium-slot');
if (toCard && podium.contains(toCard)) {
const otherImg = toCard.querySelector('.podium-sprite img');
if (otherImg && ev.relatedTarget && !isPixelTransparent(otherImg, ev.clientX, ev.clientY)) {
return;
}
}
setHovered(null);
}, { passive: true });
}
});
podium.addEventListener('pointerleave', () => { setHovered(null); }, { passive: true });
window.addEventListener('scroll', () => { if (hoveredSlot) place(hoveredSlot); }, true);
window.addEventListener('resize', () => { if (hoveredSlot) place(hoveredSlot); });
})();
</script> <style>
.skins-podium {
display: flex;
align-items: flex-end;
justify-content: center;
gap: 30px;
padding: 40px 20px;
}
.content-card .card-skins {
overflow: visible;
min-height: 0;
height: auto;
}
#skins .content-card {
overflow: visible;
min-height: 0;
height: auto;
}
.podium-slot {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
cursor: pointer;
transition: filter 0.14s ease, box-shadow 0.14s ease;
}
/* Z-index INVERTIDO: sprites da direita passam por trás das da esquerda */
.podium-slot:nth-child(1) {
z-index: 4;
}
.podium-slot:nth-child(2) {
z-index: 3;
}
.podium-slot:nth-child(3) {
z-index: 2;
}
.podium-slot:nth-child(4) {
z-index: 1;
}
.podium-slot:nth-child(5) {
z-index: 1;
}
/* Z-index INVERTIDO: sprites da direita passam por trás das da esquerda */
.podium-slot:nth-child(1) .podium-sprite-container {
z-index: 4000;
}
.podium-slot:nth-child(2) .podium-sprite-container {
z-index: 3000;
}
.podium-slot:nth-child(3) .podium-sprite-container {
z-index: 2000;
}
.podium-slot:nth-child(4) .podium-sprite-container {
z-index: 1000;
}
.podium-slot:nth-child(5) .podium-sprite-container {
z-index: 1000;
}
/* Hitbox baseada na imagem, não no container */
.podium-slot>* {
pointer-events: none;
}
.podium-sprite img {
pointer-events: auto;
}
.podium-sprite-container,
.podium-sprite {
pointer-events: none;
}
.podium-platform,
.podium-platform-top,
.podium-platform-top img {
pointer-events: none !important;
}
.podium-sprite-container {
position: relative;
z-index: 10;
display: flex;
align-items: flex-end;
justify-content: center;
filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.5));
transform: none !important;
flex-shrink: 0;
width: 100%;
}
.podium-sprite {
display: block;
position: relative;
transform: none !important;
flex-shrink: 0;
}
.podium-sprite img {
width: auto;
height: auto;
max-width: none;
max-height: none;
image-rendering: pixelated;
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
display: block;
position: relative;
z-index: 100 !important;
transform: none !important;
flex-shrink: 0;
}
.podium-platform {
position: absolute;
width: auto;
height: auto;
bottom: -15px;
right: -25px;
z-index: 0 !important;
}
.podium-platform-top {
position: absolute;
width: auto;
height: auto;
transform-origin: center bottom;
transform: rotateX(15deg);
z-index: -1 !important;
}
.podium-platform-top img {
display: block;
width: auto;
height: auto;
max-width: none;
max-height: none;
image-rendering: pixelated;
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
position: relative;
z-index: 1;
border: none !important;
outline: none;
box-shadow: none;
filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.5));
}
.skins-podium.hovering .podium-slot.dim {
filter: brightness(.55) saturate(.85);
transition: filter .14s ease;
}
.skins-podium.hovering .podium-slot.hovered {
filter: none;
}
.skins-podium.hovering .podium-slot.hovered .podium-platform-top {
box-shadow: none;
}
.skins-podium.hovering .podium-slot.hovered .podium-platform-top img {
box-shadow: none !important;
filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.5)) !important;
}
.skin-tooltip {
position: fixed;
z-index: 9999;
left: 0;
top: 0;
pointer-events: none;
padding: 10px 12px;
border-radius: 8px;
background: rgba(28, 28, 34, .98);
color: #eaeaea;
font-size: 13px;
line-height: 1.4;
box-shadow: 0 8px 24px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 255, 255, .06);
transform: translate(-9999px, -9999px);
opacity: 0;
transition: opacity .15s ease;
text-align: center;
white-space: normal;
max-width: 280px;
min-width: 200px;
}
.skin-tooltip b {
color: #fff;
}
.podium-slot.is-clickable {
cursor: pointer;
}
.podium-slot.is-clickable:focus {
outline: 2px solid #156bc7;
outline-offset: 2px;
}
@media (max-width: 1024px) {
.skins-podium {
gap: 24px;
}
}
@media (max-width: 768px) {
.skins-podium {
flex-wrap: wrap;
gap: 20px;
}
#skins .content-card {
overflow: visible !important;
min-height: 0 !important;
height: auto !important;
}
#skins .content-card .card-skins {
overflow: visible !important;
min-height: 0 !important;
height: auto !important;
}
}
</style>