Skip to content

Instantly share code, notes, and snippets.

@iamrobert
Last active April 11, 2025 12:06
Show Gist options
  • Save iamrobert/2da4a9ddbd3e608783f424e71b5084ad to your computer and use it in GitHub Desktop.
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>
(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