6

I've tried to make a text with parallax and failed. Code seems innocuous and doesn't seem to be doing anything wrong, yet the scroll look&feel is quite wrong.

Markup is like this:

<!-- content above -->
<section class="section-parallax">
  <div class="container text-center">
    <div class="flex-row-columns">
      <div class="flex-row">
        <h2 class="heading flex-8">
          <span class="heading-sub">Some Header</span>
          <span class="heading-bottom">getting also long<sup>
        </h2>
      </div>
    </div>
  </div>
</section>
<!-- content below -->

Styles like this:

.container {
  box-sizing: border-box;
  margin-left: auto;
  margin-right: auto;
  padding-left: 15px;
  padding-right: 15px;
  width: 1400px;
}

.text-center {
  text-align: center;
}

.section-parallax {
  background: black;
  overflow: hidden;

  &,
  & .container,
  & .flex-row {
    min-height: 545px;
  }

  & .container {
    transform: translate3d(0, -100%, 0);
  }
}

.flex-row-columns {
  display: flex;
  flex-direction: column;
  margin-top: 0;
  margin-bottom: 0;
  margin-left: 0;
  margin-right: 0;
}

.flex-row {
  align-items: center;
  display: flex;
  justify-content: center;
  margin-left: -15px;
  margin-right: -15px;
}

.flex-8 {
  flex-basis: 66.66666666666667%;
  padding-left: 15px;
  padding-right: 15px;
}

.heading {
  color: white;
  font-size: 54px;
  letter-spacing: .66px;
  line-height: 1.273em;
}

.heading-sub {
  display: block;
  margin-bottom: 20px;
}

And finally the JS I've used is like this:

class ParallaxSection {
  constructor() {
    this.el = document.querySelector('.section-parallax');
    this.els = {
      container: this.el.querySelector('.container')
    };
    this.calcBounds();

    window.addEventListener('scroll', this.onScroll.bind(this));
    window.addEventListener('resize', () => {
      this.calcBounds();
      this.onScroll();
    });
  }

  calcBounds() {
    if (this.tween) {
      this.tween.kill();
      this.els.container.removeAttribute('style');
    }

    const rect = this.el.getBoundingClientRect();
    const scrollY = ParallaxSection.getScroll();

    this.start = (rect.top + scrollY) - (window.innerHeight * 0.75);
    this.end = this.start + this.el.offsetHeight + window.innerHeight;
    this.tween = TweenLite.fromTo(this.els.container, 1, {
      css: {
        force3D: true,
        y: -this.el.offsetHeight
      }
    }, {
      paused: true,
      css: {
        force3D: true,
        y: this.end - this.start - this.el.offsetHeight
      },
      ease: Linear.easeNone
    });
  }

  onScroll() {
    const scroll = ParallaxSection.getScroll();

    if (scroll >= this.start && scroll <= this.end) {
      const diff = this.end - this.start;
      const offset = scroll - this.start;
      const perc = offset / diff;
      this.tween.progress(perc);
    }
  }

  static getScroll() {
    return window.pageYOffset || document.documentElement.scrollTop;
  }
}

const p = new ParallaxSection();

Now, the odd thing is that while trying to discover the issue I put this into a Pen so I could try to see where it failed and in the pen seemed alright. That led me to remove all the elements on my page and replicate the pen exactly, turns out that, for some unknown reason the effect is perfect on codepen and fails out of it.

I've downloaded the whole HTML that codepen generates and it suffers the same experience.

enter image description here

Pen is here to be seen.

What's wrong with it?

iehrlich
  • 3,572
  • 4
  • 34
  • 43
Antonio Laguna
  • 8,973
  • 7
  • 36
  • 72
  • 1
    Do you really need GSAP for this? You can replicate this effect by having a fixed container. – Cosmin Ababei Mar 26 '17 at 21:04
  • 1
    You don't need to use the CSSPlugin for this, you can animate the 'y' property directly. I wouldn't have thought that would be enough to make it 'janky' though. If things are different between codepen/local it may be that one of your container `
    `'s does not have `transform: translateZ(0)` on it and codepen`s does? The code looks reasonable to me.
    – Paul Thomas Mar 27 '17 at 10:33
  • Is it bad all the time for you, or just when you get to the parallax section? – Paul Thomas Mar 27 '17 at 10:34
  • Effect just seems wrong on the parallax section. FPS on scrolling seems 60 all the time anyway. Codepen seems now wrong too after this: https://twitter.com/CodePen/status/845351286816096256 using translate3d so it could be smoother. – Antonio Laguna Mar 27 '17 at 14:21
  • @AntonioLaguna when you say you've downloaded, do you mean that you used the export feature? After exporting I was still unable to replicate the issues, perhaps your computer is being slow when accessing the file directly? Have you tried running it on a local server to see if it still occurs? – Patrick Barr Mar 28 '17 at 17:07
  • Some of the html is invalid `getting also long`. Doesn't look like you're closing the `span` – K Scandrett Apr 01 '17 at 03:01
  • I'd try to make the white text fixed (absolute position) and only scroll the black part behind it, plus some JS code to show and hide the white letters at the correct moment. That'll remove your jitter. example: http://codepen.io/anon/pen/evxrXY (not incluing the hiding logic) – S. Roose Apr 02 '17 at 19:08

1 Answers1

0

I think the problems comes from trying to execute the logic on every scrolled pixel. Maybe you can fix that by using:

Martin Chaov
  • 824
  • 7
  • 17