@@ -9,6 +9,8 @@ export interface CarouselProps extends IProps, HTMLDivProps {
9
9
palyTime ?: number ;
10
10
scrollTime ?: number ;
11
11
autoPlay ?: boolean ;
12
+ afterChange ?: ( current : number ) => void ;
13
+ beforeChange ?: ( current : number ) => void ;
12
14
}
13
15
14
16
export interface CarouselRef {
@@ -18,14 +20,16 @@ export interface CarouselRef {
18
20
stopPlay : ( ) => void ;
19
21
}
20
22
21
- function Carousel ( props : CarouselProps , ref : CarouselRef ) {
23
+ function Carousel ( props : CarouselProps , ref : React . ForwardedRef < CarouselRef > ) {
22
24
const {
23
25
position = 0 ,
24
26
width = 400 ,
25
27
height = 200 ,
26
28
palyTime = 2000 ,
27
29
scrollTime = 200 ,
28
30
autoPlay = true ,
31
+ afterChange,
32
+ beforeChange,
29
33
30
34
prefixCls = 'w-carousel' ,
31
35
className,
@@ -35,23 +39,24 @@ function Carousel(props: CarouselProps, ref: CarouselRef) {
35
39
const cls = useMemo ( ( ) => [ prefixCls , className ] . filter ( Boolean ) . join ( ' ' ) . trim ( ) , [ prefixCls , className ] ) ;
36
40
37
41
const [ currentPosition , currentPositionSet ] = useState ( position ) ;
42
+ const [ transitionInner , transitionInnerSet ] = useState ( `${ scrollTime * 0.001 } s ease-in-out` ) ;
38
43
const positionRef = useRef ( currentPosition ) ;
39
- const childCount = React . Children . count ( props . children ) ;
40
- const stopPlay = useRef < Function > ( ( ) => { } ) ;
44
+ const childCount = React . Children . count ( props . children ) + 1 ;
45
+ const stopPlay = useRef ( { stop : ( ) => { } , after : afterChange , before : beforeChange } ) ;
41
46
42
47
React . useImperativeHandle (
43
48
ref ,
44
49
( ) => ( {
45
50
gotoSlide,
46
51
prevSlide : ( ) => gotoSlide ( positionRef . current - 1 ) ,
47
52
nextSlide : ( ) => gotoSlide ( positionRef . current + 1 ) ,
48
- stopPlay : ( ) => stopPlay . current ( ) ,
53
+ stopPlay : ( ) => stopPlay . current . stop ( ) ,
49
54
} ) ,
50
55
[ ref ] ,
51
56
) ;
52
57
53
58
const gotoSlide = ( slidNumber : number ) => {
54
- stopPlay . current ( ) ;
59
+ stopPlay . current . stop ( ) ;
55
60
const maxSlid = childCount - 1 ;
56
61
let slidNumberTemp = slidNumber > maxSlid ? maxSlid : slidNumber ;
57
62
slidNumberTemp = slidNumber < 0 ? 0 : slidNumberTemp ;
@@ -63,13 +68,15 @@ function Carousel(props: CarouselProps, ref: CarouselRef) {
63
68
const play = ( ms : number = palyTime ) => {
64
69
if ( autoPlay ) {
65
70
const time = setInterval ( ( ) => {
71
+ stopPlay . current . after ?.( positionRef . current ) ;
66
72
positionRef . current ++ ;
67
73
if ( positionRef . current >= childCount ) {
68
74
positionRef . current = 0 ;
69
75
}
70
76
currentPositionSet ( positionRef . current ) ;
77
+ stopPlay . current . before ?.( positionRef . current ) ;
71
78
} , ms ) ;
72
- stopPlay . current = ( ) => {
79
+ stopPlay . current . stop = ( ) => {
73
80
clearInterval ( time ) ;
74
81
} ;
75
82
}
@@ -78,23 +85,43 @@ function Carousel(props: CarouselProps, ref: CarouselRef) {
78
85
useEffect ( ( ) => {
79
86
play ( ) ;
80
87
return ( ) => {
81
- stopPlay . current ( ) ;
88
+ stopPlay . current . stop ( ) ;
82
89
} ;
83
90
} , [ autoPlay ] ) ;
84
91
92
+ useEffect ( ( ) => {
93
+ let time : NodeJS . Timeout ;
94
+ if ( childCount === currentPosition + 1 ) {
95
+ time = setTimeout ( ( ) => {
96
+ stopPlay . current . before = ( ) => {
97
+ transitionInnerSet ( `${ scrollTime * 0.001 } s ease-in-out` ) ;
98
+ stopPlay . current . before = props . beforeChange ;
99
+ } ;
100
+ transitionInnerSet ( 'none' ) ;
101
+ gotoSlide ( 0 ) ;
102
+ } , scrollTime ) ;
103
+ }
104
+ return ( ) => {
105
+ clearTimeout ( time ) ;
106
+ } ;
107
+ } , [ currentPosition ] ) ;
108
+
109
+ const childrens = React . Children . map ( props . children , ( child ) => {
110
+ return < div style = { { width, height, ...style } } > { child } </ div > ;
111
+ } ) ;
112
+
85
113
return (
86
114
< div className = { cls } style = { { width, height } } >
87
115
< div
88
116
className = { `${ cls } -content` }
89
117
style = { {
90
118
width : width * childCount ,
91
119
transform : `translate3d(${ - ( currentPosition * width ) } px, 0px, 0px)` ,
92
- transition : ` ${ scrollTime * 0.001 } s ease-in-out` ,
120
+ transition : transitionInner ,
93
121
} }
94
122
>
95
- { React . Children . map ( props . children , ( child ) => {
96
- return < div style = { { width, height, ...style } } > { child } </ div > ;
97
- } ) }
123
+ { childrens }
124
+ < div style = { { width, height, ...style } } > { childrens ?. [ 0 ] } </ div >
98
125
</ div >
99
126
</ div >
100
127
) ;
0 commit comments