czsk/assets/inversion.js
Nikita 3fea00f30c
All checks were successful
Build and Deploy / build (push) Successful in 7s
Build and Deploy / deploy (push) Successful in 15s
123
2025-12-26 15:35:40 +01:00

116 lines
No EOL
4 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
// Проверяем поддержку backdrop-filter
const hasBackdropFilter = 'backdropFilter' in document.body.style ||
'webkitBackdropFilter' in document.body.style;
if (window.innerWidth <= 768) {
console.log('Мобильное устройство - кастомный курсор отключен');
return;
}
console.log('Инициализация курсора. Поддержка backdrop-filter:', hasBackdropFilter);
// Создаем элементы
const cursorOuter = document.createElement('div');
const cursorInner = document.createElement('div');
cursorOuter.className = 'cursor-outer';
cursorInner.className = 'cursor-inner';
// Если нет поддержки backdrop-filter, используем fallback
if (!hasBackdropFilter) {
cursorOuter.style.mixBlendMode = 'difference';
cursorOuter.style.backgroundColor = 'rgba(255, 255, 255, 0.2)';
cursorInner.style.mixBlendMode = 'difference';
}
document.body.appendChild(cursorOuter);
document.body.appendChild(cursorInner);
// Скрываем стандартный курсор
document.body.style.cursor = 'none';
// Переменные для анимации
let mouseX = window.innerWidth / 2;
let mouseY = window.innerHeight / 2;
let cursorX = mouseX;
let cursorY = mouseY;
let innerX = mouseX;
let innerY = mouseY;
let isVisible = false;
// Скорость следования
const outerSpeed = 0.25;
const innerSpeed = 0.15;
// Анимация
function animate() {
// Плавное движение
cursorX += (mouseX - cursorX) * outerSpeed;
cursorY += (mouseY - cursorY) * outerSpeed;
innerX += (mouseX - innerX) * innerSpeed;
innerY += (mouseY - innerY) * innerSpeed;
// Применяем позиции
cursorOuter.style.transform = `translate(${cursorX}px, ${cursorY}px)`;
cursorInner.style.transform = `translate(${innerX}px, ${innerY}px)`;
requestAnimationFrame(animate);
}
// Отслеживание мыши
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
if (!isVisible) {
cursorOuter.style.opacity = '1';
cursorInner.style.opacity = '1';
isVisible = true;
}
});
// Ховер-эффекты
const interactive = document.querySelectorAll(
'a, button, .photo-card, .number, .photo-container, img, .navigation a'
);
interactive.forEach(el => {
el.addEventListener('mouseenter', () => {
cursorOuter.style.width = '90px';
cursorOuter.style.height = '90px';
cursorOuter.style.borderWidth = '3px';
});
el.addEventListener('mouseleave', () => {
cursorOuter.style.width = '70px';
cursorOuter.style.height = '70px';
cursorOuter.style.borderWidth = '2px';
});
});
// Скрываем при выходе из окна
document.addEventListener('mouseleave', () => {
cursorOuter.style.opacity = '0';
cursorInner.style.opacity = '0';
isVisible = false;
});
// Показываем при входе в окно
document.addEventListener('mouseenter', () => {
if (document.body.style.cursor === 'none') {
cursorOuter.style.opacity = '1';
cursorInner.style.opacity = '1';
isVisible = true;
}
});
// Запускаем анимацию
animate();
// Обновляем при ресайзе
window.addEventListener('resize', () => {
mouseX = Math.min(mouseX, window.innerWidth);
mouseY = Math.min(mouseY, window.innerHeight);
});
});