Jump to content
Search Community

Sacha

Members
  • Posts

    17
  • Joined

  • Last visited

Everything posted by Sacha

  1. Thank you a lot! Solved my problem
  2. Hey, I'm having problems killing / deactivating a scrolltrigger after it got activated. My goal is to play a html video at a specific point with the scrolltrigger. After the video got started once, the scrolltrigger should be removed. I tried finding something in the docs but could only find the ScrollTrigger.kill() function, which kills all ScrollTriggers or how to kill a timeline. Is it possible to only kill certain triggers, for example using an ID or something similar without using a whole timeline? const video = document.querySelector("video"); ScrollTrigger.create({ trigger: video, start: "bottom bottom", markers: true, id: i, onToggle: () => video.play() + ScrollTrigger.kill(), toggleActions: 'play none none none', });
  3. Hello, I'm using the snap from scrollTrigger together with scrollTo on my website. Works great on desktop, but I noticed that both don't play along so well on mobile. I've set up the ScrollTo so it scrolls to the top of the page if you click on the logo and you are already on the homepage. Works well, but if you are below the section that uses snap, ScrollTo will not work right and wont scroll to the top like it does normally. It stops at some point or looks really buggy and not smooth. Here's the website where you can test it on mobile (tested in Safari and Firefox, both having the same bug. But only on mobile devices. Works normal in previews on desktop). Edit: will write a codePen
  4. Is it neither possible if the timeline is used in a scrollTrigger? Because here the duration doesn't really declare a time in seconds, but more a fraction of the timeline, which itself keeps its total duration. So changing the duration wouldn't affect the whole timeline's constant duration. (Just speculative thoughts about the timeline inside a scrollTrigger, I have no idea how it actually works, but I hope you understand my way of thinking.) tl1.current .to(ref.current, { scaleY: 3, duration: values[0], }, 'start1') .to(ref2.current, { scaleY: 1, duration: values[1], }, 'start1') Are these two individual tweens inside a timeline? Or what do you mean by that?
  5. Thank you, I now understood your function. Sorry for the misunderstanding. Is there a way to update the duration on a timeline in a similar way? Here would be an example. The snap values from myFunction are the two calculated vertical centers of different sized sections inside an element. So the element is the parent, with two child sections, each with a different height. The first value from myFunction is the center of the first section, the second one the center of the second (based on the total height of the parent element) . Here I need to achieve the same thing. So if scrollTrigger refreshes (which changes the snapTo values), the duration (which is based on the snap values) should also be updated. Is this possible? let snapValues = myFunction(); // returns [0.2, 0.7] as example let durationFirstHalf = snapValues[0]; // returns 0.2 let durationSecondHalf = snapValues[1] - 2 * snapValues[0]; // returns 0.3 // so the first section would have a total relative height of 0.4, the second one 0.6. .to(firstTarget.current, { scaleY: 2, duration: durationFirstHalf, }, 'start1') // first animation goes from 0 to 0.2 .to(firstTarget.current, { scaleY: 1, duration: durationFirstHalf, }, 'end1') // first animation goes from 0.2 to 0.4 .to(secondTarget.current, { scaleY: 2, duration: durationSecondHalf, }, 'start2') // second animation goes from 0.4 to 0.7 .to(secondTarget.current, { scaleY: 1, duration: durationSecondHalf, }, 'end2') // second animation goes from 0.7 to 1
  6. Sorry, again my fault for not writing working examples. I just used[1,2,3,4] as example, but my actual array are numbers between 0 and 1, so for example [0.25, 0.75]
  7. function myFunction() { let heights = [10, 6]; let totalHeight = heights[0] + heights[1]; let snapValues = []; let prev = 0; snapValues = heights.map((height, i) => { let current = (prev + height / 2) / totalHeight; prev += height; return current; }); return snapValues; } Hmm okay, I'm not sure if you didn't understand what I meant or I don't what you mean. Here's my example for the myFunction function. This would return an array of [5, 13], so I'd assume that this is what happens. Correct me if I'm wrong. snapTo: myFunction() // would be snapTo: [5, 13] I don't understand you code suggestion snap: (value) => snapper(value) Shouldn't snapper be a function here? But no matter the code, I'm still having trouble using an arrow function inside snap No matter if I do something simple like using an actual array for the snap value, it still jumps back to the top of the page as soon as I enter the scrollTrigger element.. let someArray = [1,2,3,4] snap: () => someArray
  8. Thank you for your quick replies and help! I used the snapTo inside the snap object, but wrote it wrong here because I deleted some unnecessary code and missed that. Setting invalidateOnRefresh to true inside the scrolltrigger didn't help. My start arrow function updates automatically every time the scrolltrigger refreshes, but doing the same for snapTo wont work. @GreenSock myFunction returns an array. So setting snapTo: myFunction() works like it should (like @Cassie demonstrated in the sandbox), but I can't find a way to make it refresh its array when the scrollTrigger refreshes (Taking Cassie's example; change the random snap value every time the scrollTrigger refreshes).
  9. Hey, I'm looking for an easy way to update variables used in a tween. Take this example, where the duration is a variable that has to update when the window is resized. To avoid creating a new resize eventlistener, I'm looking for a way to update this variable using the integrated listener from GSAP. let time = myFunction(); timeline.current.to(myRef.current, { scaleY: 2, duration: time[0], }, 0) In this example, using variables and functions inside a scrollTrigger, it will automatically update them, when the scrollTrigger gets refreshed (which happens on window resizes if I understand it correctly.) Here I have another question; which way it the right one? Using a arrow function like in the start property, or a normal function call like on the snapTo property (the start property works great, but using a normal function call inside the snapTo only fires once. Using an arrow function here doesn't seem to work, it breaks the snapTo and always scrolls to the top of the page when triggered.)? tl1.current = gsap.timeline({ scrollTrigger: { trigger: myRef.current, start: () => "0% 50%+=" + (myRef.current !== null ? myRef.current.clientHeight : 100), end: "100% 50%", snapTo: myFunction(), } }) Since I'm working with React, is there a way to say for example useEffect(() => { console.log("update"); }, [timeline.current.scrollTrigger]) which would call everytime the scrollTrigger of timeline updates / refreshes?
  10. Thank you, I will try that which should work. Btw I created a demo when I wrote my first question. Here's the link again. https://codesandbox.io/s/reverent-star-il30g EDIT .play(0) works great, thank you. Sorry for this silly question, should have known this was the issue..
  11. Hey again, I'm working on my animated mobile navigation. Before this, I used one timeline, and did .reverse() when it closes, but I want to change the closing animation. So I create a second timeline. So for the code I use something like this: const [open, setOpen] = setState(false); const timeline1 = useRef(); const timeline2 = useRef(); useEffect(() => { if (open) { timeline1.play(); } else { timeline2.play(); } }, [open]} <button onClick={() => setOpen(!open)}> This works fine when opening and closing the navigation once, but after that, the style wont change. It's like the timeline would have applied the "once: true" attribute. I tried recreating it in a sandbox, but there I'm having even more problems. I can't even make it work once, and I don't know why...
  12. Thank you for taking the time to help me out and writing this great example! Helped a lot, thanks!
  13. Hey, I'm trying to create two sections with scrolltrigger events and a snapTo, which snaps to the center of each section. Because it shouldn't be two single events, but the events should seamlessly transition from one to the other, I need to put both sections in one, and target this with a single scrolltrigger. My idea was, that I use snapTo: [0.25, 0.75], so it would snap to the center of each section. This logic would work if both sections would be of the same height, but as soon as they have different heights, this doesn't indicate their true center. If there a way to use scrollTrigger and calculate both centers, based on their heights, and using it in the wrapper scrollTrigger? Or do I have to find another way, calculating the centers of each section with normal JS code?
  14. In React you can do cleanup functions after the useEffect. So like I did in the sandbox. If you look at the console, you see that the console logs are being fired, but the tweens are not being killed. useEffect(() => { //code //cleanup return () => { console.log(gsapNav); gsap.utils.toArray(sectionRef.current).forEach((section, i) => { gsapNav[i].kill(); console.log("kill " + i); }); console.log(gsapNav); }; }, []); And the bug did actually replicate just like on my page. If you don't scroll to the first scrolltrigger and click on the link, the scrolltrigger doesn't appear on the second page. But if you scroll to the blue section and trigger the scrolltrigger and click on the link, the markers are still visible on the second page and it creates blank scrollable content.
  15. I tried my best recreating it in a sandbox. Here also I'm not able to kill the scroll trigger and it's still active on the second page. I can't recreate the bug with the multiple scrollbars, but I guess it will be fixed together with the other problem. https://codesandbox.io/s/react-router-link-example-forked-11glv
  16. Hey Cassie, first thank you for the additional links! The article states we should use refs to define timelines, so they wont get rerendered every time. That's something I didn't do yet, maybe it fixes my problem. Is this only the case for animations / timelines that are used on multiple pages or also for a scrollTrigger animation that I only run on my index page? EDIT I used this approach for my problematic code, and it didn't resolve it. Now it's back to working when no scrolltrigger was activated, and breaking when some trigger was activated.. I will try to reproduce it in a sandbox.
  17. Hello, first thank you for this amazing and powerful toolset! You're doing an amazing job and helping a lot of people. I'm using GSAP scrolltrigger on my React Gatsby page. One of the uses is setting the background color of my navigation bar to a different color, when scrolled past specific sections. This all works great. Because of the rooting system of a react app, the triggers and timelines don't get killed automatically when a page is changed. So I have to kill them manually. Yesterday it worked if the scrolltrigger wasn't active. So if I changed pages without activating a scrollTrigger, they would get killed, otherwise if they were active, the wouldn't. Now it somehow doesn't kill anything anymore at all. Also I'm having a really weird bug when setting markers to "true". When "false", everything is fine, but on "true", the site is buggy and creates markers on the bottom of the page and adds a second scrollbar and everything. Really weird behaviour. But that shouldn't be the focus of this post. I tried setting up a codepen, but couldn't figure out how to import React.. Maybe someone can give me a quick tip to set one up, so I could try to replicate the behaviour there. Here's the code I'm using if that helps. useEffect(() => { gsap.set(navRef.current, { backgroundColor: "rgb(255, 255 255)", }); let gsapNav = []; // nav background color adapt to section color gsap.utils.toArray(sectionRef.current).forEach((section, i) => { let bgcolor = section.current.dataset.bgcolor; gsapNav[i] = gsap.to(navRef.current, { scrollTrigger: { markers: false, trigger: section.current, start: "top 102px", end: "bottom 102px", toggleActions: "play reverse play reverse", }, backgroundColor: `rgb(${bgcolor})`, duration: 0.3, }) }); // cleanup function when page is changed return () => { // prints both scrolltriggers console.log(gsapNav); gsap.utils.toArray(sectionRef.current).forEach((section, i) => { gsapNav[i].kill(); console.log("kill " + i) }) // still prints both scrolltriggers / tweens console.log(gsapNav); } }, []); And here the JSX () return ( <section> <div>Some content</div> </section> <section ref={sectionRef.current[0]} data-bgcolor="239, 244, 248"> <div>Some content and color change</div> </section> <section> <div>Some content</div> </section> <section ref={sectionRef.current[1]} data-bgcolor="239, 244, 248"> <div>Some content and color change</div> </section> )
×
×
  • Create New...