UNPKG

@thecoderzeus/scroll-reveal-fx

Version:

Uma suíte de animação de alta performance, modular e sem dependências, para criar interações ricas e elegantes baseadas no scroll e no mouse.

106 lines (87 loc) 4.04 kB
/** * @param {object} [options={}] - The configuration options. * @param {string} [options.selector] - The CSS selector for elements to apply the effect to. * @param {number} [options.intensity=10] - The max rotation in degrees. * @param {number} [options.perspective=1000] - The perspective value for the 3D effect. * @param {number} [options.speed=400] - The transition speed in ms when entering/leaving. * @param {string} [options.easing='cubic-bezier(0.03, 0.98, 0.52, 0.99)'] - Easing for the transition. */ export function applyTilt(options = {}) { const defaults = { selector: '.tilt', intensity: 10, perspective: 1000, speed: 400, easing: 'cubic-bezier(0.03, 0.98, 0.52, 0.99)', }; const config = { ...defaults, ...options }; const elements = document.querySelectorAll(config.selector); if (elements.length === 0) { console.warn(`Tilt: No elements found with selector: "${config.selector}"`); return; } elements.forEach(el => { if (el.parentElement) { el.parentElement.style.perspective = `${config.perspective}px`; } el.addEventListener('mousemove', (e) => { const rect = el.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const rotateX = ((y - centerY) / centerY) * -config.intensity; const rotateY = ((x - centerX) / centerX) * config.intensity; el.style.transition = `transform 50ms linear`; el.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; }); el.addEventListener('mouseleave', () => { el.style.transition = `transform ${config.speed}ms ${config.easing}`; el.style.transform = 'rotateX(0deg) rotateY(0deg)'; }); }); } export function applyMagnetism(options) { const defaults = { selector: '.magnetic', intensity: 0.2, threshold: 100, easing: 'cubic-bezier(0.03, 0.98, 0.52, 0.99)', scale: 1.1 }; const config = { ...defaults, ...options }; const elements = document.querySelectorAll(config.selector); elements.forEach(element => { let animationFrameId = null; element.addEventListener('mousemove', (e) => { const rect = element.getBoundingClientRect(); const mouseX = e.clientX; const mouseY = e.clientY; const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const deltaX = mouseX - centerX; const deltaY = mouseY - centerY; const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance < config.threshold) { const targetX = deltaX * config.intensity; const targetY = deltaY * config.intensity; cancelAnimationFrame(animationFrameId); animationFrameId = requestAnimationFrame(() => { element.style.transform = `translate3d(${targetX}px, ${targetY}px, 0) scale(${config.scale})`; element.style.transition = `transform 0.2s ${config.easing}`; }); } else { // Se o mouse está fora do threshold mas ainda sobre o elemento, reseta. resetTransform(); } }); const resetTransform = () => { cancelAnimationFrame(animationFrameId); animationFrameId = requestAnimationFrame(() => { element.style.transform = 'translate3d(0, 0, 0) scale(1)'; element.style.transition = `transform 0.5s ${config.easing}`; }); }; element.addEventListener('mouseleave', resetTransform); }); }