Jump to content
Search Community

Romann

Members
  • Posts

    17
  • Joined

  • Last visited

Posts posted by Romann

  1. I think, i am looking for a way how to disable ScrollSmoother raf, and animate it in my custom function, the problem i have is synchronization of the dom elements animation with my canvas 3d elements, basically i need to combine request animatioin frame so dom elements and 3d elements are animated in one spot.  Nothing wrong with ScrollSmoother, it is perfect. 

  2. is it possible to control SmoothScroller request animation frame (updates) externally ? I have react app and i need to sychnronyze better SmoothScroller with other animations i have going, and i would like to do smoothscroller animation/position calculation togetehr with my other animation. 

  3. 24 minutes ago, GreenSock said:

    There are so many confusing things about your setup, I'm not really sure what to say. There are multiple scrollbars, you're reporting negative scrollTop values (those should pretty much always be positive), you're animating a generic object and an element in the same way in your forEach(), you're also trying to involve separate pinning logic...I don't quite know where to start, what exactly you're trying to do, or how to really help you here. 

     

    Jack, thank you for your time working on such a thoughtful  reply, I really appreciate it, i don't want to waste your time anymore,  but i have to ask last question, why you think animating a generic object is not an award winning idea ? The reason I am animating generic object "valuetopass" so i can pass the same Y value to the scrollproxy getter and setter.  You think cleaner way to achieve the same effect exist, without animatic a generic object ? 

  4. 19 hours ago, GreenSock said:

    I noticed quite a few things:

    1. You had an invalid start value of "top " - it should be a space-delimited value with two values, like "top top" - see the docs for details.
    2. It seemed like a very odd setup because you're setting the trigger to the body itself...and you're also using the default scroller which is the viewport (typically the body). So when you set it up with top: "top top", end: "bottom bottom", you're basically saying "start when the top of the body reaches the top of the body" and "end when the bottom of the body reaches the bottom of the body" - sorta perplexing. See what I mean? Maybe you meant end: "bottom top"
    3. Then later, after you've already created some ScrollTriggers, you set the default scroller to be the container (ScrollTrigger.defaults({ scroller: container });). Did you intend to run that first? 
    4. You're using a scrollerProxy() that attempts to tap into a valuetopass object ({}), but you forgot to set an initial y value, thus the getter would return undefined.
    5. I have no idea what you're trying to do with that final ScrollTrigger that has pinReparent: true

    I think it'd be much better if you could just slowly build something up from the most basic stuff rather than trying to do so many thing that seem to be causing misunderstandings. For example, maybe just try to get one thing to pin or trigger at the spot you want. THEN, once that works, move onto something that does the pinReparent (which is almost never needed) and then finally the smooth scrolling. I just feel like there are so many things that are jumbled in your demo that they're obfuscating each other and muddying the waters. I don't mean that in an insulting way at all - I'm simply trying to offer some advice to get to a solution in the fastest, most efficient way possible. 

     

    Thank you for the advice, i really appreciate it, I believe i fixed issues you pointed out, I originally used my own simple smooth scroll but i thought it is more confusing for you to look at the code because it is something not GSAP related so that's why i switched to fully native scroll-trigger smooth scroll and now i have two scroll triggers and i am confused even more.

     

    1. Did i correctly setup scrollrpoxy and scrolltrigger smooth scrolling ?

    2. How can i make my second scroll trigger pin work ? 

     

     

    let container = document.querySelector("#scroll-container");
    
    // ScrollTrigger.defaults({ scroller: container });
    
    ScrollTrigger.scrollerProxy(container, {
      
        scrollTop(value) {
          if (arguments.length) {
            valuetopass.y = value; // setter
          }
          return  valuetopass.y;    // getter
        },
        getBoundingClientRect() {
          return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight};
      }
    
    })
    let valuetopass = {y:0}
    
    let arr = []
    let height = container.scrollHeight;
    document.body.style.height = height + "px";
    
    arr.push(container,valuetopass)
    
    arr.forEach(box =>{ 
    
    gsap.to(box, {
        y: -(height - window.innerHeight),
        scrollTrigger: {
          // scroller:container,
          trigger: document.body, // if i use anything else here it does not work
          start: "top top",
          end: "bottom top",
          scrub: 1,
          // markers:true,
        }
      });
    
    })
    
      ScrollTrigger.create({
        scroller: container,
        trigger: ".pin-on",
        start: "top center",
        end:"bottom bottom",
        pin: true,
        // pinType: "fixed",
        scrub:1,
        // pinReparent: true,
        markers:true,
        // pinSpacing:false,
        // anticipatePin: 1
      })

     

    Updated codepen:

     

    See the Pen YzpJzxB by ivashnev (@ivashnev) on CodePen

     

  5. Thank you Jack,

     

    actually in my example i am not moving body tag, i have exactly what you described typical smooth scroll approach and still markers are not positioned absolutely to the screen but moving together with the content.

     

    In addition i. did another example and i used exclusively GSAP and scrolltrigger to make smoothscrolling effect, so no 3rd party plugins used and i still have the same issue: scroll start markers scrolling with content and overall not able to control when pinning exactly starts.

     

    I would greatly appreciate is someone can take a look and tell me why i don't have good control of when pin starts/stops

     

    here is 100% gsap/scrolltrigger example with not properly working pin:

     

    See the Pen YzpJzxB by ivashnev (@ivashnev) on CodePen

     

     

  6. 2 hours ago, GreenSock said:

    Did you set your ScrollTrigger's "scroller" to the thing you're using for the proxy (scroll.DOM.scrollable)? Remember, the whole point of scrollerProxy() is to tell ScrollTrigger to use your proxy in the place of a particular DOM element when it's trying to determine its scroll position. So if, for example, your ScrollTrigger is using the default scroller (the main viewport), but you set up a scrollerProxy() for some other element, it won't have any effect. 

     

    Jack, thank you this helped i can see it is working now and pinning mechanics fully synced with interpolated value, one problem i have now i lost ability to control start and end trigger, specifically by some reason scroller-start and scroller end markers are now part of the scrollable element so they scroll with the page instead of positioned to the screen size. what could be the problem ? 

     

    See the Pen PobBaOL by ivashnev (@ivashnev) on CodePen

     

     

     

  7. 14 hours ago, GreenSock said:

    Ah, I didn't have time to read through your whole post originally and now I see that it's definitely caused by your scroll-jacking smooth-scrolling stuff. I didn't realize you were scroll-jacking, sorry. 

     

    Basically, the page's scroll position is updated immediately (and that's what ScrollTrigger uses for its calculations), but the content on the page itself is being slowed down by your scroll-jacking, thus the pinning occurs before your content "catches up". 

     

    Unfortunately, we just don't have the resources to troubleshoot custom scroll-jacking code that you've written but I'm confident that you could get it working with ScrollTrigger by using the scrollerProxy() method. Let us know if you have any GSAP-specific questions we can answer for you. 

     

    Thank you for the advice,

     

    I am trying to implement scrollerProxy functionality but unfortunately i dont see any effect, this is what i did:

     

      scroll = new Scroll();
    
    // scroller proxy setup
    // scrollable element "scroll.DOM.scrollable",
    // interpolated position value scrollTop -  "scroll.renderedStyles.translationY.previous"
    
    ScrollTrigger.scrollerProxy(scroll.DOM.scrollable, {
      
          scrollTop(value) {
            if (arguments.length) {
                scroll.renderedStyles.translationY.previous = value; // setter
            }
            return  scroll.renderedStyles.translationY.previous;    // getter
          }
    
      })

    I did check examples provided on the scrollerProxy() page but all 3 examples are working with a libraries and there is no very basic example available. 

     

    My question is: What parameters from my simple smooth scroll i need to provide to scrollerProxy in order to connect this two ? 

    My understanding is the only parameter needed  - is interpolated value of scrollTop.

     

     

     

  8. 2 hours ago, GreenSock said:

    If I understand your question correctly, it's because you've got anticipatePin set to 1. Just remove that. The entire point of anticipatePin is to do what you're seeing - it watches the speed that you're scrolling and tries to anticipate when it should pin, and do it early because most modern browsers handle scrolling on a different thread, so if you scroll quickly and there's a lot of work the browser has to do when pinning, you might see it scroll slightly past where it was supposed to for a fraction of a second before pinning. This has nothing to do with GSAP or bugs in ScrollTrigger - it's just a logic issue with how browsers handle scrolling and repainting. 

     

    So remove anticipatePin altogether and see if that resolves things for you :)

     

     

    Thanks Jack,

     

    Unfortunately this did not help, here is live demo on codepen:

     

    See the Pen PobBaOL by ivashnev (@ivashnev) on CodePen

     

     

     

  9.  

     

     

    by some reason my element pins fine if i scroll slow, but if i scroll really fast pin start in a very offset position. What could be the issue ? 

    For the smooth scrolling i am using simple LERP value i apply with transform:translate on my wrapper  Also "document.documentElement.scrollTop" is available at any point in chrome console, so i don't think i am doing any scroll jacking according to scrolltrigger documentation. I did read about scrollerProxy() but i cant figure out how to connect it with my own scroll smoothing javascript and do i have to if everything else works exempt inconsistent pin start depends on how fast i scroll ?

     

    This are some pieces of my smooth scroll (no library used)

     

    let docScroll;
    const getPageYScroll = () => (docScroll = window.pageYOffset || document.documentElement.scrollTop);
    window.addEventListener("scroll", getPageYScroll);

     

          this.renderedStyles = {
            translationY: {
              // interpolated value
              previous: 0,
              // current value
              current: 0,
              // amount to interpolate
              ease: 0.15,
    
              // current value setter
              // in this case the value of the translation will be the same like the document scroll
              setValue: () => docScroll
            }
          };

     

      // sets the initial value (no interpolation) - translate the scroll value
          for (const key in this.renderedStyles) {
            this.renderedStyles[key].current = this.renderedStyles[
              key
            ].previous = this.renderedStyles[key].setValue();
          }

     

            this.DOM.scrollable.style.transform = `translate3d(0,${-1 *this.renderedStyles.translationY.previous}px,0)`;

     

     

    This is my scrolltrigger pin:

     

    I have to use pinReparent since my smoothscroll wraps everything in div layer that is transformed Y 

     

          let pin = ScrollTrigger.create({
            id: "Pinned", 
            trigger: ".pin-on",
            start: "50% 50%",
            end:"5000",
            pin: true,
            // scrub:1,
            pinReparent: true,
            markers:true,
            // pinSpacing:false,
            anticipatePin: 1
          })

     

    if this is not clear enough, let me know i will assemble simplified version of the issue

     

     

     

  10. 7 hours ago, ZachSaucier said:

    Hey Romann. 

    1. This is really just a JavaScript question. It's probably best to use .querySelector() or .querySelectorAll() on your box inside of the loop. I talk more about this in my article about animating efficiently.
    2. I don't really understand what you're saying works vs doesn't work here. Maybe if you made a minimal demo it'd help? Or at least were more clear with what code is different to make it work.

     

    Thank you so much, 1 - makes sense, works for me just wanted to confirm, for the second question:

     

    I am not able to kill scrolltrigger if use this code structure (asigning  scrolltrigger directly to the timeline)

    gsap.utils.toArray("#content section").forEach(box =>{
     
    var tr = gsap.timeline({
    scrollTrigger: {
    trigger: box,
    start: 'top bottom',
    end: 'top top',
    scrub:1,
    // markers: true,
    }
    });
     
    tr.fromTo(box, { y:250 },{y:0});
     
    triggers.push(tr)
     
    })

     

     

    If i am using ScrollTrigger.creat  - i am able to kill scroltrigger

     

    gsap.utils.toArray("#content section").forEach(box =>{
    let tr = ScrollTrigger.create({
    trigger: box,
     
    start: 'top bottom',
    end: 'top top',
    // markers:true,
    onEnter: () => navColorActivate(),
    onLeave: () => navColorDeactivate(),
    onEnterBack: () => navColorActivate(),
    onLeaveBack: () => navColorDeactivate(),
    })
    triggers.push(tr)
     
    })

     

     

     

    For both scenarios i am using this method:

     

    triggers.forEach(t =>t.kill());

     

     

     

     

     

     

     

     
  11. Hello smart people,  i have two questions gsap and scrolltrigger related:

     

    1.

     

    How can i efficiently select variety of html tags to animate for example i am using utils.toArray to select multiple section tags on my page and with forEach loop i get a variable with stored node of html select element i can use for my animation, what if i want to have multiple twins and reference elements with in"box" variable ? 

     

    tr.fromTo(box, { opacity: 0,y:-100 },{ opacity: 1,y:0 });
     

     

    for example i want to select another tag that is inside box variable is this is the only option ?  (this would select any first section child element, but unfirtunatelly i may have some variations in the components so for one component first child element can be ARTICLE and for another it may be P tag so the problem in this method is that it is not specific)

     

    tr.fromTo(box.children[0], { opacity: 0,y:-100 },{ opacity: 1,y:0 });
     

     

    I was hoping there is more flexible option like something like this: (it does not work)

     

    tr.fromTo(box+" .article", { opacity: 0,y:-100 },{ opacity: 1,y:0 });

     

    Unfortunately it does not work

     

    Question : What would be the most efficient way to select tags for animation when having multiple components on the page ? I want to have one scrolltrigger for the entire section but elements inside may be different section to section. How can i have one scroll trigger per component (section)  but select variety of child nodes to animate

     

     

    2.

     

    I have a single page app and i am running scrolltrigger only on one page, when i leave this page scrolltrigger should  be eleminated. 

     

    By some reason whatever i do does not kill scrolltrigger.

     

    But if i change the way i setup scrolltrigger to this:

     

     

    gsap.utils.toArray(".black").forEach(box =>{
    let tr = ScrollTrigger.create({
    trigger: box,
    start: "top top+=83px",
    end:'bottom-=83px top',
    // markers:true,
    onEnter: () => navColorActivate(),
    onLeave: () => navColorDeactivate(),
    onEnterBack: () => navColorActivate(),
    onLeaveBack: () => navColorDeactivate(),
    })
     
    triggers.push(tr)
     
    })

     

    It works perfectly. Why ? Why this code is eleminated and original code is not ? 

     

     

    here is my original code for both questions:

     

    1. let triggers = []
    2.  
    1. if (triggers.length) {
    2. triggers.forEach(t =>t.kill());
    3. triggers = []
    4. }
    5.  
    1. //this code executed only when i am visiting project page
    if (match.route.pageType ==="project") {
     
    1. gsap.utils.toArray("#content section").forEach(box =>{
    2.  
    3. console.log(box.children)
    4.  
    5. var tr = gsap.timeline({
    6. scrollTrigger: {
    7. id:"triggerC",
    8. trigger: box,
    9. start: 'top center',
    10. // markers: true,
    11. toggleActions: "play none none reverse"
    12. }
    13. });
    14.  
    15. tr.fromTo(box, { opacity: 0,y:-100 },{ opacity: 1,y:0 });
    16. triggers.push(tr)
    17.  
    18. })
    19. }
  12. 1 hour ago, GreenSock said:

    Glad to hear eventCallbacks() worked for you. FYI, this is just a JavaScript thing: 

    
    
    // invokes immediately uiUpdater() and the RESULT is fed to then(): 
    .then(this.uiUpdater(curui,this.projects));
    
    // wrap it in a function declaration to wait:
    .then(() => this.uiUpdater(curui,this.projects));

    But I'm not sure if you're mutating curui and this.projects between those calls; if so, you'd need to handle it a bit differently. Just ask if you need help with that. 

     

    Thank you for this solution, this one works even better because now i have access to "this" inside my callback function and with eventCallback "this" returned undefined. 

  13. Hi everyone, 

     

    Have a quick question,  I have a timeline, i am using this timeline multiple times in my project to animate text. In one instance i want to call a function at the end of timeline animation.  I am able to use then() like this:

     

    this.tl.timeScale(1).reverse(1).then(this.uiUpdater);

     

    It works, but i have to pass some parameters for my "this.uiUpdate" function, and if i do so like this: .then(this.uiUpdater(curui,this.projects) this function executes immediately without waiting for the timeline to complete. I was thinking about somehow eliminating the need for passing parameters but got another problem, i am loosing access to "this" inside my callback function (this.uiUpdater) so i am not able to access needed parameters.

     

    I know i can use onComplete constructor but the problem is if i apply it on the timeline it is going to execute every time i use this timeline, so i need somehow to execute it only when needed

     

    onComplete: this.uiUpdater,
    onCompleteParams:[curui,this.projects],

     

    What would be the best approach to this problem ? Any other solutions possible ? 

     

    Ideally  - .then() approach works great for me only if i can somehow pass needed parameters.

     

    Thank you ! and sorry no codepen example yet, project is kind of big,  if my question is unclear, i will go ahead and build simplified  version for codepen. 

  14. Hello good people of GSAP,

     

    I have a question on how to use the same timeline for multiple elements on the page, specifically i am looking for Vanilla Javascript solution, yep i saw examples on codepen, but they both are done with use of jQuery  and this is very confusing to me, i am still learning javascript and not familiar with jQuery. Also this codepen examples are using older TweenMax syntax and this is not helpful either.

     

    Can someone please give me an idea what i should change or add to my code so animation is happening only on the tile user click, right now it is happening for all tiles at once.  I know i can run forEach method for each of my tile, but i have problem understanding how can i fire event to very specific tile  user clicking.

     

    Thanks  !

     

    See the Pen xxOBMGN by ivashnev (@ivashnev) on CodePen

×
×
  • Create New...