mirror of
https://github.com/jxnblk/mdx-deck.git
synced 2024-11-29 13:58:02 +03:00
Adjust scroll behavior
This commit is contained in:
parent
c9157a37d9
commit
88a76c61f5
94
lib/entry.js
94
lib/entry.js
@ -10,11 +10,61 @@ import debounce from 'lodash.debounce'
|
||||
// todo: dynamic import
|
||||
import slides from '../docs/index.mdx'
|
||||
|
||||
const Carousel = styled.div([], {
|
||||
const CarouselRoot = styled.div([], {
|
||||
display: 'flex',
|
||||
overflowX: 'auto',
|
||||
width: '100vw',
|
||||
scrollSnapType: 'mandatory',
|
||||
})
|
||||
|
||||
class Carousel extends React.Component {
|
||||
root = React.createRef()
|
||||
isScroll = false
|
||||
|
||||
handleScroll = debounce(e => {
|
||||
if (this.isScroll) {
|
||||
this.isScroll = false
|
||||
return
|
||||
}
|
||||
const { scrollLeft } = e.target
|
||||
const rect = e.target.getBoundingClientRect()
|
||||
const n = Math.round(scrollLeft / rect.width)
|
||||
this.props.onScroll(n)
|
||||
}, 200)
|
||||
|
||||
scrollTo = (index) => {
|
||||
if (!this.root.current) return
|
||||
const el = this.root.current.querySelector('#slide-' + index)
|
||||
if (!el) return
|
||||
el.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.root.current.addEventListener('scroll', this.handleScroll)
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.root.current.removeEventListener('scroll', this.handleScroll)
|
||||
}
|
||||
|
||||
componentDidUpdate (prev) {
|
||||
if (prev.index === this.props.index) return
|
||||
this.isScroll = true
|
||||
this.scrollTo(this.props.index)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { onScroll, index, ...props } = this.props
|
||||
|
||||
return (
|
||||
<CarouselRoot
|
||||
innerRef={this.root}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const Slide = styled.div([], {
|
||||
outline: '2px solid tomato',
|
||||
flex: 'none',
|
||||
@ -42,47 +92,19 @@ class App extends React.Component {
|
||||
index: 0
|
||||
}
|
||||
|
||||
root = React.createRef()
|
||||
|
||||
update = fn => this.setState(fn)
|
||||
|
||||
handleScroll = debounce(e => {
|
||||
if (this.isProgrammaticScroll) return
|
||||
const { scrollLeft } = e.target
|
||||
const rect = e.target.getBoundingClientRect()
|
||||
const n = Math.round(scrollLeft / rect.width)
|
||||
console.log('scroll', e, n)
|
||||
this.setState({ index: n })
|
||||
}, 1000)
|
||||
|
||||
componentDidMount () {
|
||||
this.root.current.addEventListener('scroll', this.handleScroll)
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.root.current.removeEventListener('scroll', this.handleScroll)
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
if (!this.root.current) return
|
||||
const { index } = this.state
|
||||
const el = this.root.current.querySelector('#slide-' + index)
|
||||
if (!el) return
|
||||
this.isProgrammaticScroll = true
|
||||
el.scrollIntoView({
|
||||
behavior: 'smooth'
|
||||
})
|
||||
setTimeout(() => {
|
||||
console.log(this.isProgrammaticScroll)
|
||||
this.isProgrammaticScroll = false
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
render () {
|
||||
const { slides } = this.props
|
||||
const { index } = this.state
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Carousel innerRef={this.root}>
|
||||
<Carousel
|
||||
index={index}
|
||||
onScroll={index => {
|
||||
this.setState({ index })
|
||||
}}>
|
||||
{slides.map((Component, i) => (
|
||||
<Slide key={i} id={'slide-' + i}>
|
||||
<Component />
|
||||
|
Loading…
Reference in New Issue
Block a user