Hello !
I am trying to recreate the vertical carousel I found on this page : https://www.giuligartner.com/motion/amelia I can't manage to have the following section (last placeholder) directly following the sectionGsapTest after the animation is finished :
- it seems like when the bts-photo-list and the sectionGsapTest scrolltrigger hit their end trigger, some more scrolling is adding (we see all of a sudden the scrollbar increase) resulting in adding unwanted blank space under everything.
- if I set the pinSpacing of this element back to True, there is an enormous unwanted blank space between the two element (carousel and last placeholder). Code explanation :
I created 3 containers :
.sectionGsapTest is the main container : it is pinned on place so that is sticks to the middle of the screen
.teaserContainer is the one responsible for the opening effect at the beginning : it's height will progressively increase.
.bts-photo-list will be moving up as if it where scrolling inside of the teaserContainer : it contains a list of 8 pictures. The height of each picture container is set to 60vh and there is a 20px margin between each picture. That's why you would see some calculation like this on the code : (window.innerHeight * 0.55 * photoLen) > if I set this as a fixed value, it wouldn't stop directly after the photo list end.
Also there are a lot of issues that are really not good comparing to the website where I found it (https://www.giuligartner.com/motion/amelia) : the smoothness is not good and it may have to do with a lot of layers I added. On page reload it doesn't seem to really keep up the location of the scroll and the whole process is pretty wacky and failing. Maybe there is a better way of doing this.
I found this code on the example website but I don't understand it :
<!-- Timothy Ricks' wonderful GSAP text animations, thank you for sharing, Timothy! -->
// Code by T.RICKS, https://www.tricksdesign.com/
window.addEventListener("DOMContentLoaded", (event) => {
// Split text into spans
let typeSplit = new SplitType("[text-split]", {
types: "words, chars",
tagName: "span"
});
// Link timelines to scroll position
function createScrollTrigger(triggerElement, timeline) {
// Reset tl when scroll out of view past bottom of screen
ScrollTrigger.create({
trigger: triggerElement,
start: "top bottom",
onLeaveBack: () => {
timeline.progress(0);
timeline.pause();
}
});
// Play tl when scrolled into view (60% from top of screen)
ScrollTrigger.create({
trigger: triggerElement,
start: "top 85%",
onEnter: () => timeline.play()
});
}
$("[words-rotate-in]").each(function (index) {
let tl = gsap.timeline({ paused: true });
tl.set($(this).find(".word"), { transformPerspective: 1000 });
tl.from($(this).find(".word"), { rotationX: -90, duration: 0.8, ease: "power2.out", stagger: { amount: 0.8 } });
createScrollTrigger($(this), tl);
});
// Avoid flash of unstyled content
gsap.set("[text-split]", { opacity: 1 });
});