简体   繁体   中英

Divs Reverse scroll with translateY() in react.js

I'm trying to create with React.js a type of scroll like this one: http://spassky-fischer.fr/ , where two divs are scrolling in inverse directions. They are using transform: translateY() , and I tried to implement it as well but I don't get where I'm wrong here. Here's the architecture of the projet. The current version is also here: http://noiseless-tendency.surge.sh/

App.js :

ComponentDidMount(){
    window.addEventListener("scroll", this.scrollHandler);
} 

...

scrollHandler = () => {
    this.setState({
      scrollPositionY: window.scrollY
    })
}

...

render() {
    return (
      <div className="App">
          <MainItemsContainer {...this.state} />
      </div>
    );
  }

MainItemsContainer.js :

render() {

    let style_first = {
      transform: `translateY(${this.props.scrollPositionY})`,
      overflow: "hidden"
    }

    let style_second = {
      transform: `translateY(-${this.props.scrollPositionY})`,
      overflow: "hidden"
    }


    return (
      <div className="main_items_container">
        <section
        style={style_first}
        className="main_items_container_child">
          <ItemsContainer {...this.props}/>
        </section>
        <section 
          style={style_second}
          className="main_items_container_child">
          <ItemsContainer {...this.props}/>
        </section>
      </div>
    );
  }

App.css :

.main_items_container {
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
}

.main_items_container .main_items_container_child{
  width: 50%;
  height: 100vh;
  overflow: scroll;
}

The sample site you linked actually uses the wheel event rather than the scroll event. It looks like they use this library to accomplish it: https://swiperjs.com/demos/ . My understanding is that the scroll event only fires if there's a scrollbar, which is why your event handler didn't fire.

I've created a Code Sandbox that produces the effect you want in React. It does rely on jQuery to compute the height of the whole element, and to set the initial transformation for the left half. However, those are just convenience methods, and if you don't want jQuery as a dependency, you can find workarounds for those pretty easily.

So you could use hooks and pass a custom css var through inline styling on state change to update your translateY. I have not tested but I hope you get my drift.

let elRef = useRef(null)

let[ height, setHeight] = useState()

use useLayoutEffect hook to add the event listener

useLayoutEffect (()=>{
  if(!elRef) return
  elRef.current.addEventListener("scroll", setHeight(elRef.current.scrollY));

return  elRef.current.removeEventListener("scroll", setHeight());
}, )

and put the ref on you outermost div perhaps , so your outer div would look like

<div className='container' ref={elRef} style{{ --height: height}} > 
 <div className='columOne' > </div>
 <div className='columTwo' > </div>
</div>

in your css (I haven't put all that is required but just showing how you custom css var is used

.container{
display: flex;
flex-direction: row
}

And within that equal sized columns

   .columnOne{
      transform: `translateY(calc(var(--height) * 1px)`,
      overflow: "hidden"
    }

 .columnTwo{
      transform: `translateY(-calc(var(--height) * 1px)`,
      overflow: "hidden"
    }

Does that help. Let me know if I could be more clear. Or use styled components and pass a prop in to achieve the same result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM