jlmakes / scrollreveal

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

SR after parent SR runs #348

Closed ekfuhrmann closed 7 years ago

ekfuhrmann commented 7 years ago

This is similar in vein to #160, but I was curious about actual implementation.

I want to do something similar to the following:

var revealChild = sr.reveal('.child', {
  delay      : 150,
  duration   : 700,
  distance   : '20px',
});

sr.reveal('.parent', {
  duration     : 500,
  viewFactor   : 0.5,
  afterReveal  : revealChild,
}, 150);

The primary issue I'm having with this is that it is being run within a sequence, so even though I have the parent firing off the child reveal, it doesn't work great on later stages. I basically want to chain child animations to their specific parent firing off. I'm not sure if this is possible with the current implementation based on the documentation, but figured I'd ask nonetheless.

--

To help demonstrate what it is I'm trying to do, I threw together this codepen.

The cards themselves are supposed to reveal (as they do), and then right as the card reveal finishes, I want the reveal animation to run for the card-title and card-text children. It works fine early on, and when scrolling down; however if you scroll up it starts to fall apart.

Since the card-text and card-title classes are independent of the parent container, if you scroll up slowly their animation will run while the parent is still not visible. Then when the parent card loads, the text animation is already completed so nothing happens.

In addition, if you scroll down very quickly, the card animation fires off quickly, but the text/title lag behind as they need to sequence through each other. I'm guessing since I have 2 classes being sequenced together, it takes twice as long, but I am hoping there is a way to just have it sequence off the parent container and not as a whole.

Is there a better method to tying the animations to when the card reveals itself?

Thanks!

jlmakes commented 7 years ago

So I attempted a few solutions, but kept finding it far too convoluted—which I do my best to recognize as a signal of bad code/poor solution. So I’ll run you through 2 solutions that I think keep this as simple as possible.

Solution 1

What I think is the simplest solution, is to remove option.viewFactor from the parents. This way, the children will never begin their reveal before their parent. If you don't want element's to reveal the instant they are within the viewport, you can explore option.viewOffset to shrink the active viewport area.

For Example:

viewoffset

And in order to fix the other issue with child sequences taking twice as long, simply reduce the children sequence interval from 150 to 75 or so and you’re good.


Solution 2

I was thinking about this problem, and it's come down to this:

The second step really has nothing to do with detecting the child visibility, which is what got me thinking—maybe using ScrollReveal on the children is making this more complicated that necessary.

I admit it's a little unusual to suggest using less ScrollReveal, but ultimately the behavior you want for the children is more dependent on it's parent state than their own visibility. So, you could use the callbacks to toggle a class on the parent, and then handle the animations on the children the old fashioned way.

For Example:

window.sr = ScrollReveal()

sr.reveal('.card-box', {
    duration: 600,
    distance: '20px',
    easing: 'ease-out',
    origin: 'bottom',
    reset: true,
    scale: 1,
    viewFactor: 0.3,
    afterReveal: function (el) { el.classList.add('is-visible') },
    afterReset: function (el) { el.classList.remove('is-visible') },
}, 150)
.card-title {
    position: relative;
    top: 25px;
    opacity: 0;
    transition: all 0.3s;
}

.is-visible .card-title {
    top: 0;
    opacity: 1;
}

This way, ScrollReveal handles visibility checking and sequencing your parents, while you use a CSS hook to handle child animations yourself. It’s a little more work, but I think gives you the control you’re looking for over the children's behavior.

P.S.

Thanks for the accompanying demo. And boy do those colors sure look good! 😉

ekfuhrmann commented 7 years ago

As always, thanks for the incredibly well thought out and detailed response. I considered solution 2 myself but wanted to verify there wasn't something more I was missing within SR itself.