jlmakes / scrollreveal

Animate elements as they scroll into view.
https://scrollrevealjs.org/
22.35k stars 2.26k forks source link

Only animate off-screen elements as they are scrolled into view #354

Closed jamesncampbell closed 7 years ago

jamesncampbell commented 7 years ago

OS: Mac OS Sierra ScrollReview version: 3.3.5 Browser: Chrome Version 58.0.3029.110

I'd like to fade-in content as a user scrolls down the page. It works but, the animation also occurs on elements that are visible when the page is loaded. Is there anyway to prevent elements loaded into the viewport from animating and only having the off-page content animate as it is scrolled into view?

Here's the config I'm using, which is declared in the componentDidMount function of a React component:

  componentDidMount() {
    const config = {
      duration: 1000,
      delay: 150,
      scale: 1,
      easing: 'ease',
      container: document.querySelector('.app__body')
    }

    ScrollReveal.reveal('div', config);
  }

Thanks for any help on this!

jlmakes commented 7 years ago

I remember something like this being asked before, and I believe the solution we came up with was to use two different reveals pretty much back to back.

Example (using ES2015+):

const sr = ScrollReveal()

const config = {
    delay: 150,
    duration: 1000,
    easing: 'ease',
    scale: 1,
}

const items = document.querySelectorAll('.items')

/**
 * Reveal all `.items` with a modified config
 * object that has no delay or duration.
 */
sr.reveal(items, Object.assign({}, config, {
    duration: 0,
    delay: 0
}))

/**
 * Now loop through all `.items` and check the
 * visibility using the ScrollReveal store data.
 */
const unseenItems = Array.from(items).filter(item => {
    const id = item.getAttribute('data-sr-id')
    return sr.store.elements[id].seen === false
})

/**
 * Now reveal the unseen `.items`
 * with the normal config.
 */
sr.reveal(unseenItems, config)

I haven’t tested this code, but let me know if my ideas were unclear. Hopefully this inspires you.