11/* eslint-disable @typescript-eslint/no-var-requires */
22/* eslint-disable @typescript-eslint/no-unsafe-member-access */
33import React , { useEffect , useRef , useState } from "react" ;
4- import { CrossFlicking , CrossGroup } from "@egjs/react-flicking" ;
4+ import { CrossFlicking , CrossGroup , DIRECTION } from "@egjs/react-flicking" ;
55import "../../css/demo/crossflicking.css" ;
66
77export default ( ) => {
88 const flicking = useRef < CrossFlicking > ( ) ;
9+ const tabRef = useRef < null [ ] | HTMLDivElement [ ] > ( [ ] ) ;
10+ const [ opacity , setOpacity ] = useState ( 1 ) ;
11+ const [ page , setPage ] = useState ( [ 0 , 0 , 0 , 0 ] ) ;
12+ const [ panelCount , setPanelCount ] = useState ( 4 ) ;
913 const [ transform , setTransform ] = useState ( 0 ) ;
14+ const [ selectedWidth , setSelectedWidth ] = useState ( "" ) ;
1015 const groups = [
1116 {
1217 name : "Spring" ,
@@ -131,12 +136,63 @@ export default () => {
131136 const [ index , setIndex ] = useState ( 0 ) ;
132137
133138 const onChanged = ( e ) => {
139+ const cameraPos = e . currentTarget . camera . position ;
134140 setIndex ( e . index ) ;
141+ setOpacity ( 1 ) ;
142+ setSelectedWidth ( `${ tabRef . current [ e . index ] ?. getBoundingClientRect ( ) . width } px` ) ;
143+ setPanelCount ( groups [ e . index ] . panels . length ) ;
144+ } ;
145+
146+ const onSideChanged = ( e ) => {
147+ setPage ( page . map ( ( prev , i ) => {
148+ if ( i < e . mainIndex ) {
149+ e . index = e . index - groups [ i ] . panels . length ;
150+ } else if ( i === e . mainIndex ) {
151+ return e . index ;
152+ }
153+ return prev ;
154+ } ) ) ;
135155 } ;
136156
137157 const onMove = ( e ) => {
138- const pos = e . currentTarget . camera . _position ;
139- setTransform ( pos / 4.9 - 46 ) ;
158+ const start = tabRef . current [ e . currentTarget . index ] ! . getBoundingClientRect ( ) . x - tabRef . current [ 0 ] ! . getBoundingClientRect ( ) . x ;
159+ const next = e . currentTarget . index + ( e . currentTarget . visiblePanels [ 0 ] . index === e . currentTarget . index ? 1 : - 1 ) ;
160+ if ( next >= 0 && next <= groups . length - 1 ) {
161+ const cameraPos = e . currentTarget . camera . position ;
162+ const visibleLists = e . currentTarget . visiblePanels . map ( p => {
163+ return {
164+ panelIndex : p . index ,
165+ diff : p . position - cameraPos ,
166+ } ;
167+ } ) ;
168+ const size = e . currentTarget . currentPanel . size ;
169+ const half = size / 2 ;
170+ const end = ( tabRef . current [ next ] ! . getBoundingClientRect ( ) . x - tabRef . current [ e . currentTarget . index ] ! . getBoundingClientRect ( ) . x ) ;
171+
172+ const { diff = 0 } = visibleLists . find ( item => item . panelIndex === index ) ?? { } ;
173+ const ratio = Math . max ( - 1 , Math . min ( 1 , Math . abs ( diff / size ) ) ) || 1 ;
174+
175+ if ( e . isTrusted ) {
176+ }
177+ setOpacity ( Math . max ( 0 , Math . min ( 1 , 1 - Math . abs ( diff / half ) ) ) ) ;
178+ setTransform ( ( cameraPos - 200 ) / 5 ) ;
179+ }
180+ } ;
181+
182+ const onSideMove = ( e ) => {
183+ const cameraPos = e . currentTarget . camera . position ;
184+ const visibleLists = e . currentTarget . visiblePanels . map ( p => {
185+ return {
186+ panelIndex : p . index ,
187+ diff : p . position - cameraPos ,
188+ } ;
189+ } ) ;
190+ const size = e . currentTarget . currentPanel . size ;
191+ const half = size / 2 ;
192+
193+ const { diff = 0 } = visibleLists . find ( item => item . panelIndex === index ) ?? { } ; ;
194+
195+ setOpacity ( Math . max ( 0 , Math . min ( 1 , 1 - Math . abs ( diff / half ) ) ) ) ;
140196 } ;
141197
142198 const onTabClick = ( i : number ) => {
@@ -148,18 +204,19 @@ export default () => {
148204
149205 useEffect ( ( ) => {
150206 flicking . current ?. moveTo ( 0 , 0 ) ;
207+ setSelectedWidth ( `${ tabRef . current [ 0 ] ?. getBoundingClientRect ( ) . width } px` ) ;
151208 } , [ ] ) ;
152209
153210 return (
154211 < div className = "demo" >
155212 < div className = "labels" >
156- < a
213+ { selectedWidth && < a
157214 className = "area selected"
158- style = { { transform : `translate(${ transform } px)` } }
215+ style = { { width : selectedWidth , transform : `translate(${ transform } px)` } }
159216 >
160- </ a >
217+ </ a > }
161218 { groups . map ( ( item , i ) => (
162- < div className = "tab" key = { i } >
219+ < div className = "tab" ref = { el => tabRef . current [ i ] = el } key = { i } >
163220 < a
164221 className = { "label " + ( index === i ? "" : "" ) }
165222 onClick = { ( ) => onTabClick ( i ) }
@@ -172,14 +229,17 @@ export default () => {
172229 < CrossFlicking
173230 className = "main"
174231 ref = { flicking }
175- bounce = { 1 }
232+ bounce = { 0. 1}
176233 preventDefaultOnDrag = { true }
177234 moveType = { "strict" }
178235 sideOptions = { {
236+ bounce : 0.1 ,
179237 moveType : "strict" ,
180238 } }
181239 onMove = { onMove }
240+ onSideMove = { onSideMove }
182241 onChanged = { onChanged }
242+ onSideChanged = { onSideChanged }
183243 >
184244 { groups . map ( ( item , i ) => {
185245 return (
@@ -188,21 +248,26 @@ export default () => {
188248 return (
189249 < div className = "item" key = { j } >
190250 < img className = "img scaleup" src = { panel . image } />
191- < div className = "info" >
192- < div className = "name" >
193- < span className = "source" >
194- { item . name } Wallpaper ({ j + 1 } /{ item . panels . length } )
195- </ span >
196- </ div >
197- < strong className = "headline" > { panel . title } </ strong >
198- </ div >
199251 </ div >
200252 ) ;
201253 } ) }
202254 </ CrossGroup >
203255 ) ;
204256 } ) }
205257 </ CrossFlicking >
258+ < div className = "info" style = { { opacity : opacity } } >
259+ < div className = "name" >
260+ < span className = "source" >
261+ { groups [ index ] . name } Wallpaper
262+ </ span >
263+ </ div >
264+ < strong className = "headline" > { groups [ index ] . panels [ page [ index ] ] . title } </ strong >
265+ </ div >
266+ < div className = "page" >
267+ { Array . from ( { length : panelCount } ) . map ( ( _ , i ) => {
268+ return < span key = { i } className = { `dot ${ i === page [ index ] ? "on" : "" } ` } > { i + 1 } </ span > ;
269+ } ) }
270+ </ div >
206271 </ div >
207272 ) ;
208273} ;
0 commit comments