Scroll Event
앱을 보다가 Scroll하는 이벤트가 너무 멋져서 만들어 보았다.
생각보다 할 게 많아서 조금 당황했지만 완성시켜서 만족한다 하하
ScrollToComponenet
react-scroll-to-component
모듈만 설치하면 되는 지 알았다. 한 js 파일 내 있으면 단순히 ref binding만 해주면 돼서 간단한데, 따로 Component로 뺄 때가 문제였다.
// yarn add react-scroll-to-component
import scrollToComponent from 'react-scroll-to-component';
// 함수 내부, 간단하게 좌표 잡아서 좌표에 대한 위치로 scroll한다는 거다.
var scroll = require('scroll-to');
var body = document.body,
html = document.documentElement;
var elementRect = element.getBoundingClientRect();
var clientHeight = html.clientHeight;
var documentHeight = Math.max( body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight );
offset = offset || 0; // additional offset to top
var scrollPosition;
switch(alignment) {
case 'top': scrollPosition = elementRect.top; break;
case 'middle': scrollPosition = elementRect.bottom - clientHeight / 2 - elementRect.height / 2; break;
case 'bottom': scrollPosition = elementRect.bottom - clientHeight; break;
default: scrollPosition = elementRect.bottom - clientHeight / 2 - elementRect.height / 2; break; //defaul to middle
}
var maxScrollPosition = documentHeight - clientHeight;
return Math.min(scrollPosition + offset + window.pageYOffset,
maxScrollPosition);
ScrollButton
컴퍼넌트를 작성하는데, 일단 버튼이라고 한다면 색상을 가져오는 것과
버튼이니깐 또 이동을 해야 하는데, 어디로 이동할 지 DOM을 찾는 게 중요했다.
export default class ScrollButton extends React.Component {
constructor(props) {
super(props);
this.componentWillMount = this.componentWillMount.bind(this);
this.styles = {
'background-color' : this.props.color
}
}
componentWillMount() {
scrollToComponent(this.props.to, { offset: 0, align: 'top', duration: 500, ease:'inCirc'});
}
render() {
return (
<>
<Button className="button" style={this.styles} onClick={this.componentWillMount} variant="primary">{ this.props.text} </Button>
<br/>
</>
);
}
}
외부에서 호출하는 것은 다음과 같이 이루어진다.
<button onClick={() => scrollToComponent(this.Indigo, { offset: 0, align: 'bottom', duration: 1500, ease:'inExpo'})}>Go To Indigo</button>
<ScrollButton to={this} text="Indigo" color='indigo' ref={(ScrollButton) => { this.Indigo = ScrollButton; }}>Indigo</ScrollButton>
ref가 callback이니 ScrollButton 생기고 난 후 App Component에서 참조하는 this.Indigo는 ref에서 binding한 this.Indigo와 같다.