🛠️ Slide & Reveal: Fine-tuning the animation

Hey ,

I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.

Please upgrade (use this link) access this content.

I'm super eager to help you learn more!

🛠️ Slide & Reveal: Fine-tuning the animation

Right now, each book fades in when they touch the edge of the screen. It works, but people may not be able to see the animation if they don’t scroll fast enough.

We can improve the interaction by fading in each book slightly later, say around 10% from the bottom of the screen.

We can use rootMargin to make this adjustment.

const observer = new IntersectionObserver(callback, {
  rootMargin: '0px 0px -10% 0px'
})

The fading-in timing is much better than before!

But we created another problem. Books will now fade out before they reach the bottom of the screen.

Fixing the fade-out problem

The easiest way to fix this problem is to create a second Intersection Observer. We’ll use the first Intersection to add is-visible, and the second Intersection observer to remove is-visible.

First, let’s rename the first observer to incomingObserver.

const incomingObserver = new IntersectionObserver(callback, {
  rootMargin: '0px 0px -10% 0px'
})

books.forEach(book => {
  incomingObserver.observe(book)
})

Since we need two observers, it’s easier to understand each observer’s code if we kept the callback with the observer.

const incomingObserver = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('is-visible')
    }
  })
}, {
  rootMargin: '0px 0px -10% 0px'
})

We’ll create a second observer to fade out books. Let’s call this second observer outgoingObserver. The trick here is to leave rootMargin to its default values.

const outgoingObserver = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (!entry.isIntersecting && entry.getBoundingClient > 0) {
      entry.target.classList.remove('is-visible')
    }
  })
})

books.forEach(book => {
  incomingObserver.observe(book)
  outgoingObserver.observe(book)
})