平滑React组件中的视差

时间:2017-07-09 16:21:07

标签: javascript css reactjs

我有一个带有简单视差的React组件,可以更改顶部和不透明度值。问题是滚动动画有点生涩。有什么方法可以平滑过渡吗?我在vanilla JS中使用requestAnimationFrame(),但我不认为我可以在React组件中使用它,因为渲染周期不同。

此外,如果元素超出视口,我该如何停止更改状态?

这是我的实施:



const Parallax = React.createClass({
  getInitialState: function () {
    return {
      top: 0,
      opacity: 1
    };
  },

  parallax: function(event) {
    const scrollTop = window.pageYOffset;
    const elementHeight = this.splash.clientHeight;

    this.setState({ top: scrollTop * .7 + 'px' });
    this.setState({ opacity: (elementHeight - scrollTop) / elementHeight });
  },

  componentDidMount: function() {
    window.addEventListener('scroll', this.parallax);
  },

  componentWillUnmount: function() {
    window.removeEventListener('scroll', this.parallax);
  },

  render: function() {
    const splashStyle = { 
      transform: 'translateY(' + this.state.top +')',
      opacity: this.state.opacity
    };

    return (
      <div className="splash" 
        ref={ domElement => { this.splash = domElement; }}>

        <div className="splash__wrapper " style={ splashStyle }>
            <p>LONG CONTENT</p>
        </div>

      </div>
    );
  }

});

ReactDOM.render(
  <Parallax />,
  document.getElementById('container')
);
&#13;
.splash {
      position: relative;
      width: 100vw;
      max-width: 100%;
      height: 100vh;
      min-height: 500px;
      background: url(https://facebook.github.io/react/img/logo_og.png) no-repeat 10% 60%;
      -webkit-background-size: cover;
      -moz-background-size: cover;
      -o-background-size: cover;
      background-size: cover;
    }
    
    .splash__wrapper {
      position: absolute;
      color: #fff;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      transition: 0s transform;
    }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>
&#13;
&#13;
&#13;

更新:

Splash组件位于页面顶部,因此我能够将状态更改限制为元素在视图中时具有以下内容。没有好运提高滚动性能。

if (scrollTop < elementHeight) {
  this.setState({ top: scrollTop * .7 + 'px' });
  this.setState({ opacity: (elementHeight - scrollTop) / elementHeight });
}

1 个答案:

答案 0 :(得分:0)

滚动页面的用户会触发大量滚动事件。 您不希望对每个滚动事件做出反应,而是对它们进行分组,例如每1000毫秒。

这叫做油门。 lodash library有一个很好的节流方法,但其他方法存在。

包含lodash库后,eventlistener将如下所示......

window.addEventListener('scroll', _.throttle(this.parallax, 1000));