0b19b6bd4b3df1a4560fe7ae049f859aeedb8dbf
[mkgallery.git] / include / slideshow.js
1 \r
2 /**************************************************************\r
3 \r
4         Script          : slideShow\r
5         Version         : 1.3\r
6         Authors         : Samuel Birch\r
7         Desc            : transitions between images\r
8         Licence         : Open Source MIT Licence\r
9 \r
10 **************************************************************/\r
11 \r
12 var slideShow = new Class({\r
13         \r
14         getOptions: function(){\r
15                 return {\r
16                         effect: 'fade', //fade|wipe|slide|random\r
17                         duration: 2000,\r
18                         transition: Fx.Transitions.linear,\r
19                         direction: 'right', //top|right|bottom|left|random\r
20                         //color: false,\r
21                         wait: 5000,\r
22                         loop: true,\r
23                         thumbnails: false,\r
24                         thumbnailCls: 'outline',\r
25                         backgroundSlider: false, //change to be an instance.\r
26                         loadingCls: 'loading',\r
27                         onClick: false\r
28                 };\r
29         },\r
30 \r
31         initialize: function(container, images, options){\r
32                 this.setOptions(this.getOptions(), options);\r
33                 \r
34                 this.container = $(container);\r
35                 this.container.setStyles({\r
36                         position: 'relative',\r
37                         overflow: 'hidden'\r
38                 });\r
39                 if(this.options.onClick){\r
40                         this.container.addEvent('click', function(){\r
41                                 this.options.onClick(this.imageLoaded);\r
42                         }.bind(this));\r
43                 }\r
44                 \r
45                 \r
46                 this.imagesHolder = new Element('div').setStyles({\r
47                         position: 'absolute',\r
48                         overflow: 'hidden',\r
49                         top: this.container.getStyle('height'),\r
50                         left: 0,\r
51                         width: '0px',\r
52                         height: '0px',\r
53                         display: 'none'\r
54                 }).injectInside(this.container);\r
55                 \r
56                 /*\r
57                 if($type(images) == 'string' && !this.options.thumbnails){\r
58                         var imageList = [];\r
59                         $$('.'+images).each(function(el){\r
60                                 imageList.push(el.src);\r
61                                 el.injectInside(this.imagesHolder);\r
62                         },this);\r
63                         this.images = imageList;\r
64                         \r
65                 }else if($type(images) == 'string' && this.options.thumbnails){\r
66                         var imageList = [];\r
67                         var srcList = [];\r
68                         this.thumbnails = $$('.'+images);\r
69                         this.thumbnails.each(function(el,i){\r
70                                 srcList.push(el.href);\r
71                                 imageList.push(el.getElement('img'));\r
72                                 el.href = 'javascript:;';\r
73                                 el.addEvent('click',function(){\r
74                                         this.stop();\r
75                                         this.play(i);                            \r
76                                 }.bind(this,el,i));\r
77                         },this);\r
78                         this.images = srcList;\r
79                         this.thumbnailImages = imageList;\r
80                         \r
81                         if(this.options.backgroundSlider){\r
82                                 this.bgSlider = new BackgroundSlider(this.thumbnailImages,{mouseOver: false, duration: this.options.duration, className: this.options.thumbnailCls, padding:{top:0,right:-2,bottom:-2,left:0}});\r
83                                 this.bgSlider.set(this.thumbnailImages[0]);\r
84                         }\r
85                 \r
86                 }else{\r
87                 */\r
88                         this.images = images;\r
89                 /*\r
90                 }\r
91                 */\r
92                 \r
93                 this.loading = new Element('div').addClass(this.options.loadingCls).setStyles({\r
94                         position: 'absolute',\r
95                         top: 0,\r
96                         left: 0,\r
97                         zIndex: 3,\r
98                         display: 'none',\r
99                         width: this.container.getStyle('width'),\r
100                         height: this.container.getStyle('height')\r
101                 }).injectInside(this.container);\r
102                 \r
103                 this.oldImage = new Element('div').setStyles({\r
104                         position: 'absolute',\r
105                         overflow: 'hidden',\r
106                         top: 0,\r
107                         left: 0,\r
108                         opacity: 0,\r
109                         width: this.container.getStyle('width'),\r
110                         height: this.container.getStyle('height')\r
111                 }).injectInside(this.container);\r
112                 \r
113                 this.newImage = this.oldImage.clone();\r
114                 this.newImage.injectInside(this.container);\r
115                 \r
116                 \r
117                 \r
118                 this.timer = 0;\r
119                 this.image = -1;\r
120                 this.imageLoaded = 0;\r
121                 this.stopped = true;\r
122                 this.started = false;\r
123                 this.animating = false;\r
124                 window.addEvent('resize', this.reshow.bind(this));\r
125                 window.addEvent('scroll', this.reshow.bind(this));\r
126         },\r
127         \r
128         load: function(){\r
129                 $clear(this.timer);\r
130                 this.loading.setStyle('display','block');\r
131                 this.image++;\r
132                 var i;\r
133                 var width;\r
134                 var height;\r
135                 var img;\r
136                 for (i=0;i<this.images[this.image].length;i++) {\r
137                         width = this.images[this.image][i][0];\r
138                         height = this.images[this.image][i][1];\r
139                         img = this.images[this.image][i][2];\r
140                         if (width >= this.width || height >= this.height) {\r
141                                 break;\r
142                         }\r
143                 }\r
144                 /* alert('req1 image '+img); */\r
145                 delete this.imageObj;\r
146                 \r
147                 doLoad = true;\r
148                 this.imagesHolder.getElements('img').each(function(el){\r
149                         var src = this.images[this.image][i][2];\r
150                         /* alert('req2 image '+src); */\r
151                         if(el.src == src){\r
152                                 this.imageObj = el;\r
153                                 doLoad = false;\r
154                                 this.add = false;\r
155                                 this.show();\r
156                         }\r
157                 },this);\r
158                 \r
159                 if(doLoad){\r
160                         this.add = true;\r
161                         this.imageObj = new Asset.image(img, {onload: this.show.bind(this)});\r
162                         this.imageObj.set('width', width).set('height', height);\r
163                 }\r
164                 \r
165         },\r
166 \r
167         restyle: function(imgobj){\r
168                 var width = imgobj.get('width');\r
169                 var height = imgobj.get('height');\r
170                 var vfactor = this.width/width;\r
171                 var hfactor = this.height/height;\r
172                 var factor = 1;\r
173                 if (vfactor < factor) { factor = vfactor; }\r
174                 if (hfactor < factor) { factor = hfactor; }\r
175                 factor *= .95;\r
176                 height = Math.round(height * factor);\r
177                 width = Math.round(width * factor);\r
178                 var topoff = (this.height - height)/2;\r
179                 var leftoff = (this.width - width)/2;\r
180                 /* alert('dim: '+width+'x'+height+'+'+leftoff+'+'+topoff); */\r
181                 imgobj.setStyles({\r
182                         position: 'absolute',\r
183                         top: topoff,\r
184                         left: leftoff,\r
185                         width: width,\r
186                         height: height,\r
187                 });\r
188         },\r
189 \r
190         show: function(add){\r
191                 \r
192                 this.restyle(this.imageObj);\r
193                 var oimg = this.oldImage.getElement('img');\r
194                 if (oimg) {\r
195                         this.restyle(oimg);\r
196                 }\r
197 \r
198                 if(this.add){\r
199                         this.imageObj.injectInside(this.imagesHolder);\r
200                 }\r
201                 \r
202                 this.newImage.setStyles({\r
203                         zIndex: 1,\r
204                         opacity: 0\r
205                 });\r
206                 var img = this.newImage.getElement('img');\r
207                 if(img){\r
208                         this.imageObj.clone().replaces(img);\r
209                         //img.replaces(this.imageObj.clone());\r
210                 }else{\r
211                         var obj = this.imageObj.clone();\r
212                         obj.injectInside(this.newImage);\r
213                 }\r
214 \r
215                 this.imageLoaded = this.image;\r
216                 this.loading.setStyle('display','none');\r
217                 this.effect();\r
218         },\r
219         \r
220         wait: function(){\r
221                 this.timer = this.load.delay(this.options.wait,this);\r
222         },\r
223         \r
224         play: function(num){\r
225                 this.position();\r
226                 if(this.stopped){\r
227                         if(num > -1){this.image = num-1};\r
228                         if(this.image < this.images.length){\r
229                                 this.stopped = false;\r
230                                 if(this.started){\r
231                                         this.next();\r
232                                 }else{\r
233                                         this.load();\r
234                                 }\r
235                                 this.started = true;\r
236                         }\r
237                 }\r
238         },\r
239         \r
240         stop: function(){\r
241                 $clear(this.timer);\r
242                 this.stopped = true;\r
243         },\r
244 \r
245         quit: function(){\r
246                 this.stop();\r
247         /* does not work */\r
248                 var oimg = this.oldImage.getElement('img');\r
249                 if (oimg) {\r
250                         oimg.dispose();\r
251                         delete oimg;\r
252                 }\r
253         },\r
254         \r
255         next: function(wait){\r
256                 var doNext = true;\r
257                 if(wait && this.stopped){\r
258                         doNext = false;\r
259                 }\r
260                 if(this.animating){\r
261                         doNext = false;\r
262                 }\r
263                 if(doNext){\r
264                         this.cloneImage();\r
265                         $clear(this.timer);\r
266                         /* console.log(this.image) */\r
267                         if(this.image < this.images.length-1){\r
268                                 if(wait){\r
269                                         this.wait();\r
270                                 }else{\r
271                                         this.load();    \r
272                                 }\r
273                         }else{\r
274                                 if(this.options.loop){\r
275                                         this.image = -1;\r
276                                         if(wait){\r
277                                                 this.wait();\r
278                                         }else{\r
279                                                 this.load();    \r
280                                         }\r
281                                 }else{\r
282                                         this.stopped = true;\r
283                                 }\r
284                         }\r
285                 }\r
286         },\r
287         \r
288         previous: function(){\r
289                 if(this.imageLoaded == 0){\r
290                         this.image = this.images.length-2;      \r
291                 }else{\r
292                         this.image = this.imageLoaded-2;\r
293                 }\r
294                 this.next();\r
295         },\r
296         \r
297         cloneImage: function(){\r
298                 var img = this.oldImage.getElement('img');\r
299                 if(img){\r
300                         this.imageObj.clone().replaces(img);\r
301                         //img.replaces(this.imageObj.clone());\r
302                 }else{\r
303                         var obj = this.imageObj.clone();\r
304                         obj.injectInside(this.oldImage);\r
305                 }\r
306                 \r
307                 this.oldImage.setStyles({\r
308                         zIndex: 0,\r
309                         top: 0,\r
310                         left: 0,\r
311                         opacity: 1\r
312                 });\r
313                 \r
314                 this.newImage.setStyles({opacity:0});\r
315         },\r
316         \r
317         \r
318         effect: function(){\r
319                 this.animating = true;\r
320                 this.effectObj = new Fx.Morph(this.newImage, {\r
321                         duration: this.options.duration,\r
322                         transition: this.options.transition\r
323                 });\r
324                 \r
325                 var myFxTypes = ['fade','wipe','slide'];\r
326                 var myFxDir = ['top','right','bottom','left'];\r
327                 \r
328                 if(this.options.effect == 'fade'){\r
329                         this.fade();\r
330                         \r
331                 }else if(this.options.effect == 'wipe'){\r
332                         if(this.options.direction == 'random'){\r
333                                 this.setup(myFxDir[Math.floor(Math.random()*(3+1))]);\r
334                         }else{\r
335                                 this.setup(this.options.direction);\r
336                         }\r
337                         this.wipe();\r
338                         \r
339                 }else if(this.options.effect == 'slide'){\r
340                         if(this.options.direction == 'random'){\r
341                                 this.setup(myFxDir[Math.floor(Math.random()*(3+1))]);\r
342                         }else{\r
343                                 this.setup(this.options.direction);\r
344                         }\r
345                         this.slide();\r
346                         \r
347                 }else if(this.options.effect == 'random'){\r
348                         var type = myFxTypes[Math.floor(Math.random()*(2+1))];\r
349                         if(type != 'fade'){\r
350                                 var dir = myFxDir[Math.floor(Math.random()*(3+1))];\r
351                                 if(this.options.direction == 'random'){\r
352                                         this.setup(dir);\r
353                                 }else{\r
354                                         this.setup(this.options.direction);\r
355                                 }\r
356                         }else{\r
357                                 this.setup();\r
358                         }\r
359                         this[type]();\r
360                 }\r
361         },\r
362         \r
363         setup: function(dir){\r
364                 if(dir == 'top'){\r
365                         this.top = -this.height;\r
366                         this.left = 0;\r
367                         this.topOut = this.height;\r
368                         this.leftOut = 0;\r
369                         \r
370                 }else if(dir == 'right'){\r
371                         this.top = 0;\r
372                         this.left = this.width;\r
373                         this.topOut = 0;\r
374                         this.leftOut = -this.width;\r
375                         \r
376                 }else if(dir == 'bottom'){\r
377                         this.top = this.height;\r
378                         this.left = 0;\r
379                         this.topOut = -this.height;\r
380                         this.leftOut = 0;\r
381                         \r
382                 }else if(dir == 'left'){\r
383                         this.top = 0;\r
384                         this.left = -this.width;\r
385                         this.topOut = 0;\r
386                         this.leftOut = this.width;\r
387                         \r
388                 }else{\r
389                         this.top = 0;\r
390                         this.left = 0;\r
391                         this.topOut = 0;\r
392                         this.leftOut = 0;\r
393                 }\r
394         },\r
395         \r
396         fade: function(){\r
397                 this.effectObj.start({\r
398                         opacity: [0,1]\r
399                 });\r
400                 this.resetAnimation.delay(this.options.duration+90,this);\r
401                 if(!this.stopped){\r
402                 this.next.delay(this.options.duration+100,this,true);\r
403                 }\r
404         },\r
405         \r
406         wipe: function(){\r
407                 this.newImage.morph({\r
408                         duration: this.options.duration,\r
409                         transition: this.options.transition,\r
410                         top: [0,this.topOut],\r
411                         left: [0, this.leftOut]\r
412                 })\r
413                 this.effectObj.start({\r
414                         top: [this.top,0],\r
415                         left: [this.left,0],\r
416                         opacity: [1,1]\r
417                 },this);\r
418                 this.resetAnimation.delay(this.options.duration+90,this);\r
419                 if(!this.stopped){\r
420                 this.next.delay(this.options.duration+100,this,true);\r
421                 }\r
422         },\r
423         \r
424         slide: function(){\r
425                 this.effectObj.start({\r
426                         top: [this.top,0],\r
427                         left: [this.left,0],\r
428                         opacity: [1,1]\r
429                 },this);\r
430                 this.resetAnimation.delay(this.options.duration+90,this);\r
431                 if(!this.stopped){\r
432                 this.next.delay(this.options.duration+100,this,true);\r
433                 }\r
434         },\r
435         \r
436         resetAnimation: function(){\r
437                 this.animating = false;\r
438         },\r
439 \r
440         position: function(){\r
441                 var myCoords = this.container.getCoordinates();\r
442                 this.width = myCoords.width;\r
443                 this.height = myCoords.height;\r
444                 /*\r
445                 this.width = this.container.getStyle('width').toInt();\r
446                 this.height = this.container.getStyle('height').toInt();\r
447                 */\r
448                 /* alert('container dim: '+this.width+'x'+this.height); */\r
449         },\r
450 \r
451         reshow: function(){\r
452                 this.position();\r
453                 this.image--;\r
454                 this.load();\r
455         },\r
456         \r
457 });\r
458 slideShow.implement(new Options);\r
459 slideShow.implement(new Events);\r
460 \r
461 \r
462 /*************************************************************/\r
463 \r