I have a long page with multiple scroll based simple animations, some of them use the same class name to run different places.
At some point it seems the trigger position gets off for all the page and animations at the bottom of the screen are happening in the wrong place,
If I open console in the browser the animations are back at the correct position.
(function () {
gsap.registerPlugin(ScrollTrigger);
gsap.defaults({ease: "power4.out"});
ScrollTrigger.matchMedia({
// desktop
"(min-width: 800px)": function () {
mySplitText = new SplitText(".corona-hero-section h2", {type: "words,chars"});
chars = mySplitText.chars; //an array of all the divs that wrap each character
gsap.set(".corona-hero-section h2", {perspective: 400});
var tl = gsap.timeline();
tl
.from(".logo", {duration: 2, autoAlpha: 0, y: -60, stagger: 0.3}, 1)
.from(chars, {
duration: 0.8,
opacity: 0,
scale: 0,
y: 80,
rotationX: 180,
transformOrigin: "0% 50% -50",
ease: "back",
stagger: 0.01
}, "+=0");
tl.restart();
scheneChange(5, 140, '.viewer', '.scene', false, 'bottom bottom');
scheneChange(4, 138, '.viewer2', '.scene2', false, 'bottom bottom');
scheneChange(1, 122, '.viewer4', '.scene4', false, 'bottom bottom');
scheneChange(3, 146, '.viewer5', '.scene5', false, 'bottom bottom');
scheneChange(2, 139, '.viewer6', '.scene6', false, 'bottom bottom');
animateImageReveal();
animateStaggerIcons('.icon-list', '.icon-list__item');
animateStaggerIcons('.icon-num', '.icon-num__item');
animateStaggerIcons('.icon-top', '.icon-top__item');
aminateStaggerLi('.map-wrap__item');
aminateStaggerLi('.program-list-wrap li');
},
// mobile
"(max-width: 799px)": function () {
// Icons and text animation
gsap.utils.toArray('.icon-list__item').forEach((section) => {
const tls = gsap.timeline({
scrollTrigger: {
trigger: section,
scrub: true,
start: "top center",
// markers: true,
end: "+=20%",
},
});
const delay = 0.5;
const textIcon = section.querySelectorAll(".icon-list__icon");
const textTitle = section.querySelectorAll(".icon-list__title");
const textText = section.querySelector(".icon-list__text");
const textNum = section.querySelector(".icon-list__num");
tls
.from(textNum, {duration: 3, autoAlpha: 0, y: -60, stagger: delay}, 0)
.from(textIcon, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.3)
.from(textTitle, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.6)
.from(textText, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.9)
});
scheneChange(5, 140, '.viewer', '.scene');
scheneChange(4, 138, '.viewer2', '.scene2');
scheneChange(1, 122, '.viewer4', '.scene4', false);
scheneChange(3, 146, '.viewer5', '.scene5');
scheneChange(2, 139, '.viewer6', '.scene6', false);
scheneImageReveal();
animateIconNum();
scheneChange(1, 163.5, '.viewer3', '.scene3');
},
"all": function () {
animateTitleSection();
morphImg('.scene3');
}
});
function scheneChange(frames, offset, classToAnimate, action, pin = true, start = "center center") {
var frame_count = frames,
offset_value = offset;
gsap.to(classToAnimate, {
backgroundPosition: (-offset_value * frame_count * 2) + "px 50%",
ease: "steps(" + frame_count + ")", // use a stepped ease for the sprite sheet
scrollTrigger: {
trigger: action,
start: start,
end: "+=" + (frame_count * offset_value),
pin: pin,
// markers: true,
scrub: true,
}
});
}
function morphImg(trigger) {
const tls3 = gsap.timeline({
scrollTrigger: {
trigger: trigger,
scrub: true,
start: "top center",
// markers: true,
end: "+=40%",
},
});
tls3
.to('#inIsrael', {duration: 2, fill: "#9191a0", morphSVG: "#inMaoz"}, 0)
.to('#israelText', {duration: 2, morphSVG: "#maozText"}, 0)
.to('#israelUnderText', {duration: 2, morphSVG: "#maozUnderText"}, 0.2)
}
function animateIconNum() {
const sections = gsap.utils.toArray('.icon-num__item');
sections.forEach((section) => {
const tls = gsap.timeline({
scrollTrigger: {
trigger: section,
scrub: true,
start: "top center",
// markers: true,
end: "+=20%",
},
});
const delay = 0.5;
const textIcon = section.querySelectorAll(".icon-num__icon");
const textTitle = section.querySelectorAll(".icon-num__title");
const textText = section.querySelector(".icon-num__text");
// const textNum = section.querySelector(".icon-list__num");
tls
.from(textText, {duration: 3, autoAlpha: 0, y: -60, stagger: delay}, 0)
.from(textIcon, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.3)
.from(textTitle, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.6)
// .from(textText, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.9)
});
}
function animateTitleSection() {
const sections = gsap.utils.toArray(".corona-header");
sections.forEach((section) => {
const splitTimeline = gsap.timeline({
scrollTrigger: {
trigger: section,
scrub: true,
end: "+=70%",
// onToggle: self => gsap.to(".split-text", {opacity: self.isActive ? 1 : 0}),
toggleActions: "restart pause restart none",
//markers: true
}
});
const split = new SplitText(section);
splitTimeline
.to(section, {duration: 1, backgroundColor: '#fff', ease: "none"}, 0)
.to(section, {duration: 1, backgroundColor: '#222241', ease: "none"}, 1)
.from(split.chars, {
duration: 2,
opacity: 0,
x: "random(-500, 500)",
y: "random(-500, 500)",
z: "random(-500, 500)",
scale: .1,
yoyo: true,
stagger: 0.02
});
});
}
function animateImageReveal() {
let revealContainers = gsap.utils.toArray(".reveal");
revealContainers.forEach((container) => {
let tlImage = gsap.timeline({
scrollTrigger: {
trigger: container,
scrub: true,
start: "top 100%",
end: "bottom 70%",
}
});
tlImage.from(container, {duration: 0.3, autoAlpha: 0, y: -60, stagger: 0.3}, 1);
});
}
function scheneImageReveal() {
let revealContainers = gsap.utils.toArray(".reveal");
revealContainers.forEach((container) => {
let image = container.querySelector('img');
let tlImage = gsap.timeline({
scrollTrigger: {
trigger: container,
start: "20% 70%",
toggleActions: "restart none none reset",
}
});
tlImage.set(container, {autoAlpha: 1});
tlImage.from(container, 1.5, {
xPercent: -100,
ease: Power2.out
});
tlImage.from(image, 1.5, {
xPercent: 100,
// scale: 0.7,
delay: -1.5,
ease: Power2.out
});
});
}
function aminateStaggerLi(trigger) {
gsap.set(trigger, {y: 100});
ScrollTrigger.batch(trigger, {
onEnter: batch => gsap.to(batch, {opacity: 1, y: 0, stagger: {each: 0.15, grid: [1, 3]}, overwrite: true}),
onLeave: batch => gsap.set(batch, {opacity: 0, y: -100, overwrite: true}),
onEnterBack: batch => gsap.to(batch, {opacity: 1, y: 0, stagger: 0.15, overwrite: true}),
onLeaveBack: batch => gsap.set(batch, {opacity: 0, y: 100, overwrite: true})
});
ScrollTrigger.addEventListener("refreshInit", () => gsap.set(trigger, {y: 0}));
}
function animateStaggerIcons(list, listItem) {
gsap.utils.toArray(list).forEach(section => {
const elems = section.querySelectorAll(listItem);
// Set things up
gsap.set(elems, {y: 50, opacity: 0});
ScrollTrigger.create({
trigger: section,
start: 'top 60%',
onEnter: () => gsap.to(elems, {
y: 0,
opacity: 1,
duration: 1,
stagger: 0.2,
delay: 0.3,
ease: 'power3.out',
overwrite: 'auto'
}),
onLeaveBack: () => gsap.to(elems, {
y: 50,
opacity: 0,
duration: 1,
stagger: 0.2,
delay: 0.3,
ease: 'power3.out',
overwrite: 'auto'
})
});
})
}
})();