@@ -7,46 +7,7 @@ var TransitionGroup = React.addons.TransitionGroup;
77var Transitionable = require ( './TransitionableBank' ) ;
88var RAFList = require ( './RAFList' ) ;
99
10- var SubContainer = React . createClass ( {
11- displayName : 'React-Infinity' ,
12- getInitialState : function ( ) {
13- return {
14- transform : this . props . transform + ' scale(1)' ,
15- opacity : '0'
16- } ;
17- } ,
18- componentDidMount : function ( argument ) {
19- this . setState ( { transform : this . props . transform + ' scale(1)' , opacity : '1' } ) ;
20- } ,
21- componentWillReceiveProps : function ( newProps ) {
22- this . setState ( { transform : newProps . transform + ' scale(1)' } ) ;
23- } ,
24- componentWillEnter : function ( cb ) {
25- this . setState ( { transform : this . props . transform + ' scale(1)' , opacity : '0' } ) ;
26- setTimeout ( cb , 100 ) ;
27- } ,
28- componentDidEnter : function ( ) {
29- this . setState ( { transform : this . props . transform + ' scale(1)' , opacity : '1' } ) ;
30- } ,
31- componentWillLeave : function ( cb ) {
32- this . setState ( { transform : this . props . transform + ' scale(1)' , opacity : '0' } ) ;
33- setTimeout ( cb , 400 ) ;
34- } ,
35- render : function ( ) {
36- return React . DOM . div ( { style : s ( {
37- position : 'absolute' ,
38- top : '0' ,
39- left : '0' ,
40- transform : this . state . transform ,
41- width : this . props . width ,
42- height : this . props . height ,
43- transition : this . props . transition ,
44- opacity : this . state . opacity
45- } ) } ,
46- this . props . children
47- ) ;
48- }
49- } ) ;
10+ var SubContainer = require ( './SubContainer' ) ;
5011
5112/*
5213- The properties I can expect:
@@ -92,7 +53,8 @@ var Infinite = React.createClass({
9253 mobileWidth : 480 ,
9354 justifyOnMobile : true ,
9455 margin : 0 ,
95- scrollDelta : 0
56+ scrollDelta : 0 ,
57+ direction : 'vertical'
9658 } ;
9759 } ,
9860
@@ -128,18 +90,9 @@ var Infinite = React.createClass({
12890
12991 componentDidMount : function ( ) {
13092
131- // this.onResize = this.onResize.bind(this);
132- // this.onScroll = this.onScroll.bind(this);
133-
13493 global . addEventListener ( 'resize' , this . onResize ) ;
13594
13695 RAFList . bind ( this . onScroll ) ;
137- //this.props.scrollContainer.addEventListener('scroll', this.onScroll);
138-
139- // this.props.scrollContainer.addEventListener('touchstart', this.onTouchStart);
140- // this.props.scrollContainer.addEventListener('touchmove', this.onTouchMove);
141- // this.props.scrollContainer.addEventListener('touchend', this.onTouchEnd);
142- // Causes Bad performance for now.
14396
14497 this . setState ( {
14598 loaded : true ,
@@ -158,7 +111,7 @@ var Infinite = React.createClass({
158111 // move some logic here for visible element calculation.
159112
160113 // set flag for animation off
161- if ( this . state . extra . count % 20 === 0 ) {
114+ if ( this . state . extra . count % 5 === 0 ) {
162115 var scrollTop = this . state . transitionable . get ( ) ;
163116 if ( this . state . scrollTop !== scrollTop ) {
164117 this . setState ( { scrollTop : scrollTop } ) ;
@@ -168,57 +121,16 @@ var Infinite = React.createClass({
168121
169122 } ,
170123
171- // onTouchStart: function (evt) {
172- // var startY = evt.touches[0].pageY;
173- // this.setState({
174- // startY: startY,
175- // startScrollTop: this.state.scrollTop
176- // });
177-
178- // },
179- // onTouchMove: function (evt) {
180-
181- // var newY = evt.touches[0].pageY;
182- // var delta = this.state.startY - newY;
183-
184- // if(this.state.scrollTop === this.state.startScrollTop){
185- // this.setState({
186- // scrollDelta: delta
187- // });
188- // }
189-
190- // },
191- // onTouchEnd: function (evt) {
192- // console.log(":( oh god, no more control!");
193- // },
194-
195- // willReceiveProps: function (argument) {
196- // // set flag for animation on. Filtering content is completely external.
197- // },
198-
199124 onResize : function ( ) {
200125 this . setState ( { windowHeight : global . innerHeight , windowWidth : global . innerWidth } ) ;
201126 } ,
202127
203128 componentWillUnmount : function ( ) {
204129 global . removeListener ( 'resize' , this . onResize ) ;
205130 RAFList . unbind ( this . onScroll ) ;
206- //this.props.scrollContainer.removeEventListener('scroll', this.onResize);
207-
208- // this.props.scrollContainer.removeEventListener('touchstart', this.onTouchStart);
209- // this.props.scrollContainer.removeEventListener('touchmove', this.onTouchMove);
210- // this.props.scrollContainer.removeEventListener('touchend', this.onTouchEnd);
211131 } ,
212132
213- render : function ( ) {
214- if ( this . state . loaded === false ) {
215- return React . DOM . div ( { className : 'infinite-container' , style : { fontSize : '0' , position : 'relative' , textAlign : this . props . align } } ,
216- this . props . data . map ( function ( elementData , i ) {
217- return React . DOM [ this . props . component ] ( { style : { display : 'inline-block' , margin : '32px' , verticalAlign : 'top' } } , this . props . childComponent ( elementData ) ) ;
218- } . bind ( this ) )
219- ) ;
220- }
221-
133+ vertical : function ( ) {
222134 var windowWidth = this . state . windowWidth ;
223135 var windowHeight = this . state . windowHeight ;
224136
@@ -267,6 +179,76 @@ var Infinite = React.createClass({
267179 } ,
268180 TransitionGroup ( null , elementsToRender )
269181 ) ;
182+ } ,
183+
184+ horizontal : function ( ) {
185+ var windowWidth = this . state . windowWidth ;
186+ var windowHeight = this . state . windowHeight ;
187+
188+ var elementWidth = this . props . mobileWidth <= windowWidth ? this . props . elementWidth : this . props . elementMobileWidth ;
189+ var elementHeight = this . props . mobileWidth <= windowWidth ? this . props . elementHeight : this . props . elementMobileHeight ;
190+ var margin = this . props . margin ;
191+
192+ if ( ! ! this . props . justifyOnMobile && this . props . mobileWidth > windowWidth ) {
193+ elementHeight = windowHeight ;
194+ margin = 0 ;
195+ }
196+
197+ var elementsPerColumn = Math . max ( 1 , Math . floor ( ( windowHeight - margin ) / ( elementHeight + margin ) ) ) ;
198+ var extraSpace = windowHeight - elementsPerColumn * ( elementHeight + margin ) + margin ;
199+ var offset = this . props . align === 'left' ? 0 :
200+ this . props . align === 'center' ? Math . round ( extraSpace / 2 ) : extraSpace ;
201+
202+ var scrollLeft = this . state . scrollTop + this . state . scrollDelta ;
203+ var columnsToLeft = Math . floor ( ( scrollLeft - margin ) / ( elementHeight + margin ) ) ;
204+ var visibleColumns = Math . ceil ( ( ( columnsToLeft * ( elementWidth + margin ) ) + windowWidth ) / ( elementWidth + margin ) ) ;
205+
206+ var extra = elementsPerColumn === 1 ? Math . ceil ( visibleColumns / 2 ) : 2 ;
207+ var lowerLimit = ( columnsToLeft - extra ) * elementsPerColumn ;
208+ var higherLimit = ( visibleColumns + extra * 2 ) * elementsPerColumn ;
209+
210+ var elementsToRender = [ ] ;
211+
212+ this . props . data . forEach ( function ( obj , index ) {
213+ if ( index >= lowerLimit && index < higherLimit ) {
214+ var row = index % elementsPerColumn ;
215+ var column = Math . floor ( index / elementsPerColumn ) ;
216+ elementsToRender . push ( SubContainer ( {
217+ key : obj . id || obj . _id ,
218+ transform : 'translate(' + ( offset + column * ( elementWidth + margin ) ) + 'px, ' + ( margin + row * ( elementHeight + margin ) ) + 'px)' ,
219+ width : elementWidth + 'px' ,
220+ height : elementHeight + 'px' ,
221+ transition : this . props . transition
222+ } , this . props . childComponent ( obj ) ) ) ;
223+ }
224+ } . bind ( this ) ) ;
225+
226+ return React . DOM . div ( { className : 'infinite-container' , style : {
227+ height : ( margin + ( elementHeight + margin ) * Math . ceil ( this . props . data . length / elementsPerColumn ) ) + 'px' ,
228+ width : '100%' ,
229+ position : 'relative' }
230+ } ,
231+ TransitionGroup ( null , elementsToRender )
232+ ) ;
233+ } ,
234+
235+ render : function ( ) {
236+ if ( this . state . loaded === false ) {
237+ return React . DOM . div ( { className : 'infinite-container' , style : { fontSize : '0' , position : 'relative' , textAlign : this . props . align } } ,
238+ this . props . data . map ( function ( elementData , i ) {
239+ return React . DOM [ this . props . component ] ( { style : { display : 'inline-block' , margin : '32px' , verticalAlign : 'top' } } , this . props . childComponent ( elementData ) ) ;
240+ } . bind ( this ) )
241+ ) ;
242+ }
243+
244+ if ( this . props . direction === 'horizontal' ) {
245+ return this . horizontal ( ) ;
246+ } else if ( this . props . direction === 'vertical' ) {
247+ return this . vertical ( ) ;
248+ } else {
249+ console . warn ( 'the prop `direction` must be either "vertical" or "horizontal". It is set to' , this . props . direction ) ;
250+ return this . vertical ( ) ;
251+ }
270252
271253 }
272254
0 commit comments