two view page jsx

This commit is contained in:
vuthpov 2020-05-11 20:42:34 +07:00
parent e2f0f5c7e6
commit 64614fdd7c
3 changed files with 122 additions and 158 deletions

View File

@ -1,6 +1,6 @@
import React, {createContext} from 'react' import React, { createContext } from 'react'
import OnePageView from './OnePageView' import OnePageView from './OnePageView'
import TwoPagesView from './TwoPagesView' import TwoPagesView from './TwoPagesView.jsx'
import BookComponentsController from './BookComponentsController' import BookComponentsController from './BookComponentsController'
import './index.css' import './index.css'
@ -12,7 +12,7 @@ export interface IBookPage {
thumbnail?: string thumbnail?: string
} }
export const getBookViewModes = (currIndex = 0, srcLength = 0)=>[ export const getBookViewModes = (currIndex = 0, srcLength = 0) => [
{ {
text: 'One Page', text: 'One Page',
value: 'one page', value: 'one page',
@ -41,51 +41,51 @@ export interface IBookContext {
src?: IBookPage[], src?: IBookPage[],
flagToReverse?: boolean, flagToReverse?: boolean,
mode?: BookViewMode, mode?: BookViewMode,
readonly setBookContextState: (newState: any)=> undefined readonly setBookContextState: (newState: any) => undefined
} }
const getPagesCountToTurn = (mode: string)=>{ const getPagesCountToTurn = (mode: string) => {
let pagesToTurn = getBookViewModes().find(item=> item.value === mode)?.pagesToTurn let pagesToTurn = getBookViewModes().find(item => item.value === mode)?.pagesToTurn
return pagesToTurn || 0 return pagesToTurn || 0
} }
class BookComponent extends React.Component<any, any>{ class BookComponent extends React.Component<any, any>{
constructor(props: any){ constructor(props: any) {
super(props) super(props)
this.state = { this.state = {
currIndex: 0, currIndex: 0,
src: [], src: [],
flagToReverse: false, flagToReverse: false,
mode: "one page", mode: "one page",
setBookContextState: (newState: IBookContext)=>{ setBookContextState: (newState: IBookContext) => {
this.setState((oldState: any)=> ({ this.setState((oldState: any) => ({
...oldState, ...oldState,
...newState ...newState
})) }))
}, },
changePage: this.changePage, changePage: this.changePage,
pagesToTurn: 1, pagesToTurn: 1,
} }
} }
changePage = (goToPrevious: boolean, indexToGo?: number)=>{ changePage = (goToPrevious: boolean, indexToGo?: number) => {
const {mode, currIndex} = this.state const { mode, currIndex } = this.state
const pagesCountToTurn = indexToGo || getPagesCountToTurn(mode) const pagesCountToTurn = indexToGo || getPagesCountToTurn(mode)
const prefixPageCount = goToPrevious? -1 : 1 const prefixPageCount = goToPrevious ? -1 : 1
this.setState({ this.setState({
currIndex: (pagesCountToTurn * prefixPageCount) + currIndex, currIndex: (pagesCountToTurn * prefixPageCount) + currIndex,
flagToReverse: goToPrevious flagToReverse: goToPrevious
}) })
} }
componentDidMount(){ componentDidMount() {
fetch('https://picsum.photos/v2/list?limit=30') fetch('https://picsum.photos/v2/list?limit=30')
.then(response=>{ .then(response => {
return response.json() return response.json()
}).then(data=>{ }).then(data => {
data = data.map((item: any)=>{ data = data.map((item: any) => {
return { return {
src: item.download_url, src: item.download_url,
alt: item.author alt: item.author
@ -98,9 +98,9 @@ class BookComponent extends React.Component<any, any>{
}) })
} }
getControlsDisable = ()=>{ getControlsDisable = () => {
const {mode, currIndex, src} = this.state const { mode, currIndex, src } = this.state
const {nextDisable, prevDisable} = getBookViewModes(currIndex, src.length).find(item=> item.value === mode) || { const { nextDisable, prevDisable } = getBookViewModes(currIndex, src.length).find(item => item.value === mode) || {
nextDisable: true, nextDisable: true,
prevDisable: true prevDisable: true
} }
@ -110,21 +110,21 @@ class BookComponent extends React.Component<any, any>{
prevDisable prevDisable
} }
} }
render(){
const {mode} = this.state
return <BookContext.Provider value={{...this.state}}> render() {
const { mode } = this.state
return <BookContext.Provider value={{ ...this.state }}>
<BookContext.Consumer> <BookContext.Consumer>
{state=>( {state => (
<> <>
{mode === "one page" && <OnePageView {...state}/>} {mode === "one page" && <OnePageView {...state} />}
{mode === "two pages" && <TwoPagesView {...state}/>} {mode === "two pages" && <TwoPagesView {...state} />}
<BookComponentsController <BookComponentsController
onPrevClick={()=>{ onPrevClick={() => {
this.changePage(true) this.changePage(true)
}} }}
onNextClick={()=>{ onNextClick={() => {
this.changePage(false) this.changePage(false)
}} }}
{...this.getControlsDisable()} {...this.getControlsDisable()}

View File

@ -0,0 +1,91 @@
import React, { useState, useEffect } from 'react';
import { useTransition, animated } from 'react-spring';
import {
ComponentContainer,
PageComponent,
PageContainer,
} from './OnePageView';
export default function TwoPagesView(props) {
let { src, currIndex, flagToReverse } = props;
const [pagesToshow, setPagesToShow] = useState([
{
src: '',
alt: '',
thumbnail: '',
},
{
src: '',
alt: '',
thumbnail: '',
},
]);
const transitionFirst = useTransition(pagesToshow[0], (item) => item.src, {
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)"},
});
const transitionSecond = useTransition(pagesToshow[1], (item) => 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)"},
});
useEffect(() => {
const shouldShowPage = (pageIndex) => {
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: '',
},
]);
}
}, [currIndex, src]);
return (
<ComponentContainer>
<PageContainer>
{transitionFirst.map(({ item, key, props }) => {
return (
item && (
<animated.div style={{ ...props }} key={key}>
<PageComponent width={'50%'} src={item.src} />
</animated.div>
)
);
})}
{transitionSecond.map(({ item, key, props }) => {
return (
item && (
<animated.div
style={{
...props,
transformOrigin: 'left center',
}}
key={key}
>
<PageComponent width={'50%'} src={item.src} />
</animated.div>
)
);
})}
</PageContainer>
</ComponentContainer>
);
}

View File

@ -1,127 +0,0 @@
import React, {useState, useEffect} from 'react'
import {Transition, animated} from 'react-spring/renderprops'
import {ComponentContainer, PageComponent} from './OnePageView'
import { IBookPage } from './BookComponent'
import styled from 'styled-components'
const PageContainer = styled.div`
height: 600px;
position: relative;
width: 100%;
cursor: pointer;
margin-bottom: 8px;
overflow-x: hidden;
& > div {
will-change: transform, opacity;
position: absolute;
width: 100%;
height: 100%;
}
`
export default function TwoPagesView(props: any) {
let {src, currIndex, flagToReverse} = props
const [pagesToshow, setPagesToShow] = useState<IBookPage[]>([
{
src: '',
alt: '',
thumbnail: '',
},
{
src: '',
alt: '',
thumbnail: '',
}
])
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: '',
}
])
}
}, [currIndex, src])
const firstPageObj = {
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)"},
}
const secondPageObj = {
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: {},
}
return (
<ComponentContainer>
<PageContainer>
<Transition
reset
unique
items={pagesToshow[0]}
{...firstPageObj}
>
{
image=> style=>{
return(
<animated.div style={{
...style,
}}>
{React.createElement(()=>{
return <PageComponent width={"50%"} src={image? image.src: null}/>
})}
</animated.div>
)
}
}
</Transition>
<Transition
reset
unique
items={pagesToshow[1]}
{...secondPageObj}
>
{
image=> style=>{
return(
<animated.div style={{
...style,
}}>
{React.createElement(()=>{
return <PageComponent width={"50%"} src={image? image.src: null}/>
})}
</animated.div>
)
}
}
</Transition>
</PageContainer>
</ComponentContainer>
)
}
interface Book {
name: string
}