add two pages view

This commit is contained in:
Vut Pov 2020-05-09 11:45:34 +07:00
parent 3c81df65a7
commit e4a862d142
5 changed files with 144 additions and 25 deletions

View File

@ -1,5 +1,6 @@
import React, {createContext} from 'react'
import OnePageView from './OnePageView'
import TwoPagesView from './TwoPagesView'
export const BookContext = createContext({})
@ -36,7 +37,7 @@ export interface IBookContext {
}
class BookComponent extends React.Component<any>{
class BookComponent extends React.Component<any, any>{
constructor(props: any){
super(props)
this.state = {
@ -45,10 +46,18 @@ class BookComponent extends React.Component<any>{
flagToReverse: false,
mode: "one page",
setBookContextState: (newState: IBookContext)=>{
this.setState(oldState=> ({
this.setState((oldState: any)=> ({
...oldState,
...newState
}))
},
changePage: (indexToGo: number, goToPrevious: boolean)=>{
const newCurrIndex = this.state.currIndex + indexToGo
this.setState({
currIndex: newCurrIndex,
flagToReverse: goToPrevious
})
}
}
}
@ -72,11 +81,14 @@ class BookComponent extends React.Component<any>{
}
render(){
const {mode} = this.state
return <BookContext.Provider value={{...this.state}}>
<BookContext.Consumer>
{state=>(
<>
<OnePageView {...state}/>
{mode === "one page" && <OnePageView {...state}/>}
{mode === "two pages" && <TwoPagesView {...state}/>}
</>
)}
</BookContext.Consumer>

View File

@ -17,7 +17,7 @@ const JumpControls = (props: any)=>{
}
}
},
[inputValue])
[inputValue, src.length, setBookContextState])
useEffect(()=>{
setInputValue(currIndex + 1)

View File

@ -1,4 +1,4 @@
import React, {useState, useCallback, useEffect} from 'react'
import React, {useState, useEffect} from 'react'
import {Transition, animated} from 'react-spring/renderprops'
import styled, { } from 'styled-components'
import BookComponentsController from './BookComponentsController'
@ -24,10 +24,9 @@ const PageContainer = styled.div`
height: 100%;
}
`
const StyledImage = styled(animated.div)<{src:string}>`
width: 100%;
height: 100%;
const StyledImage = styled(animated.div)<{src:string, width:number | string, height: number| string}>`
width: ${props=> props.width? props.width: '100%'};
height: ${props=> props.height? props.height: '100%'};
display: flex;
justify-content: center;
align-items: center;
@ -36,24 +35,16 @@ const StyledImage = styled(animated.div)<{src:string}>`
`
const PageComponent = (props: any)=>{
const {src} = props
return <StyledImage src={src}/>
const {src, width, height} = props
return <StyledImage src={src} width={width} height={height}/>
}
function BookComponent(props: any) {
const {src, currIndex, setBookContextState, flagToReverse} = props
const {src, currIndex, flagToReverse, changePage} = props
const [prevDisable, setPrevDisable] = useState(true)
const [nextDisable, setNextDisable] = useState(false)
const changePage = useCallback((indexToGo, goToPrevious)=>{
const newCurrIndex = currIndex + indexToGo
setBookContextState({
currIndex: newCurrIndex,
flagToReverse: goToPrevious
})
}, [currIndex])
useEffect(() => {
setNextDisable(currIndex >= src.length - 1)
@ -77,8 +68,6 @@ function BookComponent(props: any) {
return(
<animated.div style={{
...style,
overflowX: 'hidden'
}}>
{React.createElement(()=><PageComponent src={src[currIndex]? src[currIndex].src: null}/>)}
</animated.div>
@ -100,4 +89,4 @@ function BookComponent(props: any) {
)
}
export default BookComponent
export {ComponentContainer, PageContainer, PageComponent, BookComponent as default }

View File

@ -0,0 +1,118 @@
import React, {useState, useEffect, useCallback} from 'react'
import {Transition, animated} from 'react-spring/renderprops'
import BookComponentsController from './BookComponentsController'
import {ComponentContainer, PageComponent, PageContainer} from './OnePageView'
import { IBookContext } from './BookComponent'
export default function TwoPagesView(props: any) {
let {src, currIndex, changePage, flagToReverse} = props
const [pagesToshow, setPagesToShow] = useState<IBookContext[]>([])
const [prevDisable, setPrevDisable] = useState(true)
const [nextDisable, setNextDisable] = useState(false)
useEffect(()=>{
const shouldShowPage = (pageIndex: number)=>{
return src.length > 0 && pageIndex <= src.length - 1
}
const newCurrIndex = currIndex % 2 === 0 ? currIndex: currIndex - 1
const shouldShowFirstPage = shouldShowPage(newCurrIndex)
if(shouldShowFirstPage){
const shouldShowSecondPage = shouldShowPage(newCurrIndex + 1)
setPagesToShow([
src[newCurrIndex],
shouldShowSecondPage? src[newCurrIndex + 1]: {
src: '',
alt: '',
thumbnail: '',
}
])
}
setPrevDisable(newCurrIndex <= 1)
setNextDisable(newCurrIndex >= src.length - 2)
}, [currIndex, src])
const pageChangeClick = useCallback((indexToGo, flagToReverse)=>{
const newIndex = currIndex + indexToGo
const shouldChangePage = newIndex >= 0 && newIndex < src.length
if(shouldChangePage){
changePage(indexToGo, flagToReverse)
}
}, [src.length, currIndex, changePage])
return (
<ComponentContainer>
<PageContainer>
<Transition
reset
unique
items={pagesToshow}
keys={(item: any)=> item.src}
initial={{}}
from={{opacity: 1, transform: flagToReverse? "translate3d(-50%, 0, 0)": "translate3d(100%, 0, 0)"}}
enter={{ opacity: 1, transform: "translate3d(0%, 0, 0)" }}
leave={{ opacity: 0, transform: flagToReverse? "translate3d(100%, 0, 0)": "translate3d(-50%, 0, 0)"}}
>
{
currIndex=> style=>{
return(
<animated.div style={{
...style,
}}>
{React.createElement(()=>{
return <PageComponent width={"50%"} src={pagesToshow[0]? pagesToshow[0].src: null}/>
})}
</animated.div>
)
}
}
</Transition>
<Transition
reset
unique
items={pagesToshow}
keys={(item: any)=> item.src}
from={{opacity: 1, transform: flagToReverse? "translate3d(0%, 0, 0)": "translate3d(150%, 0, 0)"}}
enter={{ opacity: 1, transform: "translate3d(50%, 0, 0)" }}
leave={{ opacity: 0, transform: flagToReverse? "translate3d(150%, 0, 0)": "translate3d(0%, 0, 0)"}}
initial={{}}
>
{
currIndex=> style=>{
return(
<animated.div style={{
...style,
}}>
{React.createElement(()=>{
return <PageComponent width={"50%"} src={pagesToshow[1]? pagesToshow[1].src: null}/>
})}
</animated.div>
)
}
}
</Transition>
</PageContainer>
<BookComponentsController
prevDisable={prevDisable}
onPrevClick={()=> {
pageChangeClick(-2, true)
}}
nextDisable={nextDisable}
onNextClick={()=>{
pageChangeClick(2, false)
}}
{...props}
/>
</ComponentContainer>
)
}
interface Book {
name: string
}

View File

@ -12,13 +12,13 @@ export default function ViewSwitcher(props: IBookContext) {
setBookContextState({
mode
})
},[])
},[setBookContextState])
return (
<Select value={mode} onSelect={viewModeChange}>
{
bookViewModes.map((item: any)=>{
return <Option value={item.value}>{item.text}</Option>
return <Option value={item.value} key={item.value}>{item.text}</Option>
})
}
</Select>