Compare commits
No commits in common. "ef4f0c8bf80ada49418cf4a8ad4fedbfecc077ea" and "0204a379f7f25681a960d726a30675665fad937b" have entirely different histories.
ef4f0c8bf8
...
0204a379f7
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "image-viewer",
|
"name": "image-viewer",
|
||||||
"version": "0.1.3",
|
"version": "0.1.2",
|
||||||
"private": false,
|
"private": false,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import React, {createContext} from 'react'
|
import React, {createContext} from 'react'
|
||||||
import OnePageView from './OnePageView'
|
import OnePageView from './OnePageView'
|
||||||
import TwoPagesView from './TwoPagesView'
|
|
||||||
import BookComponentsController from './BookComponentsController'
|
|
||||||
import './index.css'
|
|
||||||
|
|
||||||
export const BookContext = createContext({})
|
export const BookContext = createContext({})
|
||||||
|
|
||||||
@ -12,22 +9,16 @@ export interface IBookPage {
|
|||||||
thumbnail?: string
|
thumbnail?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getBookViewModes = (currIndex = 0, srcLength = 0)=>[
|
export const bookViewModes = [
|
||||||
{
|
{
|
||||||
text: 'One Page',
|
text: 'One Page',
|
||||||
value: 'one page',
|
value: 'one page',
|
||||||
icon: '',
|
icon: ''
|
||||||
pagesToTurn: 1,
|
|
||||||
nextDisable: currIndex >= srcLength - 1,
|
|
||||||
prevDisable: currIndex === 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Two Pages',
|
text: 'Two Pages',
|
||||||
value: 'two pages',
|
value: 'two pages',
|
||||||
icon: '',
|
icon: ''
|
||||||
pagesToTurn: 2,
|
|
||||||
nextDisable: currIndex >= srcLength - 2,
|
|
||||||
prevDisable: currIndex <= 1,
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -45,12 +36,7 @@ export interface IBookContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const getPagesCountToTurn = (mode: string)=>{
|
class BookComponent extends React.Component<any>{
|
||||||
let pagesToTurn = getBookViewModes().find(item=> item.value === mode)?.pagesToTurn
|
|
||||||
return pagesToTurn || 0
|
|
||||||
}
|
|
||||||
|
|
||||||
class BookComponent extends React.Component<any, any>{
|
|
||||||
constructor(props: any){
|
constructor(props: any){
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -59,25 +45,12 @@ class BookComponent extends React.Component<any, any>{
|
|||||||
flagToReverse: false,
|
flagToReverse: false,
|
||||||
mode: "one page",
|
mode: "one page",
|
||||||
setBookContextState: (newState: IBookContext)=>{
|
setBookContextState: (newState: IBookContext)=>{
|
||||||
this.setState((oldState: any)=> ({
|
this.setState(oldState=> ({
|
||||||
...oldState,
|
...oldState,
|
||||||
...newState
|
...newState
|
||||||
}))
|
}))
|
||||||
},
|
|
||||||
changePage: this.changePage,
|
|
||||||
pagesToTurn: 1,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changePage = (goToPrevious: boolean, indexToGo?: number)=>{
|
|
||||||
const {mode, currIndex} = this.state
|
|
||||||
const pagesCountToTurn = indexToGo || getPagesCountToTurn(mode)
|
|
||||||
const prefixPageCount = goToPrevious? -1 : 1
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
currIndex: (pagesCountToTurn * prefixPageCount) + currIndex,
|
|
||||||
flagToReverse: goToPrevious
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(){
|
componentDidMount(){
|
||||||
@ -98,38 +71,12 @@ class BookComponent extends React.Component<any, any>{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getControlsDisable = ()=>{
|
|
||||||
const {mode, currIndex, src} = this.state
|
|
||||||
const {nextDisable, prevDisable} = getBookViewModes(currIndex, src.length).find(item=> item.value === mode) || {
|
|
||||||
nextDisable: true,
|
|
||||||
prevDisable: true
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
nextDisable,
|
|
||||||
prevDisable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const {mode} = this.state
|
|
||||||
|
|
||||||
return <BookContext.Provider value={{...this.state}}>
|
return <BookContext.Provider value={{...this.state}}>
|
||||||
<BookContext.Consumer>
|
<BookContext.Consumer>
|
||||||
{state=>(
|
{state=>(
|
||||||
<>
|
<>
|
||||||
{mode === "one page" && <OnePageView {...state}/>}
|
<OnePageView {...state}/>
|
||||||
{mode === "two pages" && <TwoPagesView {...state}/>}
|
|
||||||
<BookComponentsController
|
|
||||||
onPrevClick={()=>{
|
|
||||||
this.changePage(true)
|
|
||||||
}}
|
|
||||||
onNextClick={()=>{
|
|
||||||
this.changePage(false)
|
|
||||||
}}
|
|
||||||
{...this.getControlsDisable()}
|
|
||||||
{...this.state}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</BookContext.Consumer>
|
</BookContext.Consumer>
|
||||||
|
@ -1,48 +1,45 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import {Button} from 'antd'
|
import {Button, Popover} from 'antd'
|
||||||
import ViewSwitcher from './ViewSwitcher'
|
import ViewSwitcher from './ViewSwitcher'
|
||||||
import JumpControls from './JumpControls'
|
import JumpControls from './JumpControls'
|
||||||
import {
|
|
||||||
CaretLeftOutlined,
|
|
||||||
CaretRightOutlined,
|
|
||||||
} from '@ant-design/icons';
|
|
||||||
|
|
||||||
const ControlsContanter = styled.div`
|
const ControlsContanter = styled.div`
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 500px;
|
||||||
`
|
`
|
||||||
export default function BookCoponentsController(props: any) {
|
export default function BookCoponentsController(props: any) {
|
||||||
const {onPrevClick, prevDisable, onNextClick, nextDisable, ...restProps} = props
|
const {onPrevClick, prevDisable, onNextClick, nextDisable, ...restProps} = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ControlsContanter>
|
<ControlsContanter>
|
||||||
<JumpControls {...restProps}/>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={()=>{
|
onClick={()=>{
|
||||||
onPrevClick()
|
onPrevClick()
|
||||||
}}
|
}}
|
||||||
disabled={prevDisable}
|
disabled={prevDisable}
|
||||||
style={{
|
>
|
||||||
marginRight: 8
|
Previous
|
||||||
}}
|
</Button>
|
||||||
icon={<CaretLeftOutlined />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={()=>{
|
onClick={()=>{
|
||||||
onNextClick()
|
onNextClick()
|
||||||
}}
|
}}
|
||||||
disabled={nextDisable}
|
disabled={nextDisable}
|
||||||
style={{
|
|
||||||
marginRight: 8
|
|
||||||
}}
|
|
||||||
icon={<CaretRightOutlined />}
|
|
||||||
>
|
>
|
||||||
|
Next
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
|
<Popover
|
||||||
|
trigger="click"
|
||||||
|
content={<JumpControls {...restProps}/>}>
|
||||||
|
<Button>
|
||||||
|
Jump
|
||||||
|
</Button>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
<ViewSwitcher {...restProps}/>
|
<ViewSwitcher {...restProps}/>
|
||||||
|
|
||||||
</ControlsContanter>
|
</ControlsContanter>
|
||||||
|
@ -1,23 +1,14 @@
|
|||||||
import React, {useState, useCallback, useEffect} from 'react'
|
import React, {useState, useCallback, useEffect} from 'react'
|
||||||
import {Slider, InputNumber} from 'antd'
|
import {Row, Col, Slider, InputNumber} from 'antd'
|
||||||
import styled from 'styled-components'
|
|
||||||
|
|
||||||
|
|
||||||
const Container = styled.div`
|
|
||||||
width: 100%;
|
|
||||||
display: inline-flex;
|
|
||||||
`
|
|
||||||
|
|
||||||
const JumpControls = (props: any)=>{
|
const JumpControls = (props: any)=>{
|
||||||
const {src, currIndex, setBookContextState, pagesToTurn} = props
|
const {src, currIndex, setBookContextState} = props
|
||||||
const [inputValue, setInputValue] = useState(currIndex)
|
const [inputValue, setInputValue] = useState(currIndex)
|
||||||
const [sliderValue, setSliderValue] = useState(currIndex)
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(value) => {
|
(value) => {
|
||||||
|
|
||||||
if(value){
|
if(value){
|
||||||
const newCurrIndex = value -1
|
const newCurrIndex = value -1
|
||||||
|
|
||||||
if(newCurrIndex < src.length && newCurrIndex >=0){
|
if(newCurrIndex < src.length && newCurrIndex >=0){
|
||||||
setBookContextState({
|
setBookContextState({
|
||||||
currIndex: value - 1,
|
currIndex: value - 1,
|
||||||
@ -26,43 +17,31 @@ const JumpControls = (props: any)=>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[inputValue, src.length, setBookContextState])
|
[inputValue])
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
setInputValue(currIndex + 1)
|
setInputValue(currIndex + 1)
|
||||||
}, [currIndex])
|
}, [currIndex])
|
||||||
|
|
||||||
useEffect(() => {
|
return <Row>
|
||||||
setSliderValue(inputValue)
|
<Col span={12}>
|
||||||
}, [inputValue])
|
|
||||||
|
|
||||||
|
|
||||||
const sliderRestProps = ()=>{
|
|
||||||
return sliderValue === inputValue? {}: {value: inputValue}
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Container>
|
|
||||||
<Slider
|
<Slider
|
||||||
style={{
|
|
||||||
flexGrow: 1
|
|
||||||
}}
|
|
||||||
min={1}
|
min={1}
|
||||||
max={src.length}
|
max={src.length}
|
||||||
onAfterChange={onChange}
|
onChange={onChange}
|
||||||
step={pagesToTurn}
|
value={typeof inputValue === 'number' ? inputValue : 0}
|
||||||
defaultValue={typeof inputValue === 'number' ? inputValue : 1}
|
|
||||||
{...sliderRestProps()}
|
|
||||||
/>
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={4}>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
className={"jump-control"}
|
|
||||||
min={1}
|
min={1}
|
||||||
max={src.length}
|
max={src.length}
|
||||||
style={{ margin: '0 8px' }}
|
style={{ margin: '0 8px' }}
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Col>
|
||||||
|
</Row>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default JumpControls
|
export default JumpControls
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react'
|
import React, {useState, useCallback, useEffect} from 'react'
|
||||||
import {Transition, animated} from 'react-spring/renderprops'
|
import {Transition, animated} from 'react-spring/renderprops'
|
||||||
import styled, { } from 'styled-components'
|
import styled, { } from 'styled-components'
|
||||||
|
import BookComponentsController from './BookComponentsController'
|
||||||
|
|
||||||
const ComponentContainer = styled.div`
|
const ComponentContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -23,9 +24,10 @@ const PageContainer = styled.div`
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
const StyledImage = styled(animated.div)<{src:string, width:number | string, height: number| string}>`
|
|
||||||
width: ${props=> props.width? props.width: '100%'};
|
const StyledImage = styled(animated.div)<{src:string}>`
|
||||||
height: ${props=> props.height? props.height: '100%'};
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -34,13 +36,30 @@ const StyledImage = styled(animated.div)<{src:string, width:number | string, hei
|
|||||||
`
|
`
|
||||||
|
|
||||||
const PageComponent = (props: any)=>{
|
const PageComponent = (props: any)=>{
|
||||||
const {src, width, height} = props
|
const {src} = props
|
||||||
return <StyledImage src={src} width={width} height={height}/>
|
return <StyledImage src={src}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function BookComponent(props: any) {
|
function BookComponent(props: any) {
|
||||||
const {src, currIndex, flagToReverse} = props
|
const {src, currIndex, setBookContextState, flagToReverse} = 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)
|
||||||
|
setPrevDisable(currIndex <= 0)
|
||||||
|
}, [currIndex, src])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComponentContainer>
|
<ComponentContainer>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
@ -58,6 +77,8 @@ function BookComponent(props: any) {
|
|||||||
return(
|
return(
|
||||||
<animated.div style={{
|
<animated.div style={{
|
||||||
...style,
|
...style,
|
||||||
|
overflowX: 'hidden'
|
||||||
|
|
||||||
}}>
|
}}>
|
||||||
{React.createElement(()=><PageComponent src={src[currIndex]? src[currIndex].src: null}/>)}
|
{React.createElement(()=><PageComponent src={src[currIndex]? src[currIndex].src: null}/>)}
|
||||||
</animated.div>
|
</animated.div>
|
||||||
@ -66,8 +87,17 @@ function BookComponent(props: any) {
|
|||||||
}
|
}
|
||||||
</Transition>
|
</Transition>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
|
|
||||||
|
<BookComponentsController
|
||||||
|
prevDisable={prevDisable}
|
||||||
|
onPrevClick={()=> changePage(-1, true)}
|
||||||
|
nextDisable={nextDisable}
|
||||||
|
onNextClick={()=>changePage(1, false)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
|
||||||
</ComponentContainer>
|
</ComponentContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export {ComponentContainer, PageContainer, PageComponent, BookComponent as default }
|
export default BookComponent
|
@ -1,91 +0,0 @@
|
|||||||
import React, {useState, useEffect} from 'react'
|
|
||||||
import {Transition, animated} from 'react-spring/renderprops'
|
|
||||||
import {ComponentContainer, PageComponent, PageContainer} from './OnePageView'
|
|
||||||
import { IBookContext } from './BookComponent'
|
|
||||||
|
|
||||||
export default function TwoPagesView(props: any) {
|
|
||||||
let {src, currIndex, flagToReverse} = props
|
|
||||||
const [pagesToshow, setPagesToShow] = useState<IBookContext[]>([])
|
|
||||||
|
|
||||||
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])
|
|
||||||
|
|
||||||
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>
|
|
||||||
</ComponentContainer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Book {
|
|
||||||
name: string
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
import React, {useCallback} from 'react'
|
import React, {useCallback} from 'react'
|
||||||
import {Select} from 'antd'
|
import {Select} from 'antd'
|
||||||
import {IBookContext, getBookViewModes} from './BookComponent'
|
import {IBookContext, bookViewModes} from './BookComponent'
|
||||||
|
|
||||||
|
|
||||||
const {Option} = Select
|
const {Option} = Select
|
||||||
@ -10,16 +10,15 @@ export default function ViewSwitcher(props: IBookContext) {
|
|||||||
|
|
||||||
const viewModeChange = useCallback((mode) => {
|
const viewModeChange = useCallback((mode) => {
|
||||||
setBookContextState({
|
setBookContextState({
|
||||||
mode,
|
mode
|
||||||
pagesToTurn: getBookViewModes().find(item=> item.value === mode)?.pagesToTurn || 0
|
|
||||||
})
|
})
|
||||||
},[setBookContextState])
|
},[])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select value={mode} onSelect={viewModeChange}>
|
<Select value={mode} onSelect={viewModeChange}>
|
||||||
{
|
{
|
||||||
getBookViewModes().map((item: any)=>{
|
bookViewModes.map((item: any)=>{
|
||||||
return <Option value={item.value} key={item.value}>{item.text}</Option>
|
return <Option value={item.value}>{item.text}</Option>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
.jump-control .ant-input-number-handler-wrap{
|
|
||||||
display: none;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user