我有一个带有简单视差的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;
更新:
Splash组件位于页面顶部,因此我能够将状态更改限制为元素在视图中时具有以下内容。没有好运提高滚动性能。
if (scrollTop < elementHeight) {
this.setState({ top: scrollTop * .7 + 'px' });
this.setState({ opacity: (elementHeight - scrollTop) / elementHeight });
}
答案 0 :(得分:0)
滚动页面的用户会触发大量滚动事件。 您不希望对每个滚动事件做出反应,而是对它们进行分组,例如每1000毫秒。
这叫做油门。 lodash library有一个很好的节流方法,但其他方法存在。
包含lodash库后,eventlistener将如下所示......
window.addEventListener('scroll', _.throttle(this.parallax, 1000));