AmanVerma Posted February 7 Share Posted February 7 Greetings to fellow devs here! I am trying to animate two children divs to move in the opposite directions using scrolltrigger. Got this suggestion from Google Bard, to put the elements in an array and then try to animate them. But the issue is, even though I am specifying opposite percentages, the elements are still moving in the same direction. Below are CSS and React codes attached. I am using refs and the latest useGSAP hook. And here is the codepen with issue reproduced : here is css @import url("https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Inter:wght@100..900&family=Oswald:wght@200..700&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); .main { height: 100vh; margin: 0; padding: 0; } .c1 { display: flex; align-items: flex-end; height: 100%; background: red; overflow: hidden; } .c1 h1 { text-transform: uppercase; color: #fff; font-size: 40vw; font-family: "Oswald"; white-space: nowrap; font-weight: 500; letter-spacing: -30px; } .content2 { height: 100%; background: #000; z-index: -1; font-family: "Inter"; display: grid; place-items: center; position: relative; } .data1, .data2 { width: 50%; background: rgba(167, 255, 56, 1); padding: 2.5rem; margin: 10px auto; border-radius: 25px; z-index: 1; } .data2 { background: rgba(253, 151, 255, 1); position: absolute; z-index: 0; } @media (max-width: 750px) { .data1 h1 { font-size: 2.5rem; font-weight: 900; } } here is the react code: import React, { useRef } from "react"; import gsap from "gsap"; import { useGSAP } from "@gsap/react"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import "./LenScroll.css"; export default function LenisScroll() { const heading = useRef(); const container = useRef(); const data1 = useRef(); const data2 = useRef(); useGSAP( () => { gsap.registerPlugin(ScrollTrigger); const tl = gsap.timeline(); tl.to(heading.current, { x: "-100%", fontWeight: 200, letterSpacing: "1rem", scrollTrigger: { trigger: ".c1", scroller: "body", scrub: 0.2, pin: true, }, }); // THIS RIGHT HERE! gsap.to([data1.current, data2.current], { y: ["-100%", "-100%"], scrollTrigger: { trigger: ".content2", scroller: "body", pin: true, scrub: 0.8, markers: true, }, }); }, { scope: container.current }, ); return ( <div ref={container} className="main"> <div className="c1"> <h1 ref={heading}>Aman Verma</h1> </div> <div className="content2"> <div ref={data1} className="data1"> <h1>Para is the easiest way to earn money as a Software engineer</h1> </div> <div ref={data2} className="data2"> <h1>Para is the easiest way to earn money as a Software engineer</h1> </div> </div> </div> ); } See the Pen xxBJyyY by amanopia (@amanopia) on CodePen Link to comment Share on other sites More sharing options...
Solution mvaneijgen Posted February 7 Solution Share Posted February 7 Hi @AmanVerma welcome to the forum! You can indeed use an array, but then you still need to tell it which item you want to use from the array. I've converted your x property to xPercent, seen that you want to use % values, and created a function from it from which we receive the current index of the element you want to animate. Then somewhere else we create an array with the values we want to use and then add that value when tweening your elements. Hope it helps and happy tweening! See the Pen dyrjQGr?editors=1010 by mvaneijgen (@mvaneijgen) on CodePen 2 Link to comment Share on other sites More sharing options...
AmanVerma Posted February 7 Author Share Posted February 7 Thanks for the answer! It works! I didn't know, one could use a callback. That makes me wonder, suppose I wanted to animate, just the second element in the array. Consider the .child2 to have an opacity of 0 initially, and we want to animate it to 1. One approach I can see is that we create an opacity array for that purpose, but wouldn't creating an opacity array for every element, make this function run redundantly for the other targets, that don't even need an opacity. Because I read somewhere in the docs that animation runs for every element in the target array. Is there a better solution to target just one element. Also, where can I read more about callbacks in gsap? Thanks! Here is my solution: let array = [-100, 100]; let opacityArr = [1, 1] gsap.to( [".child1",".child2" ], { yPercent: (index) => array[index], opacity: (index) => opacityArr[index], scrollTrigger: { markers: true, start: "top 1%", end: "bottom 1%", trigger: ".test", pin: true, scrub: 0.8, ease: "power2.inOut" } }) Link to comment Share on other sites More sharing options...
mvaneijgen Posted February 7 Share Posted February 7 I'm not sure what you're calling a 'callback' we have eventCallbacks in the docs, but that is more when a tween has finished or it starting onComplete, onStart https://gsap.com/docs/v3/GSAP/Tween/eventCallback()/ In my above pen I've used Function-based values which you can read more about here https://gsap.com/docs/v3/GSAP/gsap.to()/#function-based-values. If you're new to GSAP check out this awesome getting started guide https://gsap.com/resources/get-started/ explains a lot in a nice overview, but the docs is also a great resource in general. Personally I almost never use single gsap tweens, but I always gravitate to using a timeline. It is great in a pinch, but with a timeline you get so much more control, see below pen where a timeline has all these animations on it and ScrollTrigger controls that timeline on scrolling, some tweens start at the same time as other twens using the position parameter and other tweens wait for their turn, this al gets explained in the getting started guide, so be sure to check it out. If you need any further assistance, please show us what you've already tried and provide a minimal demo, so that we can dive directly in the code. Hope it helps and happy tweening! See the Pen LYaBqrm?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen 2 Link to comment Share on other sites More sharing options...
AmanVerma Posted February 8 Author Share Posted February 8 I was trying to refer to the function-based values, and used the word callback instead. I apologize for the confusion. Thank you for pointing me to the right resources! Link to comment Share on other sites More sharing options...
mvaneijgen Posted February 8 Share Posted February 8 No worries, glad it helped. Happy tweening! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now