Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I use Parallax.js with React.js? #167

Closed
JoeyCurry opened this issue Jan 10, 2017 · 16 comments
Closed

How can I use Parallax.js with React.js? #167

JoeyCurry opened this issue Jan 10, 2017 · 16 comments

Comments

@JoeyCurry
Copy link

How can I use Parallax.js with React.js?

@reneroth
Copy link
Collaborator

The same way you use any external JS library with React :)
require, and then hook it, for example in your componentWillMount method

@wagerfield
Copy link
Owner

Thanks for taking the time to help everyone out @RROrg.

@JoeyCurry please see below:

import React, { Component } from 'react'
import Parallax from 'parallax-js' // Now published on NPM

class ParallaxComponent extends Component {
  componentDidMount() {
    this.parallax = new Parallax(this.scene)
  }
  componentWillUnmount() {
    this.parallax.disable()
  }
  render() {
    render (
      <ul ref={el => this.scene = el}>
        <li className="layer" dataDepth="0.00">
          <img src="layer1.png"/>
        </li>
        <li className="layer" dataDepth="0.50">
          <img src="layer2.png"/>
        </li>
        <li className="layer" dataDepth="1.00">
          <img src="layer3.png"/>
        </li>
      </ul>
    )
  }
}

@raj-khare
Copy link

Why it's not working?

Could not find a declaration file for module 'parallax-js'. '/Users/stuff/Desktop/portfolio/node_modules/parallax-js/dist/parallax.js' implicitly has an 'any' type.
Try `npm install @types/parallax-js` if it exists or add a new declaration (.d.ts) file containing `declare module 'parallax-js';`

@reneroth
Copy link
Collaborator

reneroth commented Jun 9, 2018

@pixzels set noImplicitAny to false in your typescript configuration. If you still face problems after that, please open a new issue and contribute as much information as possible.

@TheDoubt TheDoubt mentioned this issue Jun 14, 2018
@brybrophy
Copy link

@pixzels It isn't working because there are no TypeScript type definitions for this package.

In the error message it says you can

add a new declaration (.d.ts) file containing declare module 'parallax-js';

I would suggest going this route, rather than setting noImplicitAny=false in your TypeScript config. If you really want to get the most power out of TypeScript, you want your config to be as strict as possible.

@Harti
Copy link

Harti commented Aug 12, 2018

@brybrophy where do you suggest such a file should be added, and what should its contents be precisely?

@majidzeno
Copy link

when I tried to console.log(this.scene) it returns undefined, I wrapped it in an if condition and it still returns undefined

@reneroth
Copy link
Collaborator

reneroth commented Sep 26, 2018 via email

@majidzeno
Copy link

majidzeno commented Sep 26, 2018

@reneroth I used npm i -s parallax-js and inside my component, I did the same thing like that quoted reply, I added ref={el => this.scene = el} to my component and inside componentDidMount i tried to cosole.log(this.scene) and i got undefined
P.S: My component is fetched from Wordpress API ... I think that could be the cause

Thanks for taking the time to help everyone out @RROrg.

@JoeyCurry please see below:

import React, { Component } from 'react'
import Parallax from 'parallax-js' // Now published on NPM

class ParallaxComponent extends Component {
  componentDidMount() {
    this.parallax = new Parallax(this.scene)
  }
  componentWillUnmount() {
    this.parallax.disable()
  }
  render() {
    render (
      <ul ref={el => this.scene = el}>
        <li className="layer" dataDepth="0.00">
          <img src="layer1.png"/>
        </li>
        <li className="layer" dataDepth="0.50">
          <img src="layer2.png"/>
        </li>
        <li className="layer" dataDepth="1.00">
          <img src="layer3.png"/>
        </li>
      </ul>
    )
  }
}

@majidzeno
Copy link

majidzeno commented Sep 27, 2018

@reneroth Okay I solved the issue , I was fetching posts from API and I was trying to apply parallax to every single post , I used the solution that @wagerfield introduced, the issue was the refs, in React 16.3 it is recommended to use React.createRef() API and also after using ref it returns a node so to access the dom element you have to use current, to access all posts I had to give the posts container a ref and then loop through its children and give every single post a parallax in componentDidUpdate .. check out my component

import React, { Component } from "react";
import Parallax from "parallax-js";
class Diary extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.scene = React.createRef();
  }

  componentDidUpdate() {
    if (this.scene) {
      var childNodes = this.scene.current.childNodes;
      var i;
      for (i = 0; i < childNodes.length; i++) {
        this.parallax = new Parallax(childNodes[i]);
      }
    } else {
      return null;
    }
  }
  componentWillUnmount() {
    this.parallax.disable();
  }

  render() {
    if (!this.state.pageData) return null;
    const posts = this.state.pageData.map((post, index) => {
      return (
        <div
          key={index}
          className="post diary-post"
          data-relative-input="true"
          data-hover-only="true"
          data-clip-relative-input="true">
          <div className="diary-post__background" data-depth="0.4">
            <figure
              data-depth="0.6"
              className="diary-post__image"
              style={{
                backgroundImage: `url(${
                  post._embedded["wp:featuredmedia"][0].media_details.sizes
                    .medium.source_url
                })`
              }}
            />
          </div>
          <h2 className="diary-post__title" data-depth="0.4">
            {post.title.rendered}
          </h2>
          <h6 className="diary-post__date">{post.date}</h6>
        </div>
      );
    });
    return (
      <main ref={this.scene} className="page page-diary">
        {posts}
      </main>
    );
  }
}
export default Diary;

@reneroth
Copy link
Collaborator

reneroth commented Sep 27, 2018 via email

@xavierartot
Copy link

I switched to React library, a tons are much better for a SAP.
https://www.npmjs.com/package/rc-scroll-anim
https://www.npmjs.com/package/react-plx
etc...

@kingdavidmartins
Copy link

kingdavidmartins commented Oct 11, 2020

Updated with hook version for those who are curious.

const YourComponent = () => {
  const sceneEl = useRef(null);

  useEffect(() => {
    const parallaxInstance = new Parallax(sceneEl.current, {
      relativeInput: true,
      hoverOnly: true
    })

    parallaxInstance.enable();

    return () => parallaxInstance.disable();
  }, [])

  return (
    <div ref={sceneEl}>
      {/* html */}
    </div>
  )
}

@fleece30
Copy link

Updated with hook version for those who are curious.

const YourComponent = () => {
  const sceneEl = useRef(null);

  useEffect(() => {
    const parallaxInstance = new Parallax(sceneEl.current, {
      relativeInput: true,
      hoverOnly: true
    })

    parallaxInstance.enable();

    return () => parallaxInstance.disable();
  }, [])

  return (
    <div ref={sceneEl}>
      {/* html */}
    </div>
  )
}

The sceneEl.current is always null for some reason so parallax doesnt understand what it is and throws an error. I tried to do it using getElementById but it just messes up the design of the app and doesnt apply the parallax effect.

@ArmedVeteran
Copy link

ArmedVeteran commented Feb 1, 2021

Updated with hook version for those who are curious.

const YourComponent = () => {
  const sceneEl = useRef(null);

  useEffect(() => {
    const parallaxInstance = new Parallax(sceneEl.current, {
      relativeInput: true,
      hoverOnly: true
    })

    parallaxInstance.enable();

    return () => parallaxInstance.disable();
  }, [])

  return (
    <div ref={sceneEl}>
      {/* html */}
    </div>
  )
}

The sceneEl.current is always null for some reason so parallax doesnt understand what it is and throws an error. I tried to do it using getElementById but it just messes up the design of the app and doesnt apply the parallax effect.

The solution posted by @kingdavidmartins works well. Are you sure sceneEl.current is the problem? I've had a mistake in my code, because I've been looking at the original answer and there's an attribute spelling mistake (made due to the React standard) - it should be "data-depth", instead of "dataDepth". That's what solved the lack of parallax in my case anyway.

@arzitmahajan
Copy link

How resolved it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests