my-animation-lib
Version:
A powerful animation library combining Three.js, GSAP, custom scroll triggers, and advanced effects with MathUtils integration
185 lines (151 loc) • 4.81 kB
JavaScript
import { gsap } from 'gsap';
export class TextEffects {
constructor(element, options = {}) {
this.element = element;
this.options = {
duration: options.duration || 1,
easing: options.easing || 'power2.out',
...options
};
}
typewriter(options = {}) {
const text = this.element.textContent;
this.element.textContent = '';
const timeline = gsap.timeline();
for (let i = 0; i < text.length; i++) {
const span = document.createElement('span');
span.textContent = text[i];
span.style.opacity = '0';
this.element.appendChild(span);
timeline.to(span, {
opacity: 1,
duration: options.speed || 0.05,
ease: options.easing || this.options.easing
}, i * (options.speed || 0.05));
}
return timeline;
}
scramble(options = {}) {
const originalText = this.element.textContent;
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()';
const duration = options.duration || this.options.duration;
const timeline = gsap.timeline();
timeline.to({}, {
duration: duration,
onUpdate: function() {
const progress = this.progress();
const scrambledText = originalText.split('').map((char, index) => {
if (progress > index / originalText.length) {
return originalText[index];
}
return chars[Math.floor(Math.random() * chars.length)];
}).join('');
this.targets()[0].element.textContent = scrambledText;
},
onUpdateParams: [this]
});
return timeline;
}
wave(options = {}) {
const text = this.element.textContent;
this.element.textContent = '';
const timeline = gsap.timeline({ repeat: -1 });
for (let i = 0; i < text.length; i++) {
const span = document.createElement('span');
span.textContent = text[i];
span.style.display = 'inline-block';
this.element.appendChild(span);
timeline.to(span, {
y: options.amplitude || -20,
duration: options.duration || 0.5,
ease: 'sine.inOut',
delay: i * (options.delay || 0.1)
}, 0);
}
return timeline;
}
bounce(options = {}) {
const text = this.element.textContent;
this.element.textContent = '';
const timeline = gsap.timeline({ repeat: -1 });
for (let i = 0; i < text.length; i++) {
const span = document.createElement('span');
span.textContent = text[i];
span.style.display = 'inline-block';
this.element.appendChild(span);
timeline.to(span, {
y: options.amplitude || -30,
duration: options.duration || 0.6,
ease: 'bounce.out',
delay: i * (options.delay || 0.1)
}, 0);
}
return timeline;
}
fadeIn(options = {}) {
const timeline = gsap.timeline();
timeline.fromTo(this.element, {
opacity: 0,
y: 50
}, {
opacity: 1,
y: 0,
duration: options.duration || this.options.duration,
ease: options.easing || this.options.easing
});
return timeline;
}
slideIn(options = {}) {
const direction = options.direction || 'left';
const timeline = gsap.timeline();
let startProps = {};
if (direction === 'left') startProps.x = -100;
else if (direction === 'right') startProps.x = 100;
else if (direction === 'up') startProps.y = 100;
else if (direction === 'down') startProps.y = -100;
timeline.fromTo(this.element, {
...startProps,
opacity: 0
}, {
x: 0,
y: 0,
opacity: 1,
duration: options.duration || this.options.duration,
ease: options.easing || this.options.easing
});
return timeline;
}
rotateIn(options = {}) {
const timeline = gsap.timeline();
timeline.fromTo(this.element, {
rotation: options.startRotation || -180,
scale: 0,
opacity: 0
}, {
rotation: 0,
scale: 1,
opacity: 1,
duration: options.duration || this.options.duration,
ease: options.easing || this.options.easing
});
return timeline;
}
glitch(options = {}) {
const intensity = options.intensity || 10;
const timeline = gsap.timeline({ repeat: -1 });
timeline.to(this.element, {
duration: 0.1,
x: intensity,
ease: "none"
}).to(this.element, {
duration: 0.1,
x: -intensity,
ease: "none"
}).to(this.element, {
duration: 0.1,
x: 0,
ease: "none"
});
return timeline;
}
}