SnippetUI

Анимированный магнитный тултип

Сложная плавно появляющаяся анимированная всплывающая подсказка, плавно повторяющая движение курсора над элементом.

HTMLCSSJavaScript

Предварительный просмотр

Варианты использования и функции

Magnetic Tooltip — это богатый компонент пользовательского интерфейса, который плавно следует за курсором пользователя.

  • Плавное отслеживание: добавляет задержку (смягчение) к движению мыши, чтобы придать ему естественный и утонченный вид.
  • Дизайн Glassmorphism: сочетание размытия фона (фонового фильтра) и полупрозрачной границы создает футуристическую красоту.
  • Интуитивная обратная связь: идеально подходит для кнопок призыва к действию, карточек и других элементов, к которым вы хотите привлечь внимание.

##Точки дизайна и UX

  1. Комфорт анимации Линейная интерполяция (Lerp) с использованием функции замедления и requestAnimationFrame обеспечивает плавное движение без заиканий.
  2. Визуальная иерархия Наслаивая «box-shadow» и «backdrop-filter», мы создаем трехмерный эффект, как будто элементы плывут по экрану.
  3. Не прерывайте общение Сама всплывающая подсказка разработана с использованием pointer-events: none, чтобы не мешать пользователю выполнять операции наведения.

Как настроить

  • Последующая регулировка скорости: Вы можете настроить скорость отслеживания, изменив значение const Speed = 0,15; в JavaScript (ближе к 1, быстрее).
  • Изменить цвет темы: Пожалуйста, измените цвет фона linear-gradient и .Magnetic-tooltip .Magnetic-target в CSS, чтобы он соответствовал теме проекта.
  • Смещение позиции: Вы можете изменить расстояние от курсора до всплывающей подсказки, отрегулировав значение transform: ... TranslateY(-15px); в .Magnetic-tooltip.visible.

Код реализации

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

Статус совместимости браузера

  • Хром: поддерживается
  • Firefox: поддерживается
  • Сафари: поддерживается
  • Край: Да

*Свойство «backdrop-filter» поддерживается последними основными браузерами. Safari использует префикс -webkit-.