X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F20_ui%2F15_ScrollBox.js;h=5e49890b668810226afc62a0017fc1482b257081;hb=3d352d8bf476ab57cc333e8d02d0e6ea5efa69b7;hp=43b57cfabdbe988c2fbaa145b2a133c4960543c6;hpb=136b808d09fef278c92b1c1c2cecf67f1383314d;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/20_ui/15_ScrollBox.js b/0.6.x/js/20_ui/15_ScrollBox.js index 43b57cf..5e49890 100644 --- a/0.6.x/js/20_ui/15_ScrollBox.js +++ b/0.6.x/js/20_ui/15_ScrollBox.js @@ -1,32 +1,5 @@ -function X_UI_ScrollBox_momentum( current, start, time, lowerMargin, wrapperSize, deceleration ){ - var distance = current - start, - speed = Math.abs( distance ) / time, - destination, - duration; - - deceleration = deceleration === undefined ? 0.0006 : deceleration; - - destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); - duration = speed / deceleration; - - if( destination < lowerMargin ){ - destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; - distance = Math.abs( destination - current ); - duration = distance / speed; - } else - if ( destination > 0 ) { - destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; - distance = Math.abs( current ) + destination; - duration = distance / speed; - }; - - return { - destination : Math.round( destination ), - duration : duration - }; -}; var X_UI_ScrollBox_SUPPORT_ATTRS = { // スクロール開始するために必要な移動距離、縦か横、どちらか制限する場合、より重要 @@ -35,7 +8,7 @@ var X_UI_ScrollBox_SUPPORT_ATTRS = { scrollYEnabled : [ true, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], scrollEnabled : [ true, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], bounceEnabled : [ true, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], - bounceTime : [ 600, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.TIME ], + bounceTime : [ 300, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.TIME ], useWheel : [ true, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], useKey : [ true, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], hasScrollShadow : [ true, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.BOOLEAN ], @@ -44,8 +17,10 @@ var X_UI_ScrollBox_SUPPORT_ATTRS = { var XUI_ScrollBox = XUI_ChromeBox.inherits( '_ScrollBox', - X_Class.PRIVATE_DATA, + X_Class.NONE, { + layout : XUI_Layout_Canvas, + directionLockThreshold : 10, scrollXEnabled : true, scrollYEnabled : true, @@ -58,8 +33,6 @@ var XUI_ScrollBox = XUI_ChromeBox.inherits( hasScrollShadow : true, scrollShadowColor : '#000', - supportAttrs : XUI_Attr_createAttrDef( XUI_Attr_Support, X_UI_ScrollBox_SUPPORT_ATTRS ), - scrolling : false, initiated : '', @@ -67,7 +40,6 @@ var XUI_ScrollBox = XUI_ChromeBox.inherits( directionLocked : '', startTime : 0, endTime : 0, - isAnimating : false, isInTransition : false, hasHScroll : false, @@ -104,9 +76,9 @@ var XUI_ScrollBox = XUI_ChromeBox.inherits( _containerNode : null, xnodeSlider : null, - Constructor : function( layout, args ){ - this[ 'Super' ]( layout, args ); - this._containerNode = X_Class_getPrivate( this.containerNode ); + Constructor : function( user, layout, args ){ + this[ 'Super' ]( user, layout, args ); + this._containerNode = X_Pair_get( this.containerNode ); this.xnodeSlider = this._containerNode.xnode[ 'className' ]( 'ScrollSlider' ).listen( X_EVENT_ANIME_END, this, X_UI_ScrollBox_onAnimeEnd ); this.xnode[ 'className' ]( 'ScrollBox' ); }, @@ -160,24 +132,24 @@ var XUI_ScrollBox = XUI_ChromeBox.inherits( function X_UI_ScrollBox_onLayoutBefore( e ){ if( e[ 'cancelable' ] && this.isInTransition && X_Node_Anime_translateZ ){ this[ 'listenOnce' ]( XUI_Event.SCROLL_END, X_UI_rootData, X_UI_rootData.calculate ); - return X_Callback_PREVENT_DEFAULT; + return X_CALLBACK_PREVENT_DEFAULT; }; this.scrollXRatio = this.scrollX ? this.scrollXMax / this.scrollX : 0; this.scrollYRatio = this.scrollY ? this.scrollYMax / this.scrollY : 0; this.xnodeSlider.stop(); this.isInTransition = false; - return X_Callback_NONE; + return X_CALLBACK_NONE; }; function X_UI_ScrollBox_onLayoutComplete( e ){ // scroll の停止、GPU の解除 var font = this.fontSize = this.xnodeSlider.call( 'fontSize' ); - - this.scrollXMax = ( this.boxWidth - this._containerNode.boxWidth ) * font; - this.scrollYMax = ( this.boxHeight - this._containerNode.boxHeight ) * font; - this.hasHScroll = this.scrollXEnabled && this.scrollXMax < 0; - this.hasVScroll = this.scrollYEnabled && this.scrollYMax < 0; + this.scrollXMax = ( this.boxWidth - this._containerNode.boxWidth ) * font | 0; + this.scrollYMax = ( this.boxHeight - this._containerNode.boxHeight ) * font | 0; + + this.hasHScroll = this.scrollXEnabled && ( this.scrollXMax < -1 ); // < 0 だと + this.hasVScroll = this.scrollYEnabled && ( this.scrollYMax < -1 ); if( !this.hasHScroll ){ this.scrollXMax = 0; @@ -250,7 +222,7 @@ function X_UI_ScrollBox_onLayoutComplete( e ){ }; function X_UI_ScrollBox_onStart( e ){ - var ret = X_Callback_NONE; + var ret = X_CALLBACK_NONE; // React to left mouse button only if( e.pointerType === 'mouse' && e.button !== 0 ){ @@ -271,9 +243,10 @@ function X_UI_ScrollBox_onStart( e ){ this.startTime = X_Timer_now(); // スクロール中の停止 - if( this.isInTransition || this.isAnimating ){ - this.isInTransition = this.isAnimating = false; + if( this.isInTransition ){ + this.isInTransition = false; this[ 'dispatch' ]( XUI_Event.SCROLL_END ); + // TODO current位置 this.xnodeSlider.stop(); }; @@ -284,19 +257,23 @@ function X_UI_ScrollBox_onStart( e ){ this.pointX = e.pageX; this.pointY = e.pageY; + console.log( 'scrollstart ' + e.pageY ); + this[ 'listen' ]( XUI_Event._POINTER_MOVE, this, X_UI_ScrollBox_onMove ); this[ 'listen' ]( [ XUI_Event._POINTER_UP, XUI_Event._POINTER_CANCEL ], this, X_UI_ScrollBox_onEnd ); - return ret | X_Callback_PREVENT_DEFAULT; + return ret | X_CALLBACK_PREVENT_DEFAULT; }; function X_UI_ScrollBox_onMove( e ){ - var ret = X_Callback_NONE, + var ret = X_CALLBACK_NONE, deltaX, deltaY, timestamp, newX, newY, absDistX, absDistY; // 規定以上の move でスクロール開始 - + +//console.log( 'scrollmove ' + e.buttons + ' ' + e.button ); + if( !this.scrollEnabled || e.pointerType !== this.initiated ){ return ret; }; @@ -386,11 +363,11 @@ function X_UI_ScrollBox_onMove( e ){ this.startY = this.scrollY; }; // イベントの拘束 - return ret | X_Callback_PREVENT_DEFAULT | X_Callback_CAPTURE_POINTER; + return ret | X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_CAPTURE_POINTER; }; function X_UI_ScrollBox_onEnd( e ){ - var ret = X_Callback_NONE, + var ret = X_CALLBACK_NONE, time = 0, easing = '', newX, newY, @@ -422,7 +399,7 @@ function X_UI_ScrollBox_onEnd( e ){ // we scrolled less than 10 pixels if( !this.moved ){ // this[ 'dispatch' ]( X_EVENT_CANCELED ); - console.log( 'we scrolled less than 10 pixels' ); + console.log( 'we scrolled less than 10 pixels ' + e.pageY ); return ret; }; @@ -486,8 +463,8 @@ function X_UI_ScrollBox_resetPosition( that, time ){ return false; }; - //console.log( 'バウンド!' ); - //console.log( 'rese x:' + x + ' y:' + y ); + console.log( ' ===> resetPosition - バウンド!' ); + console.log( ' x:' + x + ' y:' + y ); that.scrollTo( x, y, time, that.bounceEasing, 1000 ); return true; @@ -495,61 +472,96 @@ function X_UI_ScrollBox_resetPosition( that, time ){ function X_UI_ScrollBox_onAnimeEnd( e ){ if( e.target !== this.xnodeSlider || !this.isInTransition ){ - return X_Callback_NONE; + return X_CALLBACK_NONE; }; if( !X_UI_ScrollBox_resetPosition( this, this.bounceTime ) ){ this.isInTransition = false; - this.dispatch( XUI_Event.SCROLL_END ); + this[ 'dispatch' ]( XUI_Event.SCROLL_END ); + }; + return X_CALLBACK_NONE; +}; + +function X_UI_ScrollBox_momentum( current, start, time, lowerMargin, wrapperSize, deceleration ){ + var distance = current - start, + speed = Math.abs( distance ) / time, + destination, + duration; + + deceleration = deceleration === undefined ? 0.0006 : deceleration; + + destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); + duration = speed / deceleration; + + if( destination < lowerMargin ){ + destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; + distance = Math.abs( destination - current ); + duration = distance / speed; + } else + if ( destination > 0 ) { + destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; + distance = Math.abs( current ) + destination; + duration = distance / speed; + }; + + return { + destination : Math.round( destination ), + duration : duration }; - return X_Callback_NONE; }; X.UI.ScrollBox = X.UI.ChromeBox.inherits( 'ScrollBox', X_Class.NONE, - XUI_ScrollBox, { Constructor : function(){ + var supports, slider; + + if( XUI_ScrollBox.prototype.usableAttrs === XUI_ChromeBox.prototype.usableAttrs ){ + XUI_ScrollBox.prototype.usableAttrs = supports = XUI_Attr_createAttrDef( XUI_Attr_Support, X_UI_ScrollBox_SUPPORT_ATTRS ); + + XUI_ScrollBox.prototype.attrClass = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports, { width : '100%', height : '100%', bgColor : 0x111111 } ); + }; + var args = [ XUI_Layout_Vertical, { - name : 'ScrollBox-Scroller', - role : 'container', - width : 'auto', - minWidth : '100%', - height : 'auto', - minHeight : '100%' + name : 'ScrollBox-Scroller', + role : 'container', + width : 'auto', + minWidth : '100%', + height : 'auto', + minHeight : '100%' } ], i = arguments.length, - arg, layout, attr; + arg, attr; for( ; i; ){ arg = arguments[ --i ]; if( arg[ 'instanceOf' ] && arg[ 'instanceOf' ]( XUI_LayoutBase ) ){ - layout = arg; + args[ 0 ] = arg; } else if( arg[ 'instanceOf' ] && arg[ 'instanceOf' ]( X.UI.AbstractUINode ) ){ args[ args.length ] = arg; } else if( X_Type_isObject( arg ) ){ - attr = arg; + args[ args.length ] = attr = arg; + slider = attr.scrollSlider; }; }; - X_Class_newPrivate( + X_Pair_create( this, - XUI_Layout_Canvas, - [ - { - width : '100%', - height : '100%' - }, - X.UI.VBox.apply( 0, args ) - ] + XUI_ScrollBox( + this, + null, + [ + slider || X.UI.VBox.apply( 0, args ) + ] + ) ); - attr && this.attr( attr ); + //attr && this.attr( attr ); }, scrollX : function(){ @@ -567,4 +579,5 @@ X.UI.ScrollBox = X.UI.ChromeBox.inherits( } } -); \ No newline at end of file +); +