d06246e058af5ef6d2f254a1a9034af28ad4f2eb
[platform/framework/web/web-ui-fw.git] / src / widgets / imageslider / js / jquery.mobile.tizen.imageslider.js
1 /*
2         Author: Minkyu Kang <mk7.kang@samsung.com>
3 */
4
5 /*
6  * Notification widget
7  *
8  * HTML Attributes
9  *
10  *  data-role: set to 'imageslider'
11  *  data-start-index: start index
12  *  data-vertical-align: set to top or middle or bottom.
13  *
14  * APIs
15  *
16  *  add(image_file): add the image (parameter: url of iamge)
17  *  del(image_index): delete the image (parameter: index of image)
18  *  refresh(): refresh the widget, should be called after add or del.
19  *
20  * Events
21  *
22  *  N/A
23  *
24  * Example
25  *
26  * <div data-role="imageslider" id="imageslider" data-start-index="3" data-vertical-align="middle">
27  *      <img src="01.jpg">
28  *      <img src="02.jpg">
29  *      <img src="03.jpg">
30  *      <img src="04.jpg">
31  *      <img src="05.jpg">
32  * </div>
33  *
34  *
35  * $('#imageslider-add').bind('vmouseup', function ( e ) {
36  *      $('#imageslider').imageslider('add', '9.jpg');
37  *      $('#imageslider').imageslider('add', '10.jpg');
38  *      $('#imageslider').imageslider('refresh');
39  * });
40  *
41  * $('#imageslider-del').bind('vmouseup', function ( e ) {
42  *      $('#imageslider').imageslider('del');
43  * });
44  *
45  */
46
47 (function ($, window, undefined) {
48         $.widget("tizen.imageslider", $.mobile.widget, {
49                 options: {
50                         photoFlicking: false
51                 },
52
53                 dragging: false,
54                 moving: false,
55                 max_width: 0,
56                 max_height: 0,
57                 org_x: 0,
58                 org_time: null,
59                 cur_img: null,
60                 prev_img: null,
61                 next_img: null,
62                 images: null,
63                 images_hold: null,
64                 index: 0,
65                 align_type: null,
66                 direction: 1,
67                 container: null,
68                 interval: null,
69
70                 _resize: function ( obj ) {
71                         var width;
72                         var height;
73                         var margin = 40;
74                         var ratio;
75                         var img_max_width = this.max_width - margin;
76                         var img_max_height = this.max_height - margin;
77
78                         height = obj.height();
79                         width = obj.width();
80
81                         ratio = height / width;
82
83                         if ( width > img_max_width ) {
84                                 obj.width( img_max_width );
85                                 obj.height( img_max_width * ratio );
86                         }
87
88                         height = obj.height();
89
90                         if ( height > img_max_height ) {
91                                 obj.height( img_max_height );
92                                 obj.width( img_max_height / ratio );
93                         }
94                 },
95
96                 _align: function ( obj, img ) {
97                         var img_top = 0;
98
99                         if ( !obj.length )
100                                 return;
101
102                         if ( this.align_type == "middle" ) {
103                                 img_top = (this.max_height - img.height()) / 2;
104                         } else if ( this.align_type == "bottom" ) {
105                                 img_top = this.max_height - img.height();
106                         } else {
107                                 img_top = 0;
108                         }
109
110                         obj.css( 'top', img_top + 'px' );
111                 },
112
113                 _detach: function ( image_index, obj ) {
114                         if ( !obj.length ) {
115                                 return;
116                         }
117                         if ( image_index < 0 ) {
118                                 return;
119                         }
120                         if ( image_index >= this.images.length ) {
121                                 return;
122                         }
123
124                         this.images[image_index].detach();
125                         obj.css( "display", "none" );
126                 },
127
128                 _attach: function ( image_index, obj ) {
129                         if ( !obj.length ) {
130                                 return;
131                         }
132                         if ( image_index < 0 ) {
133                                 return;
134                         }
135                         if ( image_index >= this.images.length ) {
136                                 return;
137                         }
138
139                         obj.css( "display", "block" );
140                         obj.append( this.images[image_index] );
141                         this._resize( this.images[image_index] );
142                         this._align( obj, this.images[image_index] );
143                 },
144
145                 _drag: function ( _x ) {
146                         if ( !this.dragging ) {
147                                 return;
148                         }
149
150                         if ( this.options.photoFlicking === false ) {
151                                 var delta = this.org_x - _x;
152
153                                 // first image
154                                 if ( delta < 0 && !this.prev_img.length ) {
155                                         return;
156                                 }
157                                 // last image
158                                 if ( delta > 0 && !this.next_img.length ) {
159                                         return;
160                                 }
161                         }
162
163                         var coord_x = _x - this.org_x;
164
165                         this.cur_img.css( 'left', coord_x + 'px' );
166                         if ( this.next_img.length ) {
167                                 this.next_img.css('left',
168                                                 coord_x + this.max_width + 'px');
169                         }
170                         if ( this.prev_img.length ) {
171                                 this.prev_img.css('left',
172                                                 coord_x - this.max_width + 'px');
173                         }
174                 },
175
176                 _move: function ( _x ) {
177                         var delta = this.org_x - _x;
178                         var flip = 0;
179
180                         if ( delta == 0 ) {
181                                 return;
182                         }
183
184                         if ( delta > 0 ) {
185                                 flip = delta < (this.max_width * 0.45) ? 0 : 1;
186                         } else {
187                                 flip = -delta < (this.max_width * 0.45) ? 0 : 1;
188                         }
189
190                         if ( !flip ) {
191                                 var date = new Date();
192                                 var drag_time = date.getTime() - this.org_time;
193
194                                 if ( Math.abs(delta) / drag_time > 1 ) {
195                                         flip = 1;
196                                 }
197                         }
198
199                         if ( flip ) {
200                                 if ( delta > 0 && this.next_img.length ) {
201                                         /* next */
202                                         this._detach( this.index - 1, this.prev_img );
203
204                                         this.prev_img = this.cur_img;
205                                         this.cur_img = this.next_img;
206                                         this.next_img = this.next_img.next();
207
208                                         this.index++;
209
210                                         if ( this.next_img.length ) {
211                                                 this.next_img.css( 'left',
212                                                         this.max_width + 'px' );
213                                                 this._attach( this.index + 1,
214                                                         this.next_img );
215                                         }
216
217                                         this.direction = 1;
218
219                                 } else if ( delta < 0 && this.prev_img.length ) {
220                                         /* prev */
221                                         this._detach( this.index + 1, this.next_img );
222
223                                         this.next_img = this.cur_img;
224                                         this.cur_img = this.prev_img;
225                                         this.prev_img = this.prev_img.prev();
226
227                                         this.index--;
228
229                                         if ( this.prev_img.length ) {
230                                                 this.prev_img.css( 'left',
231                                                         -this.max_width + 'px' );
232                                                 this._attach( this.index - 1,
233                                                         this.prev_img );
234                                         }
235
236                                         this.direction = -1;
237                                 }
238                         }
239
240                         var sec = 500;
241                         var self = this;
242
243                         this.moving = true;
244
245                         this.interval = setInterval(function () {
246                                 self.moving = false;
247                                 clearInterval( self.interval );
248                         }, sec - 50);
249
250                         this.cur_img.animate({left: 0}, sec);
251                         if ( this.next_img.length ) {
252                                 this.next_img.animate({left: this.max_width}, sec);
253                         }
254                         if ( this.prev_img.length ) {
255                                 this.prev_img.animate({left: -this.max_width}, sec);
256                         }
257                 },
258
259                 _add_event: function () {
260                         var self = this;
261
262                         this.container.bind('vmousemove', function ( e ) {
263                                 e.preventDefault();
264
265                                 if ( self.moving ) {
266                                         return;
267                                 }
268                                 if ( !self.dragging ) {
269                                         return;
270                                 }
271
272                                 self._drag( e.pageX );
273                         });
274
275                         this.container.bind('vmousedown', function ( e ) {
276                                 e.preventDefault();
277
278                                 if ( self.moving ) {
279                                         return;
280                                 }
281
282                                 self.dragging = true;
283
284                                 self.org_x = e.pageX;
285
286                                 var date = new Date();
287                                 self.org_time = date.getTime();
288                         });
289
290                         this.container.bind('vmouseup', function (e) {
291                                 if ( self.moving ) {
292                                         return;
293                                 }
294
295                                 self.dragging = false;
296
297                                 self._move( e.pageX );
298                         });
299
300                         this.container.bind('vmouseout', function (e) {
301                                 if ( self.moving ) {
302                                         return;
303                                 }
304                                 if ( !self.dragging ) {
305                                         return;
306                                 }
307
308                                 if ( (e.pageX < 20) ||
309                                         (e.pageX > (self.max_width - 20)) ) {
310                                         self._move( e.pageX );
311                                         self.dragging = false;
312                                 }
313                         });
314                 },
315
316                 _del_event: function () {
317                         this.container.unbind('vmousemove');
318                         this.container.unbind('vmousedown');
319                         this.container.unbind('vmouseup');
320                         this.container.unbind('vmouseout');
321                 },
322
323                 _show: function () {
324                         this.cur_img = $('div').find(
325                                         '.ui-imageslider-bg:eq(' + this.index + ')');
326                         this.prev_img = this.cur_img.prev();
327                         this.next_img = this.cur_img.next();
328
329                         this._attach( this.index - 1, this.prev_img );
330                         this._attach( this.index, this.cur_img );
331                         this._attach( this.index + 1, this.next_img );
332
333                         if ( this.prev_img.length ) {
334                                 this.prev_img.css( 'left', -this.max_width + 'px' );
335                         }
336
337                         this.cur_img.css( 'left', 0 + 'px' );
338
339                         if ( this.next_img.length ) {
340                                 this.next_img.css( 'left', this.max_width + 'px' );
341                         }
342                 },
343
344                 show: function () {
345                         this._show();
346                         this._add_event();
347                 },
348
349                 _hide: function () {
350                         this._detach( this.index - 1, this.prev_img );
351                         this._detach( this.index, this.cur_img );
352                         this._detach( this.index + 1, this.next_img );
353                 },
354
355                 hide: function () {
356                         this._hide();
357                         this._del_event();
358                 },
359
360                 _get_height: function () {
361                         var $page = $('.ui-page');
362                         var $content = $page.children('.ui-content');
363                         var $header = $page.children('.ui-header');
364                         var $footer = $page.children('.ui-footer');
365
366                         var header_h = $header.outerHeight();
367                         var footer_h = $footer.outerHeight();
368                         var padding = parseFloat($content.css('padding-top')) +
369                                         parseFloat($content.css('padding-bottom'));
370
371                         var content_h = window.innerHeight - header_h -
372                                         footer_h - padding * 2;
373
374                         return content_h;
375                 },
376
377                 _create: function () {
378                         this.images = new Array();
379                         this.images_hold = new Array();
380
381                         $( this.element ).wrapInner('<div class="ui-imageslider"></div>');
382                         $('img').wrap('<div class="ui-imageslider-bg"></div>');
383
384                         this.container = $( this.element ).find('.ui-imageslider');
385
386                         this.max_width = window.innerWidth;
387                         this.max_height = this._get_height();
388                         this.container.css( 'height', this.max_height );
389
390                         var temp_img = $('div').find('.ui-imageslider-bg:first');
391
392                         for ( i = 0; ; i++ ) {
393                                 if ( !temp_img.length ) {
394                                         break;
395                                 }
396
397                                 this.images[i] = temp_img.find('img');
398
399                                 temp_img = temp_img.next();
400                         }
401
402                         for ( i = 0; i < this.images.length; i++ ) {
403                                 this.images[i].detach();
404                         }
405
406                         var start_index = parseInt( $(this.element).attr('data-start-index') );
407                         if ( start_index === undefined ) {
408                                 start_index = 0;
409                         }
410                         if ( start_index < 0 ) {
411                                 start_index = 0;
412                         }
413                         if ( start_index >= this.images.length ) {
414                                 start_index = this.images.length - 1;
415                         }
416
417                         this.index = start_index;
418
419                         this.align_type = $( this.element ).attr('data-vertical-align');
420                 },
421
422                 _update: function () {
423                         while ( 1 ) {
424                                 if ( !this.images_hold.length ) {
425                                         break;
426                                 }
427
428                                 var image_file = this.images_hold.shift();
429
430                                 var bg_html = $('<div class="ui-imageslider-bg"></div>');
431                                 var temp_img = $('<img src="' + image_file + '"></div>');
432
433                                 bg_html.append( temp_img );
434                                 this.container.append( bg_html );
435                                 this.images.push( temp_img );
436                         }
437                 },
438
439                 refresh: function ( start_index ) {
440                         this._update();
441
442                         this._hide();
443
444                         if ( start_index === undefined ) {
445                                 start_index = this.index;
446                         }
447                         if ( start_index < 0 ) {
448                                 start_index = 0;
449                         }
450                         if ( start_index >= this.images.length ) {
451                                 start_index = this.images.length - 1;
452                         }
453
454                         this.index = start_index;
455
456                         this._show();
457                 },
458
459                 add: function ( image_file ) {
460                         this.images_hold.push( image_file );
461                 },
462
463                 del: function ( image_index ) {
464                         var temp_img;
465
466                         if ( image_index === undefined ) {
467                                 image_index = this.index;
468                         }
469
470                         if ( image_index < 0 || image_index >= this.images.length ) {
471                                 return;
472                         }
473
474                         if ( image_index == this.index ) {
475                                 temp_img = this.cur_img;
476
477                                 if ( this.index == 0 ) {
478                                         this.direction = 1;
479                                 } else if ( this.index == this.images.length - 1 ) {
480                                         this.direction = -1;
481                                 }
482
483                                 if ( this.direction < 0 ) {
484                                         this.cur_img = this.prev_img;
485                                         this.prev_img = this.prev_img.prev();
486                                         if ( this.prev_img.length ) {
487                                                 this.prev_img.css( 'left', -this.max_width );
488                                                 this._attach( image_index - 2, this.prev_img );
489                                         }
490                                         this.index--;
491                                 } else {
492                                         this.cur_img = this.next_img;
493                                         this.next_img = this.next_img.next();
494                                         if ( this.next_img.length ) {
495                                                 this.next_img.css( 'left', this.max_width );
496                                                 this._attach( image_index + 2, this.next_img );
497                                         }
498                                 }
499
500                                 this.cur_img.animate({left: 0}, 500);
501
502                         } else if ( image_index == this.index - 1 ) {
503                                 temp_img = this.prev_img;
504                                 this.prev_img = this.prev_img.prev();
505                                 if ( this.prev_img.length ) {
506                                         this.prev_img.css( 'left', -this.max_width );
507                                         this._attach( image_index - 1, this.prev_img );
508                                 }
509                                 this.index--;
510
511                         } else if ( image_index == this.index + 1 ) {
512                                 temp_img = this.next_img;
513                                 this.next_img = this.next_img.next();
514                                 if ( this.next_img.length ) {
515                                         this.next_img.css( 'left', this.max_width );
516                                         this._attach( image_index + 1, this.next_img );
517                                 }
518
519                         } else {
520                                 temp_img = $('div').find('.ui-imageslider-bg:eq('+ image_index + ')');
521                         }
522
523                         this.images.splice( image_index, 1 );
524                         temp_img.detach();
525                 },
526         }); /* End of widget */
527
528         // auto self-init widgets
529         $( document ).bind("pagecreate", function (e) {
530                 $( e.target ).find(":jqmData(role='imageslider')").imageslider();
531         });
532
533         $( document ).bind("pageshow", function (e) {
534                 $( e.target ).find(":jqmData(role='imageslider')").imageslider('show');
535         });
536
537         $( document ).bind("pagebeforehide", function (e) {
538                 $ (e.target ).find(":jqmData(role='imageslider')").imageslider('hide');
539         });
540
541 })( jQuery, this );