Closed JoeyCurry closed 7 years ago
The same way you use any external JS library with React :)
require, and then hook it, for example in your componentWillMount
method
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>
)
}
}
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';`
@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.
@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.
@brybrophy where do you suggest such a file should be added, and what should its contents be precisely?
when I tried to console.log(this.scene)
it returns undefined
, I wrapped it in an if condition and it still returns undefined
@majidzeno please make some effort in helping us help you
On 26. Sep 2018, at 15:05, Majid Eltayeb notifications@github.com wrote:
when I tried to console.log(this.scene) it returns undefined, I wrapped it in an if condition and it still returns undefined
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/wagerfield/parallax/issues/167#issuecomment-424707390, or mute the thread
@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> ) } }
@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;
Thank you for sharing your solution! :)
On 27. Sep 2018, at 14:18, Majid Eltayeb notifications@github.com wrote:
@reneroth https://github.com/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 https://github.com/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 (
<figure data-depth="0.6" className="diary-post__image" style={{ backgroundImage: url(${ post._embedded["wp:featuredmedia"][0].media_details.sizes .medium.source_url }) }} />
{post.title.rendered}
{post.date}
); }); return (
{posts}
); } } export default Diary; `
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...
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>
)
}
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.
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.
How resolved it?
How can I use Parallax.js with React.js?