16

I would like to implement an animation to fade sections, like in this example, into my application. Therefore I've had a look at fullPage.js.

However, since I need to integrate it into a Next.js React app with server-side rendering I can't use it since it relays on jQuery, which doesn't support SSR. Therefore I've tried my luck with ScrollMagic, which doesn't relay on jQuery. But it also doesn't support SSR (needs window), therefore I've initialized it in the componentDidMount() method and even loaded it there (like it's recommended here).

It currently works initially, but as soon as you change the page and an AJAX request is done and Next.js replaces the page, an error will be thrown (see below):

Node was not found

Node was not found React error when using ScrollMagic with Next.js

I've tried to destroy ScrollMagic before the AJAX request in componentWillUnmount(), but with no luck. I can't figure out what's wrong and unfortunately, I couldn't find any documentation about ScrollMagic with React or Next.js.

This is my entire component:

import React from 'react';
import PropTypes from 'prop-types';

class VerticalSlider extends React.Component {
  constructor(props) {
    super(props);
    this.ScrollMagic = null;
    this.controller = null;
    this.scenes = [];
    this.container = React.createRef();
  }

  componentDidMount() {
    if (this.container.current) {
      // Why "require" here?
      // https://github.com/zeit/next.js/issues/219#issuecomment-393939863
      // We can't render the component server-side, but we will still render
      // the HTML
      // eslint-disable-next-line global-require
      this.ScrollMagic = require('scrollmagic');
      this.initScroller();
    }
  }

  componentWillUnmount() {
    this.scenes.forEach(scene => {
      scene.destroy();
    });
    this.controller.destroy();
    this.scenes = [];
    this.controller = null;
  }

  initScroller() {
    try {
      this.controller = new this.ScrollMagic.Controller();
      if (this.container.current !== null && this.container.current.children) {
        [...this.container.current.children].forEach(children => {
          const scene = new this.ScrollMagic.Scene({
            triggerElement: children,
            duration: window.innerHeight * 1.5,
            triggerHook: 0,
            reverse: true
          });
          scene.setPin(children);
          this.scenes.push(scene);
        });
        this.controller.addScene(this.scenes);
      }
    } catch (e) {
      console.log(e);
    }
  }

  render() {
    return (
      <div ref={this.container}>
        {this.props.sections}
      </div>
    );
  }
}

VerticalSlider.propTypes = {
  sections: PropTypes.arrayOf(PropTypes.node).isRequired
};

export default VerticalSlider;
9
  • Which version of Next.js are you using? Commented Jun 9, 2018 at 7:50
  • Next.js version ^6.0.3 Commented Jun 10, 2018 at 13:19
  • 1
    This is probably not a good answer for SO but I thought maybe this would help. React has a really good and well maintained transition library called react-transition-group and Next.js has a similar library called next-page-transitions. There is a good example showing how to use it. Example uses _app.js for easily animating every page transition. I suggest you to take a look at tha Commented Jun 10, 2018 at 13:55
  • Thanks but unfortunately that's not what I need. Commented Jun 11, 2018 at 6:30
  • can you reproduce it here repl.it/site/languages/nextjs? Commented Jun 13, 2018 at 17:59

3 Answers 3

3

Would fullpage.js not be more suited for you needs?

You should be able to map your routes and then build each slide as a placeholder for the page using the app.js

Otherwise, I should have a working example of scroll magic, I will look for the repo and share it once found.

UPDATE: Here is an example of next.js using fullpage.js

However, since I need to integrate it into a Next.js React app with server-side rendering I can't use it since it relays on jQuery

fullpage.js no longer depends on jquery and it supports SSR as well.

Sign up to request clarification or add additional context in comments.

Comments

1

Although in some other venues people suggested using next/dynamic and importing the ScrollMagic library with the option 'ssr:false', I did not have success with this tactic. The ScrollMagic object was not returned correctly.

What ended up working for me was to use a modified version of the ScrollMagic library (modified by Jan Fischer: https://github.com/bitworking) in which the whole ScrollMagic library is wrapped "in a self invoking function so that I can mock the window and document object." I copied this modified ScrollMagic to my next.js project and referenced it instead of including the package as a node module.

Here is the modified file: https://raw.githubusercontent.com/bitworking/react-scrollmagic/master/src/lib/scrollmagic.js

Comments

1

You can get scroll magic to work with next.js by doing a dynamic import.

useEffect(() => {
    const load = async () => {
      if (typeof window !== undefined) {
        const ScrollMagic = (await import('scrollmagic')).default;
        const controller = new ScrollMagic.Controller();

        new ScrollMagic.Scene({
          triggerElement: '#one',
          triggerHook: 0.5,
          reverse: true,
        })
          .on('enter', function (e: any) {
            console.log('enter');
          })
          .on('leave', function (e: any) {
            console.log('leave');
          })
          .addTo(controller);
      }
    };
    load();
  }, []);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.