OSDN Git Service

3bcc3b8f66073cde781a577e73310448a21138ad
[pettanr/clientJs.git] / 0.6.x / js / 06_net / 04_XNetImage.js
1 //{+netimage"画像の読み込み監視"(Imageの読み込みを監視し画像表示のコントロールを行う)[+net,+utilimage]\r
2 /* \r
3  * original\r
4  *  LICENSE: MIT?\r
5  *  URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631\r
6  *  AUTHOR: uupaa.js@gmail.com\r
7  * \r
8  */\r
9 var X_ImgLoader_image     = window[ 'Image' ] && new Image(),\r
10         // IE では厳密には HTMLImageElement ではなく、appendChild してもサイズが取れず、removeChild に失敗する\r
11         X_ImgLoader_isElement = !( X_UA[ 'IE' ] < 9 ) && X_Type_isHTMLElement( X_ImgLoader_image ),\r
12         // http://uupaa.hatenablog.com/entry/2013/12/17/171809\r
13         // お手軽に画像の読み込みをハンドリングする、今どきな方法\r
14         X_ImgLoader_0forError = !X_UA[ 'IE' ] || X_UA[ 'IE' ] === 11;\r
15 \r
16 /*\r
17  * TODO\r
18  * new Image() のときに Image オブジェクトを作るもの(IE8-)と、HTMLImageElement を作るものがある。\r
19  * Image は、X.EventDispatcher で、<img> は X.Node で。 \r
20  */\r
21 \r
22 X_TEMP.X_ImgLoader_init = function(){\r
23         X_ImgLoader = X_Class_override(\r
24                 X_ImgLoader_isElement ? Node( X_ImgLoader_image ) : X_EventDispatcher( X_ImgLoader_image ),\r
25                 X_TEMP.X_ImgLoader_params\r
26         );\r
27         \r
28         X_ImgLoader[ 'listen' ]( [ 'load', 'error' /*, 'abort'*/ ], X_ImgLoader_handleEvent );\r
29         \r
30         delete X_TEMP.X_ImgLoader_init;\r
31         delete X_TEMP.X_ImgLoader_params;\r
32         \r
33         return X_ImgLoader;\r
34 };\r
35 \r
36 X_TEMP.X_ImgLoader_params = {\r
37                 tick       : 0,\r
38                 timerID    : 0,\r
39                 finish     : false,\r
40                 abspath    : '',\r
41                 delay      : 0,\r
42                 timeout    : 0,\r
43                 \r
44                 load : function( data ){\r
45                         this.abspath = X_URL_toAbsolutePath( data[ 'url' ] );\r
46                         this.delay   = data[ 'delay'   ] || 100;\r
47                         this.timeout = data[ 'timeout' ] || 5000;\r
48 \r
49                         this[ '_rawObject' ].src = this.abspath;\r
50 \r
51                         if( X_UA[ 'Opera7' ] && this[ '_rawObject' ].complete ){\r
52                                 this[ 'asyncDispatch' ]( 'load' );\r
53                         } else {\r
54                                 this.timerID = X_Timer_add( this.delay, 0, this, X_ImgLoader_detect );\r
55                         };\r
56                 },\r
57                 \r
58                 cancel : function(){\r
59                         var raw = this[ '_rawObject' ];\r
60                         // abort がある?\r
61                         raw && raw.abort && raw.abort();\r
62                         // this[ '_rawObject' ].src = '';\r
63                         this.finish = true;\r
64                 },\r
65                 \r
66                 reset : function(){\r
67                         console.log( 'X.Net.Image:reset ' + this.abspath + ' timerID:' + this.timerID );\r
68                         \r
69                         this.timerID && X_Timer_remove( this.timerID );\r
70                         this.timerID = 0;\r
71                         \r
72                         //X_ImgLoader_isElement ? this[ '_rawObject' ].removeAttribute( 'src' ) : ( this[ '_rawObject' ].src = '' );\r
73                         this[ '_rawObject' ].src = '';\r
74                         this.finish  = false;\r
75                         this.abspath = '';\r
76                 }\r
77         };\r
78 \r
79 function X_ImgLoader_detect(){\r
80         var raw = this[ '_rawObject' ];\r
81         \r
82         if( this.finish ) return;\r
83         \r
84         if( raw && raw.complete ){\r
85                 this.finish = true;\r
86                 console.log( 'X.Net.Image:detect ' + raw.width );\r
87                 if( raw.width ) return;\r
88                 X_Timer_remove( this.timerID );\r
89                 this.timerID = this[ 'asyncDispatch' ]( X_EVENT_ERROR );\r
90         } else\r
91         if( this.timeout < ( this.tick += this.delay ) ){\r
92                 this.finish = true;\r
93                 X_Timer_remove( this.timerID );\r
94                 this.timerID = this[ 'asyncDispatch' ]( { type : X_EVENT_ERROR, 'timeout' : true } );\r
95         };\r
96 };\r
97 \r
98 function X_ImgLoader_handleEvent( e ){\r
99         var raw = this[ '_rawObject' ], size;\r
100         \r
101         // IE11 reset() 時にここに入ってくる...\r
102         if( !this.abspath ) return;\r
103         console.log( 'X.Net.Image:handleEvent ' + e.type );\r
104         \r
105         switch( e.type ){\r
106                 case 'error' :\r
107                 //case 'abort' : // TODO ??\r
108                         // ie11(10,9 開発モード)で mineType 不正の場合、画像取得に成功してもエラーイベントが起こるのを無視する。\r
109                         if( X_ImgLoader_0forError && raw.width ) return;\r
110                         if( this.finish ) return;\r
111                         this.finish  = true;\r
112                         this.timerID && X_Timer_remove( this.timerID );\r
113                         this.timerID = this[ 'asyncDispatch' ]( /*e.type === 'error' ?*/ X_EVENT_ERROR /*: X_EVENT_CANCELED*/ );\r
114                         break;\r
115 \r
116                 case 'load' :\r
117                 // if( finish === true ) return; // これがあると firefox3.6 で駄目、、、\r
118                 // if( timer ) return; // これがあると safari3.2 で駄目、、、\r
119                         this.finish = true;\r
120                         this.timerID && X_Timer_remove( this.timerID );\r
121                         if( X_UA[ 'Opera' ] && !raw.complete ){\r
122                                 this.timerID = this[ 'asyncDispatch' ]( X_EVENT_ERROR );\r
123                                 return;\r
124                         };\r
125 \r
126                         size = X_Util_Image_getActualDimension( !X_ImgLoader_isElement ? this.abspath : this );\r
127                         this.timerID = this[ 'asyncDispatch' ]( {\r
128                                 'type' : X_EVENT_SUCCESS,\r
129                                 'src'  : this.abspath,\r
130                                 'w'    : size[ 0 ],\r
131                                 'h'    : size[ 1 ]\r
132                                 // TODO feedback net speed\r
133                                 // time , this[ '_rawObject' ].fileSize\r
134                         } );\r
135                         break;\r
136         };\r
137 };\r
138 \r
139 \r
140 // X_ImgLoader_isElement && X_ImgLoader[ 'appendAt' ]( X_Node_systemNode );\r