Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
dotsinspace

Unexpected Bump on Scroll

Go to solution Solved by GreenSock,

Recommended Posts

Code to this Problem.

/*
 * IMPORTS
 */
import React from 'react' // Npm: react.js library.
import Head from 'next/head' // Npm: next.js header utility.


/*
 * PACKAGES
 */
import Navbar from '~packages/common/components/NavBar'
import Banner from '~packages/common/components/Banner'
import TechnologyBanner from '~packages/common/components/TechnologyBanner'
import Client from '~packages/common/components/Clients'
import WebDevelopment from '~packages/common/components/WebDevelopment'
import Footer from '~packages/common/components/Footer'
import LanguageOption from '~packages/common/components/LanguageOption'
import JoinMsTeamsOrGmail from '~packages/common/components/JoinMsTeamsOrGmail'
import Particle from '~packages/reusecore/src/elements/Particle'
import AppDevelopment from '~packages/common/components/AppDevelopment'
import ContactForm from '~packages/common/components/ContactForm'
import DevOpsDevelopment from '~packages/common/components/DevOpsDevelopment'
import ServerDevelopment from '~packages/common/components/ServerDevelopment'


/*
 * OBJECTS
 */
const Index = ({ scrollContainerStyle, scrollPageStyle }) => {
  // Hook assignment.
  const [scrollContainerClasses, setScrollContainerClasses] = React.useState('background dark')
  const [languageOptionClasses, setLanguageOptionClasses] = React.useState('font light')
  const [activePage, setActivePage] = React.useState('Home')

  // Object assignment.
  const { gsap } = require('gsap')
  const { ScrollTrigger } = require('gsap/ScrollTrigger')
  const { ScrollToPlugin } = require('gsap/ScrollToPlugin')

  // Event listener.
  React.useEffect(() => {
    // Local variable.
    let _maxWidth

    // Variable assignment.
    _maxWidth = 0

    // Register gsap plugins.
    gsap.registerPlugin(ScrollTrigger)
    gsap.registerPlugin(ScrollToPlugin)

    // Const assignment.
    const _scrollContainer = '#ScrollContainer'
    const _scrollContainerPage = gsap.utils.toArray('#ScrollContainerPage')

    // Get maximum width to scroll
    const getMaxWidth = () => { _maxWidth = 0 ;_scrollContainerPage.forEach(section => _maxWidth += section.offsetWidth) }

    /*
     * Calculate maxWidth and update maxWidth
     * variable for further calculation.
     */
    getMaxWidth()

    // Event listener.
    ScrollTrigger.addEventListener('refreshInit', getMaxWidth)

    // Animate to given section.
    gsap.to(_scrollContainerPage, {
      'xPercent': -100 * (_scrollContainerPage.length - 1),
      'ease': 'power3.inOut',
      'scrollTrigger': {
        'trigger': _scrollContainer,
        'pin': true,
        'scrub': 1,
        'start': 'top top',
        'end': () => `+=${_maxWidth}`,
        'invalidateOnRefresh': true,
        'anticipatePin': 1,
        'onUpdate': v => {
          // Update states of fonts and backgrounds
          0.33 <= v.progress ? setScrollContainerClasses('background light') : setScrollContainerClasses('background dark')
          0.33 <= v.progress ? setLanguageOptionClasses('font dark') : setLanguageOptionClasses('font light')

          // Update active route.
          setActivePage(0.66 <= v.progress ? 'Technology' : 0.33 <= v.progress ? 'Clients' : 'Home')
        }
      }
    })
  }, [ScrollToPlugin, ScrollTrigger, gsap])

  // Return component.
  return (
    // Return component.
    <>
      <Head>
        <title>App | A react next landing page</title>
        <meta name='Description' content='Home | Rootandleaves Webservices'/>
      </Head>
      <main id='ScrollContainer' className={scrollContainerClasses}>
        <Particle/>
        <section style={scrollContainerStyle}>
          <LanguageOption className={languageOptionClasses}/>
          <section style={scrollPageStyle} id='ScrollContainerPage'>
            <Banner children={(<Navbar activePage={activePage}/>)}/>
          </section>
          <section style={scrollPageStyle} id='ScrollContainerPage' className='font dark'>
            <Client children={(<Navbar activePage={activePage} darkTheme/>)}/>
          </section>
          <section style={scrollPageStyle} id='ScrollContainerPage' className='font dark'>
            <TechnologyBanner children={(<Navbar activePage={activePage} darkTheme/>)} scrollById={'Technology'} onClick={v => v}/>
            <WebDevelopment />
            <AppDevelopment />
            <DevOpsDevelopment />
            <ServerDevelopment />
            <JoinMsTeamsOrGmail />
            <ContactForm />
          </section>
        </section>
        <Footer />
      </main>
    </>
  )
}


/*
 * PROPTYPES
 */
Index.defaultProps = {
  'scrollContainerStyle': {
    'display': 'flex'
  },
  'scrollPageStyle': {
    'minWidth': '100%',
    'minHeight': '100vh'
  }
}


/*
 * EXPORTS
 */
export default Index

 

Link to comment
Share on other sites

Hey dotsinspace - could you put together a minimal demo for us please?

No need to include all the assets and styles - a simplified example is best to show off the issue.

Also we recommend using useLayoutEffect instead of useEffect when using scrollTrigger as the DOM will be fully rendered and GSAP's positioning calculations will be correct.

We have some React guides here that may be of help.
 

 

  • Like 1
Link to comment
Share on other sites

@Cassie i tried to write it out on codepen but codpen version was running with no issue. so i got confused what wrong i am doing. thats why skipped to put codpen code over here. :(

Link to comment
Share on other sites

1 hour ago, dotsinspace said:

i tried to write it out on codepen but codpen version was running with no issue.

 

It's nearly impossible to look at GSAP code and infer what is going because it's working with HTML, CSS, and other code that is running like React.

 

If it works on CodePen, then that means the code is good and you have a problem with your setup. You need to try to isolate what is causing the problem.

 

Link to comment
Share on other sites

Highly Appreciate your time guys thank you and sorry for wasting your time. :ph34r:

Link to comment
Share on other sites

And Please admin delete this Post as this post will not going to help anyone and my code is open too. Thanks again

Link to comment
Share on other sites

@OSUblake i found out cause of this bump. Please do checkout this video :)

https://www.awesomescreenshot.com/video/4922136?key=46e6a765fe4512046aec941e19272ac0

 

Bump occurs when transform property marked in red changes. even i have created codepen it is working fine

you can check it out 

See the Pen gOWVdqe by dotsinspace (@dotsinspace) on CodePen

. but again things are working fine on codepen but on by next.js project this bump is occuring all the time even though i dont have animation or easing related to this.

 

if you want see live running project than please do checkout my portfolio website www.rootandleaves.com.

 

Just want to get ride this of issue i have already wasted lot of time on this.

Link to comment
Share on other sites

The pinning changes the transform, but maybe you have something other component that is messing is up, or maybe a re-render. And with pinning in React, it's a good idea to useLayoutEffect and have a wrapper element for the component instead of a fragment. But I don't know if that will fix the issue.

 

fragment
<>
  <main></main>
</>

wrapped
<div>
  <main></main>
</div>

 

Also, you don't have to use strings for property names. JavaScript infers properties as strings. You also won't get auto-complete with strings.

gsap.to(_scrollContainerPage, {
      xPercent: -100 * (_scrollContainerPage.length - 1),
      ease: 'power3.inOut',
      scrollTrigger: {
        trigger: _scrollContainer,
        pin: true,
        scrub: 1,
        start: 'top top',
        end: () => `+=${_maxWidth}`,
        invalidateOnRefresh: true,
        anticipatePin: 1
      }
    })

 

  • Like 2
Link to comment
Share on other sites

@OSUblake i just found out why it was causing that weird bump. please do checkout my codepen. just updated it and it too behaving weird. i am new to gsap. but i have question. why applying transition prop in CSS causes that bump ? is it intended or its that CSS gives transition priority over gsap.

See the Pen gOWVdqe by dotsinspace (@dotsinspace) on CodePen

Link to comment
Share on other sites

Oh yes, you should never use all on any element you animate with GSAP. You need to be specific about which properties you want to transition. CSS and GSAP will both be fighting over the animation and it will mess things up.

  • Haha 1
Link to comment
Share on other sites

Yes, just to be clear - when you have a CSS transition applied, it basically interferes with property setting and drags it out over whatever duration you set on your CSS transition. 

 

Think of GSAP like a high-performance property setter; when you animate, GSAP interpolates between the start and end values and then it directly sets that property 60 times(-ish) per second accordingly. If you have a CSS transition on that element/property, it completely messes that up. Let's say GSAP sets element.style.transform = "translateX(100px)"...well the CSS transition won't allow that to happen yet! It'll say "nah, we'll have the browser gradually get there instead". So not only does it not look correct, but it's also terrible for performance because you've got GSAP and CSS fighting over the same property at the same time. No bueno. 

 

The moral of the story: never...ever use CSS transitions on the same properties you're animating with GSAP. It's typically much better to just use GSAP. I can give you a bunch of reasons if you need that. :)

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

@OSUblake i am trying to use scrollToPlugin but its not working. Could You Please help me. please do checkout same codepen.

Link to comment
Share on other sites

TypeError: Failed to execute 'scrollTo' on 'Window': cannot convert to dictionary. this is error i am getting

Link to comment
Share on other sites

Looks like you may be trying to use jQuery? If so, you'd need to load it and write it like this.

const _el = $('#Navigate')

_el.click(function() {
  gsap.to(window, {
    'scrollTo': {
      x:100
    }
  })
});

Or you could use onclick like this

const _el = window.document.getElementById("Navigate");

_el.onclick = function () {
  gsap.to(window, {
    scrollTo: {
      x: 100
    }
  });
};

Or you could add an event listener like this

const _el = document.querySelector("#Navigate");

_el.addEventListener("click", () => {
  gsap.to(window, {
    scrollTo: {
      x: 100
    }
  });
});

You may also need to preventDefault(). Hopefully that helps. Happy tweening.

:)

 

  • Like 1
Link to comment
Share on other sites

Agreed what you are saying but on my React Next app even following code doesnt work

gsap.to(window, { scrollTo: '#IDofGivenPage' })

Even i tried all cases in react next but scrollTo Plugin just doesnt work

Link to comment
Share on other sites

@Cassie cant we target #ScrollContainer in codepen example ? or do we have to use window for scroll target. and second thing following works

 

  gsap.to(window, {
    'scrollTo': {
      x:800
    }
  })

but if try to target element with class or id than it doesnt work either.

  gsap.to(window, {
    'scrollTo': '.page2'
  })

 

Link to comment
Share on other sites

12 hours ago, dotsinspace said:

but if try to target element with class or id than it doesnt work either.

That's because the default direction is "y". 

 

// BAD
gsap.to(window, {
  scrollTo: ".page2" // will scroll on the y-axis
});

// GOOD:
gsap.to(window, {
  scrollTo: {
    x: ".page2"
  }
})

 

  • Thanks 1
Link to comment
Share on other sites

i tried all cases but there are no logs nothing which can state problem. it just doesnt work. ScrollTrigger is working fine but ScrollToPlugin just doesnt work.

 

gsap.to(window, {
  scrollTo: {
    x: ".page2"
  }
})

 

Link to comment
Share on other sites

Again - it works here.

See the Pen XWgrvqw?editors=0010 by GreenSock (@GreenSock) on CodePen



This is the purpose of a minimal demo - we can't help unless you show us your setup I'm afraid. 

 

Maybe this template we put together will help set you in the right direction - https://codesandbox.io/s/gsap-nextjs-starter-jekrn
 

19 hours ago, Cassie said:

You're probably trying to access a DOM node that isn't rendered yet - or you haven't loaded the plugin

 

Link to comment
Share on other sites

As Craig pointed out too - in your pen you were using .click, which isn't a valid event listener in a vanilla JS / react context.

 

_el.click(function() {
  gsap.to(window, {
    'scrollTo': {
      x:100
    }
  })
});

 

Link to comment
Share on other sites

If you put a console.log() in that onClick - nothing is happening. scrollTo can't do anything if the event's not firing.

Maybe this article can help - 


 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×