Aperçu

Cas d’utilisation et fonctionnalités

L’info-bulle magnétique est un composant d’interface utilisateur riche qui suit en douceur le curseur de l’utilisateur.

Points de conception et d’UX

  1. Confort d’animation L’interpolation linéaire (Lerp) utilisant la fonction d’assouplissement et « requestAnimationFrame » permet d’obtenir un mouvement fluide sans bégaiement.
  2. Hiérarchie visuelle En superposant « box-shadow » et « background-filter », nous créons un effet tridimensionnel comme si les éléments flottaient sur l’écran.
  3. N’interrompez pas l’interaction L’info-bulle elle-même est conçue avec « pointer-events : none » afin de ne pas interférer avec les opérations de survol de l’utilisateur.

Comment personnaliser

##Code d’implémentation

<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>

État de compatibilité du navigateur

*La propriété backdrop-filter est prise en charge par les derniers principaux navigateurs. Safari utilise le préfixe -webkit-.