VZ Scroll Interactions
A lightweight, universal scroll interaction library that works with any framework - vanilla JavaScript, React, Vue, Angular, and more. Create smooth scroll-triggered animations with minimal setup.
Features
- 🚀 Universal: Works with any framework or vanilla JavaScript
- 🪶 Lightweight: Minimal footprint with no dependencies
- ⚡ Performance: Optimized scroll handling with built-in throttling
- 🎯 Precise: Advanced trigger point calculations
- 🧹 Clean: Automatic cleanup and memory management
- 📱 Responsive: Built-in viewport width tracking
Installation
npm install vz-scroll-interactions
Quick Start
Vanilla JavaScript
import scrollTrigger from 'vz-scroll-interactions';
const element = document.querySelector('.my-element');
scrollTrigger.createInstance('fade-in', element, {
values: [[0, 1]], // Animate from 0 to 1
startPoint: [0.8], // Start when element is 80% in viewport
endPoint: [0.2], // End when element is 20% in viewport
callback: ({ v }) => {
element.style.opacity = v[0];
}
});
React
import { useEffect, useRef } from 'react';
import scrollTrigger from 'vz-scroll-interactions';
function AnimatedComponent() {
const elementRef = useRef();
useEffect(() => {
const instance = scrollTrigger.createInstance('slide-in', elementRef, {
values: [[100, 0]], // Slide from 100px to 0px
callback: ({ v }) => {
elementRef.current.style.transform = `translateX(${v[0]}px)`;
}
});
return () => {
scrollTrigger.removeInstance('slide-in');
};
}, []);
return <div ref={elementRef}>Animated content</div>;
}
Vue
import { ref, onMounted, onUnmounted } from 'vue';
import scrollTrigger from 'vz-scroll-interactions';
export default {
setup() {
const elementRef = ref();
onMounted(() => {
scrollTrigger.createInstance('rotate', elementRef, {
values: [[0, 360]], // Rotate from 0 to 360 degrees
callback: ({ v }) => {
elementRef.value.style.transform = `rotate(${v[0]}deg)`;
}
});
});
onUnmounted(() => {
scrollTrigger.removeInstance('rotate');
});
return { elementRef };
}
};
API Reference
Main Methods
createInstance(key, element, options)
Creates a new scroll interaction instance.
Parameters:
key
(string): Unique identifier for the instanceelement
(HTMLElement | Ref): Target element or React/Vue refoptions
(object): Configuration options
Options:
{
values: [[startValue, endValue]], // Array of value pairs to animate
startPoint: [0.5], // When animation starts (0-1, viewport percentage)
endPoint: [0.5], // When animation ends
callback: ({ v, ref, vw, start, end }) => {}, // Animation callback
unrestrictedCallback: ({ ref, vw }) => {}, // Always-called callback
isUnrestricted: false // Whether to use unrestricted mode
}
removeInstance(key)
Removes a scroll interaction instance and cleans up resources.
toggleInstance(key, enabled)
Enables or disables a specific instance without removing it.
Advanced Methods
calcTop(element, customStart)
calcBot(element, customEnd)
distance(element)
calcPercent(start, end, current)
calcCurrent(start, end, percentage)
Utility methods for custom calculations.
Global Configuration
setVzSIFactor(factor)
Sets a global scaling factor for all calculations (useful for responsive designs).
import { setVzSIFactor } from 'vz-scroll-interactions';
// Scale all calculations by 0.8
setVzSIFactor(0.8);
Advanced Usage
Multiple Value Animations
scrollTrigger.createInstance('complex-animation', element, {
values: [
[0, 100], // First value: 0 to 100
[1, 0], // Second value: 1 to 0
[0, 360] // Third value: 0 to 360
],
callback: ({ v }) => {
element.style.transform = `translateX(${v[0]}px) scale(${v[1]}) rotate(${v[2]}deg)`;
}
});
Custom Trigger Points
// Start when element top hits 80% of viewport
// End when element bottom hits 20% of viewport
scrollTrigger.createInstance('custom-trigger', element, {
startPoint: [0.8],
endPoint: [0.2],
values: [[0, 1]],
callback: ({ v, start, end }) => {
console.log(`Progress: ${v[0]}, Start: ${start}, End: ${end}`);
}
});
Responsive Animations
scrollTrigger.createInstance('responsive', element, {
values: [[0, 100]],
callback: ({ v, vw }) => {
// Different animations based on viewport width
if (vw <= 768) {
element.style.transform = `translateY(${v[0]}px)`;
} else {
element.style.transform = `translateX(${v[0]}px)`;
}
}
});
Browser Support
- Modern browsers (ES6+)
- IE11+ (with polyfills)
- Mobile browsers
- Server-side rendering safe
Performance Tips
- Reuse instances when possible instead of creating new ones
- Use throttling for heavy animations
- Clean up instances when components unmount
- Batch DOM updates in your callbacks
License
MIT License - see LICENSE file for details.
Contributing
Contributions welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.
Support
- 📖 Documentation
- 🐛 Issues
- 💬 Discussions