翻书效果
react+ts实现一个翻书效果。
import { Button, Modal, } from 'antd'; import { Component, Fragment } from 'react'; import type { Dispatch } from 'redux'; import logOneUrl from '@/assets/malicious/log/0321.jpg'; import logTowUrl from '@/assets/malicious/log/0401.jpg'; import logThreeUrl from '@/assets/malicious/log/0507.jpg'; import logFourUrl from '@/assets/malicious/log/0521.jpg'; import '../css/clickButton.less'; interface ClickProps { dashboardAnalysis?: any; dispatch?: Dispatch<any>; loading?: boolean; style: any; url: string; message: string; setCheckNumber: any; type?: string; addPck?: any; checkNumber: number } interface ClickState { salesType: 'all' | 'online' | 'stores'; currentTabKey: string; isChecked: boolean, imgId: number, imgAll: string[], visible: boolean, pnum: number, bnum: number, } class ClickButton extends Component< ClickProps, ClickState > { state: ClickState = { salesType: 'all', currentTabKey: '', isChecked: true, imgId: 0, imgAll:[logOneUrl,logTowUrl,logThreeUrl,logFourUrl], visible:false, pnum:1, bnum:1, }; handleOk = () => { this.setState({ visible: false, }); }; handleCancel = () => { this.setState({ visible: false, }); }; contentDetail = ( ) =>{ const { url } = this.props; const { imgId,imgAll, pnum, bnum} = this.state; return( <ul className='logBox'> <li className='logImgBox'><img id="urlBox" src={url} /></li> <li id="beforePage" /> <li id="behindPage" /> <li style={{ position: 'absolute', left: 0, top: 200,width:120, }} onClick={()=>{ const prePage=document.getElementById('prePage') as HTMLElement; if(imgId>0){ const id=imgId-1; this.setState({imgId:id,pnum:pnum+1}); const urlBox=document.getElementById('urlBox') as HTMLImageElement; const behindPage=document.getElementById('behindPage') as HTMLElement; prePage.setAttribute("disabled",String(true)); behindPage.style.transform=`rotateY(${360*pnum-355}deg)`; behindPage.style.transition='2s'; // behindPage.style.opacity="0"; setTimeout(function(){ urlBox.src=imgAll[id]; },100) setTimeout(function(){ behindPage.style.transition='0.1s'; behindPage.style.transform=`rotateY(${360*pnum-185}deg)`; prePage.removeAttribute("disabled"); // if(imgId>1){ // prePage.removeAttribute("disabled"); // } },2100) } }} > <Button size="small" id="prePage">上一页</Button> </li> <li style={{ position: 'absolute', left: 560, top: 200,width:80, }} onClick={()=>{ if(imgId<3){ const id=imgId+1; this.setState({imgId:id,bnum:bnum+1}); const beforePage=document.getElementById('beforePage') as HTMLElement; const urlBox=document.getElementById('urlBox') as HTMLImageElement; const nextPage=document.getElementById('nextPage') as HTMLElement; nextPage.setAttribute("disabled",String(true)); beforePage.style.transform=`rotateY(${175-360*bnum}deg)`; beforePage.style.transition='2s'; // beforePage.style.opacity='0'; setTimeout(function(){ urlBox.src=imgAll[id]; },1000) setTimeout(function(){ beforePage.style.transition='0.1s'; beforePage.style.transform=`rotateY(${5-360*bnum}deg)`; nextPage.removeAttribute("disabled"); },2100) } }} > <Button size="small" id="nextPage">下一页</Button> </li> </ul> ) } changeChecked = () => { this.setState({visible:true}) }; render() { const { isChecked } = this.state; const { message, style } = this.props; const { visible } = this.state; return ( <Fragment> {isChecked ? ( <Button style={style} onClick={this.changeChecked}> {message} </Button> ) : ""} <Modal width={680} style={{ top: 100 }} visible={visible} onOk={this.handleOk} onCancel={this.handleCancel} maskClosable={false} closable={false} footer={[ <Button key={'button'} onClick={this.handleOk} style={{ background: '#fd7602', border: 0,color: '#fff' }}>我知道了</Button> ]} > { this.contentDetail() } </Modal> </Fragment> ); } } export default ClickButton;
less样式
.logBox{ padding: 30px 0 0; perspective:500px; transform-style:preserve-3d; .logImgBox{ width: 500px; height: 360px; margin: 0 auto; img{ width: auto; height: auto; max-width: 500px; max-height: 360px; } } li:nth-of-type(2){ width:33%; height:326px; position:absolute; left:49.3%; top:42px; background:url('/puzzle_game/MaliciousGame/dataLog/base.png') no-repeat center; background-size: 206px 324px; border:1px solid lightgray; border-radius:0 5px 5px 0; transform-origin:left; transition: 1s; box-shadow:0 1px 1px lightgray; background-color:#FAF1EA; transform:rotateY(-5deg) } li:nth-of-type(3){ width:33%; height:326px; position:absolute; left:49.3%; top:42px; //background:liner-gradient(to right,white,pink); background:url('/puzzle_game/MaliciousGame/dataLog/base.png') no-repeat center; background-size: 206px 324px; border:1px solid lightgray; border-radius:0 5px 5px 0; transform-origin:left; transition:0s; box-shadow:0 1px 1px lightgray; //background-color:#FF99CC; transform:rotateY(-185deg); } }