Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8640

よく使う画面遷移のCSS

$
0
0

iosにありがちなモーダルの遷移とプッシュの遷移のサンプル

デモ
https://nakadoribooks.github.io/modal_and_push/

page.gif

使うもの

create-react-app
styled-components

コード

  • styleの定義
  • Reactの実装

スタイル

アニメーションはだいたいこのくらい

duration: 600
ease: 'cubic-bezier(.17,.71,0,1)'

styles.js
importReactfrom'react';importstyledfrom'styled-components';constsizes={headerHeight:72}// だいたいこのくらいconstanimation={page:{duration:600,ease:'cubic-bezier(.17,.71,0,1)'},}animation.page.transition=`transform ${animation.page.duration}ms ${animation.page.ease}, opacity ${animation.page.duration}ms ${animation.page.ease}`constcolors={primary:"#3880ff",secondary:"#0cd1e8",border:"#eeeeee",white:"#ffffff",black:"#000000",}constHeader=styled.div`
  width: 100%;
  padding:0px 20px;
  position:absolute;
  height: ${sizes.headerHeight}px;
  border-bottom:1px solid ${colors.border};
  background-color:${colors.white};
  padding-top:1px;
  justify-content:space-between;
  display:flex;
  align-items:center;
  box-shadow: 0 2px 2px rgba(200,200,200,.1);

  h1{
    font-size:20px;
  }
`constHeaderButton=styled.a`
  display:inline-block;
  height:40px;
  font-size:14px;
  line-height:38px;
  border: 1px solid ${colors.primary};
  border-radius:5px;
  color:${colors.primary};
  padding:0px 20px;
  min-width: 100px;
  text-align:center;
  cursor:pointer;
  :hover{
    background-color:${colors.primary};
    color:${colors.white};
  }
`constHeaderSpace=styled.div`
  width:100px;
`constRootView=styled.div``constPageWrapper=styled.div`
  position:fixed;
  top:0px;left:0px;right:0px;bottom:0px;
`// 後ろにある半透明の黒constBehindLayer=styled.div`
  background-color:${colors.black};
  opacity: 0;
  position:absolute;
  top:0px;left:0px;right:0px;bottom:0px;
  transition: opacity ${animation.page.duration}ms ease;
  ${(props)=>props.showed&&`
    opacity:0.3;
  `}
`constPageContainer=styled.div`
  height:100%;
  position:relative;
  top:0px;
  transition: ${animation.page.transition};
`constRootContainer=styled(PageContainer)`

  /* 上にモーダルきた時に少しちっさくなるやつ */
  ${props=>props.modaling&&`
    transform: scale(0.99)
  `}

  /* プッシュされた時につこし左に行くやつ */
  ${props=>props.pushing&&`
    transform: translateX(-10vh)
  `}
`constModalContainer=styled(PageContainer)`
  transform: translateY(100vh);
  ${props=>props.showed&&`
    transform: translateY(0vh);
  `}
`constPushContainer=styled(PageContainer)`
  transform: translateX(50vh);
  opacity: 0;
  ${props=>props.showed&&`
    opacity: 1.0;
    transform: translateX(0vh);
  `}
`constPageContents=styled.div`
  height:calc(100vh - ${sizes.headerHeight}px);
  position:relative;
  top:${sizes.headerHeight}px;
  overflow-y:scroll;
  background-color:${colors.white};
`constLinkButton=styled.p`
  text-align:center;
  a{
    display:inline-block;
    padding:10px 20px;
    border-radius: 10px;
    border: 1px solid ${colors.border};
    cursor:pointer;
    transition: background-color 300ms ease, transform 300ms ease;
    :hover{
      opacity: 0.7;
    }
  } 

  /* フォーカス残るよう */
  ${props=>props.focus&&`
    a{
      background-color:${colors.border};
      transofrm:scale(0.99);
    }
  `}
`constCenterContainer=styled.div`
  width:100%;
  height:100%;
  display: flex;
  justify-content: center;
  align-items: center;
`export{animation,Header,HeaderButton,HeaderSpace,RootView,PageWrapper,BehindLayer,RootContainer,ModalContainer,PushContainer,PageContents,LinkButton,CenterContainer}

React 実装

遷移先は didMountで少し遅らせてアニメーション表示

setTimeout(()=>{this.setState({showed:true})},10)

遷移元は アニメーション中のフラグとmodal/pushを表示する用のフラグ二つづつもつ。

const {modaling, pushing, showingModal, showingPush} = this.state

App.js
importReactfrom'react';import{animation,Header,HeaderButton,HeaderSpace,RootView,PageWrapper,BehindLayer,RootContainer,ModalContainer,PushContainer,PageContents,LinkButton,CenterContainer}from'./styles'classModalPageextendsReact.Component{state={showed:false}componentDidMount(){// アニメーションで表示setTimeout(()=>{this.setState({showed:true})},10)}render=()=>{const{showed}=this.statereturn<PageWrapper><BehindLayershowed={showed}/>
<ModalContainershowed={showed}><Header><HeaderButtononClick={this.handleClickClose}>閉じる</HeaderButton>
<h1>モーダル</h1>
<HeaderSpace/></Header>
<PageContents><CenterContainer><h1>モーダル</h1>
</CenterContainer>
</PageContents>
</ModalContainer>
</PageWrapper>
}handleClickClose=(event)=>{this.setState({showed:false})this.props.onClose()}}classPushPageextendsReact.Component{state={showed:false}componentDidMount(){// アニメーションで表示setTimeout(()=>{this.setState({showed:true})},10)}render=()=>{const{showed}=this.statereturn<PageWrapper><BehindLayershowed={showed}/>
<PushContainershowed={showed}><Header><HeaderButtononClick={this.handleClickClose}>戻る</HeaderButton>
<h1>プッシュ</h1>
<HeaderSpace/></Header>
<PageContents><CenterContainer><h1>プッシュ</h1>
</CenterContainer>
</PageContents>
</PushContainer>
</PageWrapper>
}handleClickClose=(event)=>{this.setState({showed:false})this.props.onBack()}}classAppextendsReact.Component{state={pushing:false,modaling:false,showingModal:false,showingPush:false}render=()=>{const{modaling,pushing,showingModal,showingPush}=this.statereturn<RootView><PageWrapper><RootContainermodaling={modaling}pushing={pushing}><Header><div/><h1>ページ遷移サンプル</h1><div /></Header>
<PageContents><CenterContainer><div>{/* 戻ってきた時に分かりやすいようにフォーカスを残しておく */}<LinkButtonfocus={showingModal}><aonClick={this.handleClickModal}>モーダル</a></LinkButton><LinkButtonfocus={showingPush}><aonClick={this.handleClickPush}>プッシュ</a></LinkButton></div>
</CenterContainer>
</PageContents>
</RootContainer>
</PageWrapper>
{showingModal&&<ModalPageonClose={this.handleCloseModal}/>}
{showingPush&&<PushPageonBack={this.handleBackPush}/>}
</RootView>
}handleClickModal=(event)=>{this.setState({modaling:true,showingModal:true})}handleClickPush=(event)=>{this.setState({pushing:true,showingPush:true})}handleCloseModal=(event)=>{this.setState({modaling:false})setTimeout(()=>{this.setState({showingModal:false})},animation.page.duration)}handleBackPush=(event)=>{this.setState({pushing:false})setTimeout(()=>{this.setState({showingPush:false})},animation.page.duration)}}exportdefaultApp;

Viewing all articles
Browse latest Browse all 8640

Trending Articles