Last active
April 11, 2025 12:06
-
-
Save iamrobert/2da4a9ddbd3e608783f424e71b5084ad to your computer and use it in GitHub Desktop.
A lightweight vanilla JavaScript library for creating magnetic hover effects on web elements. <button class="magnetic" data-strength="30" data-strength-text="15"> <span class="btn-text">Stronger Effect</span> </button>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
// Default configuration | |
const defaultConfig = { | |
selector: '.magnetic', | |
strength: 24, | |
textStrength: 18 | |
}; | |
// Public API | |
window.Magnetic = { | |
init | |
}; | |
// Initialize the magnetic effect | |
function init(options) { | |
const config = { ...defaultConfig, ...options }; | |
const items = document.querySelectorAll(config.selector); | |
items.forEach(el => { | |
// Parse numeric data-* attributes or fall back to config | |
const strength = parseFloat(el.getAttribute('data-strength')) || config.strength; | |
const textStrength = parseFloat(el.getAttribute('data-strength-text')) || config.textStrength; | |
const textEl = el.querySelector('.btn-text') || el.querySelector('span'); | |
el.addEventListener('mousemove', e => handleMouseMove(e, el, textEl, strength, textStrength)); | |
el.addEventListener('mouseleave', () => handleMouseLeave(el, textEl)); | |
}); | |
} | |
// Handle mouse movement | |
function handleMouseMove(e, el, textEl, strength, textStrength) { | |
const rect = el.getBoundingClientRect(); | |
const centerX = rect.left + rect.width / 2; | |
const centerY = rect.top + rect.height / 2; | |
const percentX = (e.clientX - centerX) / (rect.width / 2); | |
const percentY = (e.clientY - centerY) / (rect.height / 2); | |
el.style.transform = `translate(${percentX * strength}px, ${percentY * strength}px)`; | |
if (textEl) { | |
textEl.style.transform = `translate(${-percentX * textStrength}px, ${-percentY * textStrength}px)`; | |
} | |
} | |
// Handle mouse leave | |
function handleMouseLeave(el, textEl) { | |
el.style.transition = 'transform 0.3s ease'; | |
el.style.transform = 'translate(0, 0)'; | |
if (textEl) { | |
textEl.style.transition = 'transform 0.3s ease'; | |
textEl.style.transform = 'translate(0, 0)'; | |
} | |
setTimeout(() => { | |
el.style.transition = ''; | |
if (textEl) textEl.style.transition = ''; | |
}, 300); | |
} | |
// Auto-initialize | |
if (document.readyState === 'loading') { | |
document.addEventListener('DOMContentLoaded', () => window.Magnetic.init()); | |
} else { | |
window.Magnetic.init(); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment