滚动到指定位置
2019-04-07 本文已影响0人
源川
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import './index.scss'
const trail = {
linear : (t, b, c, d) => {
return c * t/d + b
},
easeIn : ( t, b, c, d ) => c * ( t /= d ) * t + b,
easeOut : ( t, b, c, d ) => -c *( t/=d )*( t - 2 ) + b,
easeInOut : ( t, b, c, d ) => {
if ( ( t/=d/2 ) < 1 ) return c/2 * t * t + b
return -c/2 * ( (--t) * (t-2) - 1 ) + b
}
}
class Back extends Component {
state = {
isShow: false
}
scrollTo = () => {
// const { y, duration, rate } = this.props
const y = 100, duration = 900, rate = 30
const start = this.getScrollTop()
let end = y
if(end < 0) {
end = 0
}
this.getStep(start, end, (step) => {
this.setScrollTop(step)
}, duration, rate)
}
getStep = (start, end, callback, duration, rate) => {
const diff = end - start
if(duration == 0 || diff == 0) {
callback && callback(end)
return
}
let count = duration / rate
let i = 0
let t = 0
this.props.onScrollStart()
const timer = window.setInterval(() => {
if(i < count - 1) {
t += rate
const value = trail.easeOut(t, start, diff, duration)
callback && callback(value)
i++
} else {
this.props.onScrollEnd()
callback && callback(end)
window.clearInterval(timer)
}
}, rate)
}
bindScroll = () => {
const scrollTop = this.getScrollTop()
if(scrollTop > this.props.offset){
this.setState({ isShow: true })
}else{
this.setState({ isShow: false })
}
}
setScrollTop = (y) => {
document.documentElement.scrollTop = y
document.body.scrollTop = y
}
getScrollTop = () => {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
return scrollTop
}
componentDidMount(){
window.addEventListener('scroll', this.bindScroll)
}
componentWillUnmount() {
window.removeEventListener('scroll', this.bindScroll)
}
render() {
const { icon } = this.props
const { isShow } = this.state
return (
<div className="back" >
{ isShow &&
<div className="back-warp" onClick={this.scrollTo}>
{ icon && <div className="back-icon">{icon}</div>}
</div>
}
</div>
)
}
}
Back.porpTypes = {
icon: PropTypes.string,
offset: PropTypes.number,
onScrollStart: PropTypes.func,
onScrollEnd: PropTypes.func
}
Back.defaultProps = {
icon: '',
offset: 1000,
onScrollStart: () => {},
onScrollEnd: () => {}
}
export default Back