Tooltip Magnético Animado
Uma dica de ferramenta animada e sofisticada que segue suavemente o movimento do cursor sobre o elemento.
HTMLCSSJavaScript
Visualização
Casos de uso e recursos
A dica de ferramenta magnética é um rico componente de UI que segue suavemente o cursor do usuário.
- Rastreamento suave: Adiciona um atraso (suavização) ao movimento do mouse para dar uma impressão natural e sofisticada.
- Design de morfismo de vidro: uma combinação de desfoque de fundo (filtro de fundo) e borda translúcida cria uma beleza futurista.
- Feedback intuitivo: perfeito para botões de call to action, cartões e outros elementos para os quais você deseja chamar a atenção.
Pontos de design e UX
- Conforto de animação
A interpolação linear (Lerp) usando a função de easing e
requestAnimationFrameatinge um movimento suave sem gagueira. - Hierarquia visual
Ao colocar em camadas
box-shadowebackdrop-filter, criamos um efeito tridimensional como se os elementos estivessem flutuando na tela. - Não interrompa a interação
A dica de ferramenta em si foi projetada com
pointer-events: nonepara não interferir nas operações de foco do usuário.
Como personalizar
- Após ajuste de velocidade:
Você pode ajustar a velocidade de rastreamento alterando o valor de
const speed = 0.15;em JavaScript (mais próximo de 1, mais rápido). - Alterar cor do tema:
Por favor, altere a cor de fundo de
linear-gradiente.magnetic-tooltipde.magnetic-targetem CSS para corresponder ao tema do projeto. - Deslocamento de posição:
Você pode alterar a distância do cursor até a dica de ferramenta ajustando o valor de
transform: ... translateY(-15px);em.magnetic-tooltip.visible.
Código de implementação
<div class="magnetic-tooltip-container">
<button class="magnetic-target" data-tooltip="🚀 新しいアップデートが利用可能です">
Hover Me
</button>
<button class="magnetic-target" data-tooltip="✨ プレミアム機能を見る">
Explore
</button>
<div class="magnetic-tooltip"></div>
</div>
<style>
.magnetic-tooltip-container {
display: flex;
gap: 2rem;
justify-content: center;
align-items: center;
min-height: 400px;
background: #000000;
background-image: radial-gradient(circle at 50% 50%, #1a1a2e 0%, #000000 100%);
border-radius: 1rem;
position: relative;
font-family: 'Inter', system-ui, sans-serif;
}
.magnetic-target {
padding: 1rem 2.5rem;
font-size: 1.125rem;
font-weight: 600;
color: #ffffff;
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 9999px;
cursor: pointer;
box-shadow: 0 10px 30px -10px rgba(139, 92, 246, 0.5);
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease, filter 0.3s ease;
}
.magnetic-target:hover {
box-shadow: 0 20px 40px -10px rgba(139, 92, 246, 0.7);
filter: brightness(1.1);
}
.magnetic-tooltip {
position: fixed;
top: 0;
left: 0;
pointer-events: none;
padding: 0.75rem 1.25rem;
background: rgba(15, 23, 42, 0.85);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 0.75rem;
color: #f8fafc;
font-size: 0.875rem;
font-weight: 500;
white-space: nowrap;
box-shadow:
0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 24px 38px 3px rgba(0, 0, 0, 0.14),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
opacity: 0;
transform: translate(-50%, -100%) scale(0.9) translateY(10px);
transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
z-index: 9999;
}
.magnetic-tooltip.visible {
opacity: 1;
transform: translate(-50%, -100%) scale(1) translateY(-15px);
}
</style>
<script>
(function initMagneticTooltip() {
const targets = document.querySelectorAll('.magnetic-target');
const tooltip = document.querySelector('.magnetic-tooltip');
if(!tooltip) return;
let mouseX = 0;
let mouseY = 0;
let tooltipX = 0;
let tooltipY = 0;
let isHovered = false;
let animationFrameId;
const speed = 0.15;
function animate() {
if (isHovered) {
tooltipX += (mouseX - tooltipX) * speed;
tooltipY += (mouseY - tooltipY) * speed;
tooltip.style.left = tooltipX + 'px';
tooltip.style.top = tooltipY + 'px';
animationFrameId = requestAnimationFrame(animate);
}
}
targets.forEach(function(target) {
target.addEventListener('mouseenter', function(e) {
isHovered = true;
tooltip.textContent = target.getAttribute('data-tooltip');
tooltip.classList.add('visible');
mouseX = e.clientX;
mouseY = e.clientY;
tooltipX = mouseX;
tooltipY = mouseY;
tooltip.style.left = tooltipX + 'px';
tooltip.style.top = tooltipY + 'px';
if (animationFrameId) cancelAnimationFrame(animationFrameId);
animate();
});
target.addEventListener('mousemove', function(e) {
mouseX = e.clientX;
mouseY = e.clientY;
// Magnetic pull effect on the button itself
const rect = target.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const deltaX = (mouseX - centerX) * 0.3;
const deltaY = (mouseY - centerY) * 0.3;
target.style.transform = 'translate(' + deltaX + 'px, ' + deltaY + 'px) scale(1.05)';
});
target.addEventListener('mouseleave', function() {
isHovered = false;
tooltip.classList.remove('visible');
target.style.transform = ''; // reset button position
if (animationFrameId) cancelAnimationFrame(animationFrameId);
});
});
})();
</script> Status de compatibilidade do navegador
- Cromo: Suportado
- Raposa de fogo: suportado
- Safári: Suportado Borda: Sim
*A propriedade backdrop-filter é suportada pelos principais navegadores mais recentes. Safari usa o prefixo -webkit-.