my-animation-lib
Version:
A powerful animation library combining Three.js, GSAP, custom scroll triggers, and advanced effects with MathUtils integration
108 lines (89 loc) • 2.77 kB
JavaScript
import { gsap } from 'gsap';
export class ScrollTrigger {
constructor() {
this.triggers = new Map();
this.scrollY = 0;
this.viewportHeight = window.innerHeight;
this.isInitialized = false;
}
async init() {
this.setupEventListeners();
this.isInitialized = true;
}
setupEventListeners() {
window.addEventListener('scroll', this.handleScroll.bind(this));
window.addEventListener('resize', this.handleResize.bind(this));
}
handleScroll() {
this.scrollY = window.pageYOffset;
this.updateTriggers();
}
handleResize() {
this.viewportHeight = window.innerHeight;
this.updateTriggers();
}
updateTriggers() {
this.triggers.forEach(trigger => {
if (trigger.isActive) {
this.updateTrigger(trigger);
}
});
}
updateTrigger(trigger) {
const rect = trigger.element.getBoundingClientRect();
const progress = this.calculateProgress(rect, trigger);
if (trigger.onUpdate) {
trigger.onUpdate(progress, trigger);
}
}
calculateProgress(rect, trigger) {
const elementTop = rect.top;
const elementHeight = rect.height;
const viewportHeight = this.viewportHeight;
let progress = 0;
if (trigger.start === 'top') {
progress = 1 - (elementTop / viewportHeight);
} else if (trigger.start === 'center') {
progress = 1 - ((elementTop + elementHeight / 2) / viewportHeight);
} else if (trigger.start === 'bottom') {
progress = 1 - ((elementTop + elementHeight) / viewportHeight);
}
return Math.max(0, Math.min(1, progress));
}
createTrigger(element, options = {}) {
const trigger = {
element,
start: options.start || 'top',
end: options.end || 'bottom',
onUpdate: options.onUpdate || null,
isActive: true,
...options
};
const id = `trigger_${Date.now()}_${Math.random()}`;
this.triggers.set(id, trigger);
return id;
}
createParallax(element, options = {}) {
const speed = options.speed || 0.5;
const direction = options.direction || 'vertical';
const trigger = this.createTrigger(element, {
onUpdate: (progress) => {
if (direction === 'vertical') {
gsap.set(element, {
y: progress * speed * 100
});
} else if (direction === 'horizontal') {
gsap.set(element, {
x: progress * speed * 100
});
}
}
});
return trigger;
}
destroy() {
window.removeEventListener('scroll', this.handleScroll);
window.removeEventListener('resize', this.handleResize);
this.triggers.clear();
}
}