baptistebriel / smooth-scrolling

smooth scrolling and parallax effects on scroll
MIT License
610 stars 74 forks source link

Parallax Sections #86

Open adamgilmour opened 6 years ago

adamgilmour commented 6 years ago

Hey baptistebriel,

Using your 'parallax-page' demo as a base, I'm trying to make a page with numerous sections, with parallax elements absolutely positioned, relative to the parent.

I originally changed the demo so it displayed divs instead of images and I'm experiencing some issues with the scroll container having no height on page load. But when you resize the window, it recalculates and works fine. I can fix this in a hacky way by forcing a resize in my code:

setTimeout(function(){
    window.dispatchEvent(new Event('resize'));
})

Is there a more elegant way to fix this? I'm using webpack as a build tool and the strange thing is once the packages are bundled for production it works fine?!? The codesandbox example below seems to work fine too.

Also another issue I'm experiencing is elements with a positive data-speed attribute applied (data-speed="1") to a div/img causes it to jump when visible in the viewport. You can see this on the link below, once the container with the cat image is scrolled to. Any ideas why it could be doing this?

Here is the code - https://codesandbox.io/s/4r6okr4834

Many thanks and great work 👍

baptistebriel commented 6 years ago

Hi @adamgilmour,

I'm not having the first issue on your demo link — the scroll container does have the desired height value, and I'm able to scroll from the beginning.

One issue I did noticed is the jump of the image. Because we're applying a transform value on it, it seems like to top position is not detected property — it could be because the image is not loaded yet, but since you're using preload: true we shouldn't see this...

One thing you can do is remove the in-viewport detection and just apply the transform all the time. The jump you've seen is because when the element enters the viewport, it applies a transform value of around ~100px. Since it's the first time the transform is applied, the jump occurs.

Try to replace the inViewport function with the following:

inViewport(el, index) {
  if(!this.cache || this.resizing) return
  const cache = this.cache[index]
  const current = this.vars.current
  const transform = ((cache.top + cache.center) - current) * cache.speed
  el.style[this.prefix] = this.getTransform(transform)
}

Let me know if that fixes the issue!

adamgilmour commented 6 years ago

Hi @baptistebriel, sorry for the delay, thanks for getting back to me.

I've sorted the first issue - it was because the Webpack setup I'm using was injecting the css via js, meaning smooth-scroll had nothing to base the height calculation on initial load.

With jumping element/image issue I think I had already tried what you've suggested but like you say it continues to transform the element when out of the viewport which may decrease page performance.

I might look into seeing whether I could add another option/data attribute to offer some 'in view' tolerance to each parallax element so you can define when the transforms should run. Do you think this would be possible?

Cheers :)

adamgilmour commented 6 years ago

I've managed to get another data attribute working for a tolerance option, works for elements that are already in the viewport but still working on how to activate elements that aren't scrolled into view yet, I'll see how I get on!

One thing I've spent a lot of time on, and got nowhere, is trying to utilise the current code so that it registers when a singular element is in viewport, instead of a collection of elements (such as your parallax demo). I can get this working fine with an external plugin https://github.com/camwiegert/in-view but would like to use existing code that you've written with getBoundingClientRect(). Ideally I'd like to pass a callback function when the element is in the viewport, in which I can use gsap to animate.

Is this possible?

Cheers :)

baptistebriel commented 6 years ago

Hey, @adamgilmour — using in-view from @camwiegert is a good idea. I believe he's using MutationObserver, but you could also use Intersection Observer if you want to look into doing it from scratch.

As of registering a single element — I think you still should do it inside a forEach function, just in case you might want to have other elements later on, your code will work.

I haven't really used this module since a while and mostly just re-write it for the project needs. You can have a look at this most recent code I've been using, if it can help. You might need to do some cleanup before actually using it, but it might be something similar to what you want.

ammein commented 5 years ago

Hey adam , I know it has been months. But I wanted to tell you the jumping image thing is because your data-speed=1 . What I did is make it data-speed=0.05 and I can see the image is VERY SLIGHTLY movement when inview hits. Try change your data-speed lower than 0.5 to see slight movement