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