| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 /* 2 Name: ImageFlow 3 Version: 1.3.0 (March 9 2010) 4 Author: Finn Rudolph 5 Support: http://finnrudolph.de/ImageFlow 6 7 License: ImageFlow is licensed under a Creative Commons 8 Attribution-Noncommercial 3.0 Unported License 9 (http://creativecommons.org/licenses/by-nc/3.0/). 10 11 You are free: 12 + to Share - to copy, distribute and transmit the work 13 + to Remix - to adapt the work 14 15 Under the following conditions: 16 + Attribution. You must attribute the work in the manner specified by the author or licensor 17 (but not in any way that suggests that they endorse you or your use of the work). 18 + Noncommercial. You may not use this work for commercial purposes. 19 20 + For any reuse or distribution, you must make clear to others the license terms of this work. 21 + Any of the above conditions can be waived if you get permission from the copyright holder. 22 + Nothing in this license impairs or restricts the author's moral rights. 23 24 Credits: This script is based on Michael L. Perrys Cover flow in Javascript [1]. 25 The reflections are generated server-sided by a slightly hacked version 26 of Richard Daveys easyreflections [2] written in PHP. The mouse wheel 27 support is an implementation of Adomas Paltanavicius JavaScript mouse 28 wheel code [3]. It also uses the domReadyEvent from Tanny O'Haley [4]. 29 30 [1] http://www.adventuresinsoftware.com/blog/?p=104#comment-1981 31 [2] http://reflection.corephp.co.uk/v2.php 32 [3] http://adomas.org/javascript-mouse-wheel/ 33 [4] http://tanny.ica.com/ICA/TKO/tkoblog.nsf/dx/domcontentloaded-for-browsers-part-v 34 */ 35 36 /* ImageFlow constructor */ 37 function ImageFlow () 38 { 39 /* Setting option defaults */ 40 this.defaults = 41 { 42 animationSpeed: 50, /* Animation speed in ms */ 43 aspectRatio: 1.964, /* Aspect ratio of the ImageFlow container (width divided by height) */ 44 buttons: false, /* Toggle navigation buttons */ 45 captions: true, /* Toggle captions */ 46 circular: false, /* Toggle circular rotation */ 47 imageCursor: 'default', /* Cursor type for all images - default is 'default' */ 48 ImageFlowID: 'imageflow', /* Default id of the ImageFlow container */ 49 imageFocusM: 1.0, /* Multiplicator for the focussed image size in percent */ 50 imageFocusMax: 4, /* Max number of images on each side of the focussed one */ 51 imagePath: '', /* Path to the images relative to the reflect_.php script */ 52 imageScaling: true, /* Toggle image scaling */ 53 imagesHeight: 0.67, /* Height of the images div container in percent */ 54 imagesM: 1.0, /* Multiplicator for all images in percent */ 55 onClick: function() { document.location = this.url; }, /* Onclick behaviour */ 56 opacity: false, /* Toggle image opacity */ 57 opacityArray: [10,8,6,4,2], /* Image opacity (range: 0 to 10) first value is for the focussed image */ 58 percentLandscape: 118, /* Scale landscape format */ 59 percentOther: 100, /* Scale portrait and square format */ 60 preloadImages: true, /* Toggles loading bar (false: requires img attributes height and width) */ 61 reflections: true, /* Toggle reflections */ 62 reflectionGET: '', /* Pass variables via the GET method to the reflect_.php script */ 63 reflectionP: 0.5, /* Height of the reflection in percent of the source image */ 64 reflectionPNG: false, /* Toggle reflect2.php or reflect3.php */ 65 reflectPath: '', /* Path to the reflect_.php script */ 66 scrollbarP: 0.6, /* Width of the scrollbar in percent */ 67 slider: true, /* Toggle slider */ 68 sliderCursor: 'e-resize', /* Slider cursor type - default is 'default' */ 69 sliderWidth: 14, /* Width of the slider in px */ 70 slideshow: false, /* Toggle slideshow */ 71 slideshowSpeed: 1500, /* Time between slides in ms */ 72 slideshowAutoplay: false, /* Toggle automatic slideshow play on startup */ 73 startID: 1, /* Image ID to begin with */ 74 glideToStartID: true, /* Toggle glide animation to start ID */ 75 startAnimation: false, /* Animate images moving in from the right on startup */ 76 xStep: 150 /* Step width on the x-axis in px */ 77 }; 78 79 80 /* Closure for this */ 81 var my = this; 82 83 84 /* Initiate ImageFlow */ 85 this.init = function (options) 86 { 87 /* Evaluate options */ 88 for(var name in my.defaults) 89 { 90 this[name] = (options !== undefined && options[name] !== undefined) ? options[name] : my.defaults[name]; 91 } 92 93 /* Try to get ImageFlow div element */ 94 var ImageFlowDiv = document.getElementById(my.ImageFlowID); 95 if(ImageFlowDiv) 96 { 97 /* Set it global within the ImageFlow scope */ 98 ImageFlowDiv.style.visibility = 'visible'; 99 this.ImageFlowDiv = ImageFlowDiv; 100 101 /* Try to create XHTML structure */ 102 if(this.createStructure()) 103 { 104 this.imagesDiv = document.getElementById(my.ImageFlowID+'_images'); 105 this.captionDiv = document.getElementById(my.ImageFlowID+'_caption'); 106 this.navigationDiv = document.getElementById(my.ImageFlowID+'_navigation'); 107 this.scrollbarDiv = document.getElementById(my.ImageFlowID+'_scrollbar'); 108 this.sliderDiv = document.getElementById(my.ImageFlowID+'_slider'); 109 this.buttonNextDiv = document.getElementById(my.ImageFlowID+'_next'); 110 this.buttonPreviousDiv = document.getElementById(my.ImageFlowID+'_previous'); 111 this.buttonSlideshow = document.getElementById(my.ImageFlowID+'_slideshow'); 112 113 this.indexArray = []; 114 this.current = 0; 115 this.imageID = 0; 116 this.target = 0; 117 this.memTarget = 0; 118 this.firstRefresh = true; 119 this.firstCheck = true; 120 this.busy = false; 121 122 /* Set height of the ImageFlow container and center the loading bar */ 123 var width = this.ImageFlowDiv.offsetWidth; 124 var height = Math.round(width / my.aspectRatio); 125 document.getElementById(my.ImageFlowID+'_loading_txt').style.paddingTop = ((height * 0.5) -22) + 'px'; 126 ImageFlowDiv.style.height = height + 'px'; 127 128 /* Init loading progress */ 129 this.loadingProgress(); 130 } 131 } 132 }; 133 134 135 /* Create HTML Structure */ 136 this.createStructure = function() 137 { 138 /* Create images div container */ 139 var imagesDiv = my.Helper.createDocumentElement('div','images'); 140 141 /* Shift all images into the images div */ 142 var node, version, src, imageNode; 143 var max = my.ImageFlowDiv.childNodes.length; 144 for(var index = 0; index < max; index++) 145 { 146 node = my.ImageFlowDiv.childNodes[index]; 147 if (node && node.nodeType == 1 && node.nodeName == 'IMG') 148 { 149 /* Add 'reflect.php?img=' */ 150 if(my.reflections === true) 151 { 152 version = (my.reflectionPNG) ? '3' : '2'; 153 src = my.imagePath+node.getAttribute('src',2); 154 src = my.reflectPath+'reflect'+version+'.php?img='+src+my.reflectionGET; 155 node.setAttribute('src',src); 156 } 157 158 /* Clone image nodes and append them to the images div */ 159 imageNode = node.cloneNode(true); 160 imagesDiv.appendChild(imageNode); 161 } 162 } 163 164 /* Clone some more images to make a circular animation possible */ 165 if(my.circular) 166 { 167 /* Create temporary elements to hold the cloned images */ 168 var first = my.Helper.createDocumentElement('div','images'); 169 var last = my.Helper.createDocumentElement('div','images'); 170 171 /* Make sure, that there are enough images to use circular mode */ 172 max = imagesDiv.childNodes.length; 173 if(max < my.imageFocusMax) 174 { 175 my.imageFocusMax = max; 176 } 177 178 /* Do not clone anything if there is only one image */ 179 if(max > 1) 180 { 181 /* Clone the first and last images */ 182 var i; 183 for(i = 0; i < max; i++) 184 { 185 /* Number of clones on each side equals the imageFocusMax */ 186 node = imagesDiv.childNodes[i]; 187 if(i < my.imageFocusMax) 188 { 189 imageNode = node.cloneNode(true); 190 first.appendChild(imageNode); 191 } 192 if(max-i < my.imageFocusMax+1) 193 { 194 imageNode = node.cloneNode(true); 195 last.appendChild(imageNode); 196 } 197 } 198 199 /* Sort the image nodes in the following order: last | originals | first */ 200 for(i = 0; i < max; i++) 201 { 202 node = imagesDiv.childNodes[i]; 203 imageNode = node.cloneNode(true); 204 last.appendChild(imageNode); 205 } 206 for(i = 0; i < my.imageFocusMax; i++) 207 { 208 node = first.childNodes[i]; 209 imageNode = node.cloneNode(true); 210 last.appendChild(imageNode); 211 } 212 213 /* Overwrite the imagesDiv with the new order */ 214 imagesDiv = last; 215 } 216 } 217 218 /* Create slideshow button div and append it to the images div */ 219 if(my.slideshow) 220 { 221 var slideshowButton = my.Helper.createDocumentElement('div','slideshow'); 222 imagesDiv.appendChild(slideshowButton); 223 } 224 225 /* Create loading text container */ 226 var loadingP = my.Helper.createDocumentElement('p','loading_txt'); 227 var loadingText = document.createTextNode(' '); 228 loadingP.appendChild(loadingText); 229 230 /* Create loading div container */ 231 var loadingDiv = my.Helper.createDocumentElement('div','loading'); 232 233 /* Create loading bar div container inside the loading div */ 234 var loadingBarDiv = my.Helper.createDocumentElement('div','loading_bar'); 235 loadingDiv.appendChild(loadingBarDiv); 236 237 /* Create captions div container */ 238 var captionDiv = my.Helper.createDocumentElement('div','caption'); 239 240 /* Create slider and button div container inside the scrollbar div */ 241 var scrollbarDiv = my.Helper.createDocumentElement('div','scrollbar'); 242 var sliderDiv = my.Helper.createDocumentElement('div','slider'); 243 scrollbarDiv.appendChild(sliderDiv); 244 if(my.buttons) 245 { 246 var buttonPreviousDiv = my.Helper.createDocumentElement('div','previous', 'button'); 247 var buttonNextDiv = my.Helper.createDocumentElement('div','next', 'button'); 248 scrollbarDiv.appendChild(buttonPreviousDiv); 249 scrollbarDiv.appendChild(buttonNextDiv); 250 } 251 252 /* Create navigation div container beneath images div */ 253 var navigationDiv = my.Helper.createDocumentElement('div','navigation'); 254 navigationDiv.appendChild(captionDiv); 255 navigationDiv.appendChild(scrollbarDiv); 256 257 /* Update document structure and return true on success */ 258 var success = false; 259 if (my.ImageFlowDiv.appendChild(imagesDiv) && 260 my.ImageFlowDiv.appendChild(loadingP) && 261 my.ImageFlowDiv.appendChild(loadingDiv) && 262 my.ImageFlowDiv.appendChild(navigationDiv)) 263 { 264 /* Remove image nodes outside the images div */ 265 max = my.ImageFlowDiv.childNodes.length; 266 for(index = 0; index < max; index++) 267 { 268 node = my.ImageFlowDiv.childNodes[index]; 269 if (node && node.nodeType == 1 && node.nodeName == 'IMG') 270 { 271 my.ImageFlowDiv.removeChild(node); 272 } 273 } 274 success = true; 275 } 276 return success; 277 }; 278 279 280 /* Manage loading progress and call the refresh function */ 281 this.loadingProgress = function() 282 { 283 var p = my.loadingStatus(); 284 if((p < 100 || my.firstCheck) && my.preloadImages) 285 { 286 /* Insert a short delay if the browser loads rapidly from its cache */ 287 if(my.firstCheck && p == 100) 288 { 289 my.firstCheck = false; 290 window.setTimeout(my.loadingProgress, 100); 291 } 292 else 293 { 294 window.setTimeout(my.loadingProgress, 40); 295 } 296 } 297 else 298 { 299 /* Hide loading elements */ 300 document.getElementById(my.ImageFlowID+'_loading_txt').style.display = 'none'; 301 document.getElementById(my.ImageFlowID+'_loading').style.display = 'none'; 302 303 /* Refresh ImageFlow on window resize - delay adding this event for the IE */ 304 window.setTimeout(my.Helper.addResizeEvent, 1000); 305 306 /* Call refresh once on startup to display images */ 307 my.refresh(); 308 309 /* Only initialize navigation elements if there is more than one image */ 310 if(my.max > 1) 311 { 312 /* Initialize mouse, touch and key support */ 313 my.MouseWheel.init(); 314 my.MouseDrag.init(); 315 my.Touch.init(); 316 my.Key.init(); 317 318 /* Toggle slideshow */ 319 if(my.slideshow) 320 { 321 my.Slideshow.init(); 322 } 323 324 /* Toggle scrollbar visibility */ 325 if(my.slider) 326 { 327 my.scrollbarDiv.style.visibility = 'visible'; 328 } 329 } 330 } 331 }; 332 333 334 /* Return loaded images in percent, set loading bar width and loading text */ 335 this.loadingStatus = function() 336 { 337 var max = my.imagesDiv.childNodes.length; 338 var i = 0, completed = 0; 339 var image = null; 340 for(var index = 0; index < max; index++) 341 { 342 image = my.imagesDiv.childNodes[index]; 343 if(image && image.nodeType == 1 && image.nodeName == 'IMG') 344 { 345 if(image.complete) 346 { 347 completed++; 348 } 349 i++; 350 } 351 } 352 353 var finished = Math.round((completed/i)*100); 354 var loadingBar = document.getElementById(my.ImageFlowID+'_loading_bar'); 355 loadingBar.style.width = finished+'%'; 356 357 /* Do not count the cloned images */ 358 if(my.circular) 359 { 360 i = i - (my.imageFocusMax*2); 361 completed = (finished < 1) ? 0 : Math.round((i/100)*finished); 362 } 363 364 var loadingP = document.getElementById(my.ImageFlowID+'_loading_txt'); 365 var loadingTxt = document.createTextNode('loading images '+completed+'/'+i); 366 loadingP.replaceChild(loadingTxt,loadingP.firstChild); 367 return finished; 368 }; 369 370 371 /* Cache EVERYTHING that only changes on refresh or resize of the window */ 372 this.refresh = function() 373 { 374 /* Cache global variables */ 375 this.imagesDivWidth = my.imagesDiv.offsetWidth+my.imagesDiv.offsetLeft; 376 this.maxHeight = Math.round(my.imagesDivWidth / my.aspectRatio); 377 this.maxFocus = my.imageFocusMax * my.xStep; 378 this.size = my.imagesDivWidth * 0.5; 379 this.sliderWidth = my.sliderWidth * 0.5; 380 this.scrollbarWidth = (my.imagesDivWidth - ( Math.round(my.sliderWidth) * 2)) * my.scrollbarP; 381 this.imagesDivHeight = Math.round(my.maxHeight * my.imagesHeight); 382 383 /* Change imageflow div properties */ 384 my.ImageFlowDiv.style.height = my.maxHeight + 'px'; 385 386 /* Change images div properties */ 387 my.imagesDiv.style.height = my.imagesDivHeight + 'px'; 388 389 /* Change images div properties */ 390 my.navigationDiv.style.height = (my.maxHeight - my.imagesDivHeight) + 'px'; 391 392 /* Change captions div properties */ 393 my.captionDiv.style.width = my.imagesDivWidth + 'px'; 394 my.captionDiv.style.paddingTop = Math.round(my.imagesDivWidth * 0.02) + 'px'; 395 396 /* Change scrollbar div properties */ 397 my.scrollbarDiv.style.width = my.scrollbarWidth + 'px'; 398 my.scrollbarDiv.style.marginTop = Math.round(my.imagesDivWidth * 0.02) + 'px'; 399 my.scrollbarDiv.style.marginLeft = Math.round(my.sliderWidth + ((my.imagesDivWidth - my.scrollbarWidth)/2)) + 'px'; 400 401 /* Set slider attributes */ 402 my.sliderDiv.style.cursor = my.sliderCursor; 403 my.sliderDiv.onmousedown = function () { my.MouseDrag.start(this); return false;}; 404 405 if(my.buttons) 406 { 407 my.buttonPreviousDiv.onclick = function () { my.MouseWheel.handle(1); }; 408 my.buttonNextDiv.onclick = function () { my.MouseWheel.handle(-1); }; 409 } 410 411 /* Set the reflection multiplicator */ 412 var multi = (my.reflections === true) ? my.reflectionP + 1 : 1; 413 414 /* Set image attributes */ 415 var max = my.imagesDiv.childNodes.length; 416 var i = 0; 417 var image = null; 418 for (var index = 0; index < max; index++) 419 { 420 image = my.imagesDiv.childNodes[index]; 421 if(image !== null && image.nodeType == 1 && image.nodeName == 'IMG') 422 { 423 this.indexArray[i] = index; 424 425 /* Set image attributes to store values */ 426 image.url = image.getAttribute('longdesc'); 427 image.xPosition = (-i * my.xStep); 428 image.i = i; 429 430 /* Add width and height as attributes only once */ 431 if(my.firstRefresh) 432 { 433 if(image.getAttribute('width') !== null && image.getAttribute('height') !== null) 434 { 435 image.w = image.getAttribute('width'); 436 image.h = image.getAttribute('height') * multi; 437 } 438 else{ 439 image.w = image.width; 440 image.h = image.height; 441 } 442 } 443 444 /* Check source image format. Get image height minus reflection height! */ 445 if((image.w) > (image.h / (my.reflectionP + 1))) 446 { 447 /* Landscape format */ 448 image.pc = my.percentLandscape; 449 image.pcMem = my.percentLandscape; 450 } 451 else 452 { 453 /* Portrait and square format */ 454 image.pc = my.percentOther; 455 image.pcMem = my.percentOther; 456 } 457 458 /* Change image positioning */ 459 if(my.imageScaling === false) 460 { 461 image.style.position = 'relative'; 462 image.style.display = 'inline'; 463 } 464 465 /* Set image cursor type */ 466 image.style.cursor = my.imageCursor; 467 i++; 468 } 469 } 470 this.max = my.indexArray.length; 471 472 /* Override dynamic sizes based on the first image */ 473 if(my.imageScaling === false) 474 { 475 image = my.imagesDiv.childNodes[my.indexArray[0]]; 476 477 /* Set left padding for the first image */ 478 this.totalImagesWidth = image.w * my.max; 479 image.style.paddingLeft = (my.imagesDivWidth/2) + (image.w/2) + 'px'; 480 481 /* Override images and navigation div height */ 482 my.imagesDiv.style.height = image.h + 'px'; 483 my.navigationDiv.style.height = (my.maxHeight - image.h) + 'px'; 484 } 485 486 /* Handle startID on the first refresh */ 487 if(my.firstRefresh) 488 { 489 /* Reset variable */ 490 my.firstRefresh = false; 491 492 /* Set imageID to the startID */ 493 my.imageID = my.startID-1; 494 if (my.imageID < 0 ) 495 { 496 my.imageID = 0; 497 } 498 499 /* Map image id range in cicular mode (ignore the cloned images) */ 500 if(my.circular) 501 { 502 my.imageID = my.imageID + my.imageFocusMax; 503 } 504 505 /* Make sure, that the id is smaller than the image count */ 506 maxId = (my.circular) ? (my.max-(my.imageFocusMax))-1 : my.max-1; 507 if (my.imageID > maxId) 508 { 509 my.imageID = maxId; 510 } 511 512 /* Toggle glide animation to start ID */ 513 if(my.glideToStartID === false) 514 { 515 my.moveTo(-my.imageID * my.xStep); 516 } 517 518 /* Animate images moving in from the right */ 519 if(my.startAnimation) 520 { 521 my.moveTo(5000); 522 } 523 } 524 525 /* Only animate if there is more than one image */ 526 if(my.max > 1) 527 { 528 my.glideTo(my.imageID); 529 } 530 531 /* Display images in current order */ 532 my.moveTo(my.current); 533 }; 534 535 536 /* Main animation function */ 537 this.moveTo = function(x) 538 { 539 this.current = x; 540 this.zIndex = my.max; 541 542 /* Main loop */ 543 for (var index = 0; index < my.max; index++) 544 { 545 var image = my.imagesDiv.childNodes[my.indexArray[index]]; 546 var currentImage = index * -my.xStep; 547 548 /* Enabled image scaling */ 549 if(my.imageScaling) 550 { 551 /* Don't display images that are not conf_focussed */ 552 if ((currentImage + my.maxFocus) < my.memTarget || (currentImage - my.maxFocus) > my.memTarget) 553 { 554 image.style.visibility = 'hidden'; 555 image.style.display = 'none'; 556 } 557 else 558 { 559 var z = (Math.sqrt(10000 + x * x) + 100) * my.imagesM; 560 var xs = x / z * my.size + my.size; 561 562 /* Still hide images until they are processed, but set display style to block */ 563 image.style.display = 'block'; 564 565 /* Process new image height and width */ 566 var newImageH = (image.h / image.w * image.pc) / z * my.size; 567 var newImageW = 0; 568 switch (newImageH > my.maxHeight) 569 { 570 case false: 571 newImageW = image.pc / z * my.size; 572 break; 573 574 default: 575 newImageH = my.maxHeight; 576 newImageW = image.w * newImageH / image.h; 577 break; 578 } 579 580 var newImageTop = (my.imagesDivHeight - newImageH) + ((newImageH / (my.reflectionP + 1)) * my.reflectionP); 581 582 /* Set new image properties */ 583 image.style.left = xs - (image.pc / 2) / z * my.size + 'px'; 584 if(newImageW && newImageH) 585 { 586 image.style.height = newImageH + 'px'; 587 image.style.width = newImageW + 'px'; 588 image.style.top = newImageTop + 'px'; 589 } 590 image.style.visibility = 'visible'; 591 592 /* Set image layer through zIndex */ 593 switch ( x < 0 ) 594 { 595 case true: 596 this.zIndex++; 597 break; 598 599 default: 600 this.zIndex = my.zIndex - 1; 601 break; 602 } 603 604 /* Change zIndex and onclick function of the focussed image */ 605 switch ( image.i == my.imageID ) 606 { 607 case false: 608 image.onclick = function() { my.glideTo(this.i);}; 609 break; 610 611 default: 612 this.zIndex = my.zIndex + 1; 613 if(image.url !== '') 614 { 615 image.onclick = my.onClick; 616 } 617 break; 618 } 619 image.style.zIndex = my.zIndex; 620 } 621 } 622 623 /* Disabled image scaling */ 624 else 625 { 626 if ((currentImage + my.maxFocus) < my.memTarget || (currentImage - my.maxFocus) > my.memTarget) 627 { 628 image.style.visibility = 'hidden'; 629 } 630 else 631 { 632 image.style.visibility = 'visible'; 633 634 /* Change onclick function of the focussed image */ 635 switch ( image.i == my.imageID ) 636 { 637 case false: 638 image.onclick = function() { my.glideTo(this.i);}; 639 break; 640 641 default: 642 if(image.url !== '') 643 { 644 image.onclick = my.onClick; 645 } 646 break; 647 } 648 } 649 my.imagesDiv.style.marginLeft = (x - my.totalImagesWidth) + 'px'; 650 } 651 652 x += my.xStep; 653 } 654 }; 655 656 657 /* Initializes image gliding animation */ 658 this.glideTo = function(imageID) 659 { 660 /* Check for jumppoints */ 661 var jumpTarget, clonedImageID; 662 if(my.circular) 663 { 664 /* Trigger left jumppoint */ 665 if(imageID+1 === my.imageFocusMax) 666 { 667 /* Set jump target to the same cloned image on the right */ 668 clonedImageID = my.max - my.imageFocusMax; 669 jumpTarget = -clonedImageID * my.xStep; 670 671 /* Set the imageID to the last image */ 672 imageID = clonedImageID-1 ; 673 } 674 675 /* Trigger right jumppoint */ 676 if(imageID === (my.max - my.imageFocusMax)) 677 { 678 /* Set jump target to the same cloned image on the left */ 679 clonedImageID = my.imageFocusMax-1; 680 jumpTarget = -clonedImageID * my.xStep; 681 682 /* Set the imageID to the first image */ 683 imageID = clonedImageID+1; 684 } 685 } 686 687 /* Calculate new image position target */ 688 var x = -imageID * my.xStep; 689 this.target = x; 690 this.memTarget = x; 691 this.imageID = imageID; 692 693 /* Display new caption */ 694 var caption = my.imagesDiv.childNodes[imageID].getAttribute('alt'); 695 if (caption === '' || my.captions === false) 696 { 697 caption = ' '; 698 } 699 my.captionDiv.innerHTML = caption; 700 701 /* Set scrollbar slider to new position */ 702 if (my.MouseDrag.busy === false) 703 { 704 if(my.circular) 705 { 706 this.newSliderX = ((imageID-my.imageFocusMax) * my.scrollbarWidth) / (my.max-(my.imageFocusMax*2)-1) - my.MouseDrag.newX; 707 } 708 else 709 { 710 this.newSliderX = (imageID * my.scrollbarWidth) / (my.max-1) - my.MouseDrag.newX; 711 } 712 my.sliderDiv.style.marginLeft = (my.newSliderX - my.sliderWidth) + 'px'; 713 } 714 715 /* Only process if opacity or a multiplicator for the focussed image has been set */ 716 if(my.opacity === true || my.imageFocusM !== my.defaults.imageFocusM) 717 { 718 /* Set opacity for centered image */ 719 my.Helper.setOpacity(my.imagesDiv.childNodes[imageID], my.opacityArray[0]); 720 my.imagesDiv.childNodes[imageID].pc = my.imagesDiv.childNodes[imageID].pc * my.imageFocusM; 721 722 /* Set opacity for the other images that are displayed */ 723 var opacityValue = 0; 724 var rightID = 0; 725 var leftID = 0; 726 var last = my.opacityArray.length; 727 728 for (var i = 1; i < (my.imageFocusMax+1); i++) 729 { 730 if((i+1) > last) 731 { 732 opacityValue = my.opacityArray[last-1]; 733 } 734 else 735 { 736 opacityValue = my.opacityArray[i]; 737 } 738 739 rightID = imageID + i; 740 leftID = imageID - i; 741 742 if (rightID < my.max) 743 { 744 my.Helper.setOpacity(my.imagesDiv.childNodes[rightID], opacityValue); 745 my.imagesDiv.childNodes[rightID].pc = my.imagesDiv.childNodes[rightID].pcMem; 746 } 747 if (leftID >= 0) 748 { 749 my.Helper.setOpacity(my.imagesDiv.childNodes[leftID], opacityValue); 750 my.imagesDiv.childNodes[leftID].pc = my.imagesDiv.childNodes[leftID].pcMem; 751 } 752 } 753 } 754 755 /* Move the images to the jump target */ 756 if(jumpTarget) 757 { 758 my.moveTo(jumpTarget); 759 } 760 761 /* Animate gliding to new x position */ 762 if (my.busy === false) 763 { 764 my.busy = true; 765 my.animate(); 766 } 767 }; 768 769 770 /* Animates image gliding */ 771 this.animate = function() 772 { 773 switch (my.target < my.current-1 || my.target > my.current+1) 774 { 775 case true: 776 my.moveTo(my.current + (my.target-my.current)/3); 777 window.setTimeout(my.animate, my.animationSpeed); 778 my.busy = true; 779 break; 780 781 default: 782 my.busy = false; 783 break; 784 } 785 }; 786 787 788 /* Used by user events to call the glideTo function */ 789 this.glideOnEvent = function(imageID) 790 { 791 /* Interrupt slideshow on mouse wheel, keypress, touch and mouse drag */ 792 if(my.slideshow) 793 { 794 my.Slideshow.interrupt(); 795 } 796 797 /* Glide to new imageID */ 798 my.glideTo(imageID); 799 }; 800 801 802 /* Slideshow function */ 803 this.Slideshow = 804 { 805 direction: 1, 806 807 init: function() 808 { 809 /* Call start() if autoplay is enabled, stop() if it is disabled */ 810 (my.slideshowAutoplay) ? my.Slideshow.start() : my.Slideshow.stop(); 811 }, 812 813 interrupt: function() 814 { 815 /* Remove interrupt event */ 816 my.Helper.removeEvent(my.ImageFlowDiv,'click',my.Slideshow.interrupt); 817 818 /* Interrupt the slideshow */ 819 my.Slideshow.stop(); 820 }, 821 822 addInterruptEvent: function() 823 { 824 /* A click anywhere inside the ImageFlow div interrupts the slideshow */ 825 my.Helper.addEvent(my.ImageFlowDiv,'click',my.Slideshow.interrupt); 826 }, 827 828 start: function() 829 { 830 /* Set button style to pause */ 831 my.Helper.setClassName(my.buttonSlideshow, 'slideshow pause'); 832 833 /* Set onclick behaviour to stop */ 834 my.buttonSlideshow.onclick = function () { my.Slideshow.stop(); }; 835 836 /* Set slide interval */ 837 my.Slideshow.action = window.setInterval(my.Slideshow.slide, my.slideshowSpeed); 838 839 /* Allow the user to always interrupt the slideshow */ 840 window.setTimeout(my.Slideshow.addInterruptEvent, 100); 841 }, 842 843 stop: function() 844 { 845 /* Set button style to play */ 846 my.Helper.setClassName(my.buttonSlideshow, 'slideshow play'); 847 848 /* Set onclick behaviour to start */ 849 my.buttonSlideshow.onclick = function () { my.Slideshow.start(); }; 850 851 /* Clear slide interval */ 852 window.clearInterval(my.Slideshow.action); 853 }, 854 855 slide: function() 856 { 857 var newImageID = my.imageID + my.Slideshow.direction; 858 var reverseDirection = false; 859 860 /* Reverse direction at the last image on the right */ 861 if(newImageID === my.max) 862 { 863 my.Slideshow.direction = -1; 864 reverseDirection = true; 865 } 866 867 /* Reverse direction at the last image on the left */ 868 if(newImageID < 0) 869 { 870 my.Slideshow.direction = 1; 871 reverseDirection = true; 872 } 873 874 /* If direction is reversed recall this method, else call the glideTo method */ 875 (reverseDirection) ? my.Slideshow.slide() : my.glideTo(newImageID); 876 } 877 }; 878 879 880 /* Mouse Wheel support */ 881 this.MouseWheel = 882 { 883 init: function() 884 { 885 /* Init mouse wheel listener */ 886 if(window.addEventListener) 887 { 888 my.ImageFlowDiv.addEventListener('DOMMouseScroll', my.MouseWheel.get, false); 889 } 890 my.Helper.addEvent(my.ImageFlowDiv,'mousewheel',my.MouseWheel.get); 891 }, 892 893 get: function(event) 894 { 895 var delta = 0; 896 if (!event) 897 { 898 event = window.event; 899 } 900 if (event.wheelDelta) 901 { 902 delta = event.wheelDelta / 120; 903 } 904 else if (event.detail) 905 { 906 delta = -event.detail / 3; 907 } 908 if (delta) 909 { 910 my.MouseWheel.handle(delta); 911 } 912 my.Helper.suppressBrowserDefault(event); 913 }, 914 915 handle: function(delta) 916 { 917 var change = false; 918 var newImageID = 0; 919 if(delta > 0) 920 { 921 if(my.imageID >= 1) 922 { 923 newImageID = my.imageID -1; 924 change = true; 925 } 926 } 927 else 928 { 929 if(my.imageID < (my.max-1)) 930 { 931 newImageID = my.imageID +1; 932 change = true; 933 } 934 } 935 936 /* Glide to next (mouse wheel down) / previous (mouse wheel up) image */ 937 if(change) 938 { 939 my.glideOnEvent(newImageID); 940 } 941 } 942 }; 943 944 945 /* Mouse Dragging */ 946 this.MouseDrag = 947 { 948 object: null, 949 objectX: 0, 950 mouseX: 0, 951 newX: 0, 952 busy: false, 953 954 /* Init mouse event listener */ 955 init: function() 956 { 957 my.Helper.addEvent(my.ImageFlowDiv,'mousemove',my.MouseDrag.drag); 958 my.Helper.addEvent(my.ImageFlowDiv,'mouseup',my.MouseDrag.stop); 959 my.Helper.addEvent(document,'mouseup',my.MouseDrag.stop); 960 961 /* Avoid text and image selection while dragging */ 962 my.ImageFlowDiv.onselectstart = function () 963 { 964 var selection = true; 965 if (my.MouseDrag.busy) 966 { 967 selection = false; 968 } 969 return selection; 970 }; 971 }, 972 973 start: function(o) 974 { 975 my.MouseDrag.object = o; 976 my.MouseDrag.objectX = my.MouseDrag.mouseX - o.offsetLeft + my.newSliderX; 977 }, 978 979 stop: function() 980 { 981 my.MouseDrag.object = null; 982 my.MouseDrag.busy = false; 983 }, 984 985 drag: function(e) 986 { 987 var posx = 0; 988 if (!e) 989 { 990 e = window.event; 991 } 992 if (e.pageX) 993 { 994 posx = e.pageX; 995 } 996 else if (e.clientX) 997 { 998 posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 999 } 1000 my.MouseDrag.mouseX = posx; 1001 1002 if(my.MouseDrag.object !== null) 1003 { 1004 var newX = (my.MouseDrag.mouseX - my.MouseDrag.objectX) + my.sliderWidth; 1005 1006 /* Make sure, that the slider is moved in proper relation to previous movements by the glideTo function */ 1007 if(newX < ( - my.newSliderX)) 1008 { 1009 newX = - my.newSliderX; 1010 } 1011 if(newX > (my.scrollbarWidth - my.newSliderX)) 1012 { 1013 newX = my.scrollbarWidth - my.newSliderX; 1014 } 1015 1016 /* Set new slider position */ 1017 var step, imageID; 1018 if(my.circular) 1019 { 1020 step = (newX + my.newSliderX) / (my.scrollbarWidth / (my.max-(my.imageFocusMax*2)-1)); 1021 imageID = Math.round(step)+my.imageFocusMax; 1022 } 1023 else 1024 { 1025 step = (newX + my.newSliderX) / (my.scrollbarWidth / (my.max-1)); 1026 imageID = Math.round(step); 1027 } 1028 my.MouseDrag.newX = newX; 1029 my.MouseDrag.object.style.left = newX + 'px'; 1030 if(my.imageID !== imageID) 1031 { 1032 my.glideOnEvent(imageID); 1033 } 1034 my.MouseDrag.busy = true; 1035 } 1036 } 1037 }; 1038 1039 1040 /* Safari touch events on the iPhone and iPod Touch */ 1041 this.Touch = 1042 { 1043 x: 0, 1044 startX: 0, 1045 stopX: 0, 1046 busy: false, 1047 first: true, 1048 1049 /* Init touch event listener */ 1050 init: function() 1051 { 1052 my.Helper.addEvent(my.navigationDiv,'touchstart',my.Touch.start); 1053 my.Helper.addEvent(document,'touchmove',my.Touch.handle); 1054 my.Helper.addEvent(document,'touchend',my.Touch.stop); 1055 }, 1056 1057 isOnNavigationDiv: function(e) 1058 { 1059 var state = false; 1060 if(e.touches) 1061 { 1062 var target = e.touches[0].target; 1063 if(target === my.navigationDiv || target === my.sliderDiv || target === my.scrollbarDiv) 1064 { 1065 state = true; 1066 } 1067 } 1068 return state; 1069 }, 1070 1071 getX: function(e) 1072 { 1073 var x = 0; 1074 if(e.touches) 1075 { 1076 x = e.touches[0].pageX; 1077 } 1078 return x; 1079 }, 1080 1081 start: function(e) 1082 { 1083 my.Touch.startX = my.Touch.getX(e); 1084 my.Touch.busy = true; 1085 my.Helper.suppressBrowserDefault(e); 1086 }, 1087 1088 isBusy: function() 1089 { 1090 var busy = false; 1091 if(my.Touch.busy) 1092 { 1093 busy = true; 1094 } 1095 return busy; 1096 }, 1097 1098 /* Handle touch event position within the navigation div */ 1099 handle: function(e) 1100 { 1101 if(my.Touch.isBusy && my.Touch.isOnNavigationDiv(e)) 1102 { 1103 var max = (my.circular) ? (my.max-(my.imageFocusMax*2)-1) : (my.max-1); 1104 if(my.Touch.first) 1105 { 1106 my.Touch.stopX = (max - my.imageID) * (my.imagesDivWidth / max); 1107 my.Touch.first = false; 1108 } 1109 var newX = -(my.Touch.getX(e) - my.Touch.startX - my.Touch.stopX); 1110 1111 /* Map x-axis touch coordinates in range of the ImageFlow width */ 1112 if(newX < 0) 1113 { 1114 newX = 0; 1115 } 1116 if(newX > my.imagesDivWidth) 1117 { 1118 newX = my.imagesDivWidth; 1119 } 1120 1121 my.Touch.x = newX; 1122 1123 var imageID = Math.round(newX / (my.imagesDivWidth / max)); 1124 imageID = max - imageID; 1125 if(my.imageID !== imageID) 1126 { 1127 if(my.circular) 1128 { 1129 imageID = imageID + my.imageFocusMax; 1130 } 1131 my.glideOnEvent(imageID); 1132 } 1133 my.Helper.suppressBrowserDefault(e); 1134 } 1135 }, 1136 1137 stop: function() 1138 { 1139 my.Touch.stopX = my.Touch.x; 1140 my.Touch.busy = false; 1141 } 1142 }; 1143 1144 1145 /* Key support */ 1146 this.Key = 1147 { 1148 /* Init key event listener */ 1149 init: function() 1150 { 1151 document.onkeydown = function(event){ my.Key.handle(event); }; 1152 }, 1153 1154 /* Handle the arrow keys */ 1155 handle: function(event) 1156 { 1157 var charCode = my.Key.get(event); 1158 switch (charCode) 1159 { 1160 /* Right arrow key */ 1161 case 39: 1162 my.MouseWheel.handle(-1); 1163 break; 1164 1165 /* Left arrow key */ 1166 case 37: 1167 my.MouseWheel.handle(1); 1168 break; 1169 } 1170 }, 1171 1172 /* Get the current keycode */ 1173 get: function(event) 1174 { 1175 event = event || window.event; 1176 return event.keyCode; 1177 } 1178 }; 1179 1180 1181 /* Helper functions */ 1182 this.Helper = 1183 { 1184 /* Add events */ 1185 addEvent: function(obj, type, fn) 1186 { 1187 if(obj.addEventListener) 1188 { 1189 obj.addEventListener(type, fn, false); 1190 } 1191 else if(obj.attachEvent) 1192 { 1193 obj["e"+type+fn] = fn; 1194 obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }; 1195 obj.attachEvent( "on"+type, obj[type+fn] ); 1196 } 1197 }, 1198 1199 /* Remove events */ 1200 removeEvent: function( obj, type, fn ) 1201 { 1202 if (obj.removeEventListener) 1203 { 1204 obj.removeEventListener( type, fn, false ); 1205 } 1206 else if (obj.detachEvent) 1207 { 1208 /* The IE breaks if you're trying to detach an unattached event http://msdn.microsoft.com/en-us/library/ms536411(VS.85).aspx */ 1209 if(obj[type+fn] === undefined) 1210 { 1211 alert('Helper.removeEvent » Pointer to detach event is undefined - perhaps you are trying to detach an unattached event?'); 1212 } 1213 obj.detachEvent( 'on'+type, obj[type+fn] ); 1214 obj[type+fn] = null; 1215 obj['e'+type+fn] = null; 1216 } 1217 }, 1218 1219 /* Set image opacity */ 1220 setOpacity: function(object, value) 1221 { 1222 if(my.opacity === true) 1223 { 1224 object.style.opacity = value/10; 1225 object.style.filter = 'alpha(opacity=' + value*10 + ')'; 1226 } 1227 }, 1228 1229 /* Create HTML elements */ 1230 createDocumentElement: function(type, id, optionalClass) 1231 { 1232 var element = document.createElement(type); 1233 element.setAttribute('id', my.ImageFlowID+'_'+id); 1234 if(optionalClass !== undefined) 1235 { 1236 id += ' '+optionalClass; 1237 } 1238 my.Helper.setClassName(element, id); 1239 return element; 1240 }, 1241 1242 /* Set CSS class */ 1243 setClassName: function(element, className) 1244 { 1245 if(element) 1246 { 1247 element.setAttribute('class', className); 1248 element.setAttribute('className', className); 1249 } 1250 }, 1251 1252 /* Suppress default browser behaviour to avoid image/text selection while dragging */ 1253 suppressBrowserDefault: function(e) 1254 { 1255 if(e.preventDefault) 1256 { 1257 e.preventDefault(); 1258 } 1259 else 1260 { 1261 e.returnValue = false; 1262 } 1263 return false; 1264 }, 1265 1266 /* Add functions to the window.onresize event - can not be done by addEvent */ 1267 addResizeEvent: function() 1268 { 1269 var otherFunctions = window.onresize; 1270 if(typeof window.onresize != 'function') 1271 { 1272 window.onresize = function() 1273 { 1274 my.refresh(); 1275 }; 1276 } 1277 else 1278 { 1279 window.onresize = function(){ 1280 if (otherFunctions) 1281 { 1282 otherFunctions(); 1283 } 1284 my.refresh(); 1285 }; 1286 } 1287 } 1288 }; 1289 } 1290 1291 /* DOMContentLoaded event handler - by Tanny O'Haley [4] */ 1292 var domReadyEvent = 1293 { 1294 name: "domReadyEvent", 1295 /* Array of DOMContentLoaded event handlers.*/ 1296 events: {}, 1297 domReadyID: 1, 1298 bDone: false, 1299 DOMContentLoadedCustom: null, 1300 1301 /* Function that adds DOMContentLoaded listeners to the array.*/ 1302 add: function(handler) 1303 { 1304 /* Assign each event handler a unique ID. If the handler has an ID, it has already been added to the events object or been run.*/ 1305 if (!handler.$$domReadyID) 1306 { 1307 handler.$$domReadyID = this.domReadyID++; 1308 1309 /* If the DOMContentLoaded event has happened, run the function. */ 1310 if(this.bDone) 1311 { 1312 handler(); 1313 } 1314 1315 /* store the event handler in the hash table */ 1316 this.events[handler.$$domReadyID] = handler; 1317 } 1318 }, 1319 1320 remove: function(handler) 1321 { 1322 /* Delete the event handler from the hash table */ 1323 if (handler.$$domReadyID) 1324 { 1325 delete this.events[handler.$$domReadyID]; 1326 } 1327 }, 1328 1329 /* Function to process the DOMContentLoaded events array. */ 1330 run: function() 1331 { 1332 /* quit if this function has already been called */ 1333 if (this.bDone) 1334 { 1335 return; 1336 } 1337 1338 /* Flag this function so we don't do the same thing twice */ 1339 this.bDone = true; 1340 1341 /* iterates through array of registered functions */ 1342 for (var i in this.events) 1343 { 1344 this.events[i](); 1345 } 1346 }, 1347 1348 schedule: function() 1349 { 1350 /* Quit if the init function has already been called*/ 1351 if (this.bDone) 1352 { 1353 return; 1354 } 1355 1356 /* First, check for Safari or KHTML.*/ 1357 if(/KHTML|WebKit/i.test(navigator.userAgent)) 1358 { 1359 if(/loaded|complete/.test(document.readyState)) 1360 { 1361 this.run(); 1362 } 1363 else 1364 { 1365 /* Not ready yet, wait a little more.*/ 1366 setTimeout(this.name + ".schedule()", 100); 1367 } 1368 } 1369 else if(document.getElementById("__ie_onload")) 1370 { 1371 /* Second, check for IE.*/ 1372 return true; 1373 } 1374 1375 /* Check for custom developer provided function.*/ 1376 if(typeof this.DOMContentLoadedCustom === "function") 1377 { 1378 /* if DOM methods are supported, and the body element exists (using a double-check 1379 including document.body, for the benefit of older moz builds [eg ns7.1] in which 1380 getElementsByTagName('body')[0] is undefined, unless this script is in the body section) */ 1381 if(typeof document.getElementsByTagName !== 'undefined' && (document.getElementsByTagName('body')[0] !== null || document.body !== null)) 1382 { 1383 /* Call custom function. */ 1384 if(this.DOMContentLoadedCustom()) 1385 { 1386 this.run(); 1387 } 1388 else 1389 { 1390 /* Not ready yet, wait a little more. */ 1391 setTimeout(this.name + ".schedule()", 250); 1392 } 1393 } 1394 } 1395 return true; 1396 }, 1397 1398 init: function() 1399 { 1400 /* If addEventListener supports the DOMContentLoaded event.*/ 1401 if(document.addEventListener) 1402 { 1403 document.addEventListener("DOMContentLoaded", function() { domReadyEvent.run(); }, false); 1404 } 1405 1406 /* Schedule to run the init function.*/ 1407 setTimeout("domReadyEvent.schedule()", 100); 1408 1409 function run() 1410 { 1411 domReadyEvent.run(); 1412 } 1413 1414 /* Just in case window.onload happens first, add it to onload using an available method.*/ 1415 if(typeof addEvent !== "undefined") 1416 { 1417 addEvent(window, "load", run); 1418 } 1419 else if(document.addEventListener) 1420 { 1421 document.addEventListener("load", run, false); 1422 } 1423 else if(typeof window.onload === "function") 1424 { 1425 var oldonload = window.onload; 1426 window.onload = function() 1427 { 1428 domReadyEvent.run(); 1429 oldonload(); 1430 }; 1431 } 1432 else 1433 { 1434 window.onload = run; 1435 } 1436 1437 /* for Internet Explorer */ 1438 /*@cc_on 1439 @if (@_win32 || @_win64) 1440 document.write("<script id=__ie_onload defer src=\"//:\"><\/script>"); 1441 var script = document.getElementById("__ie_onload"); 1442 script.onreadystatechange = function() 1443 { 1444 if (this.readyState == "complete") 1445 { 1446 domReadyEvent.run(); // call the onload handler 1447 } 1448 }; 1449 @end 1450 @*/ 1451 } 1452 }; 1453 1454 var domReady = function(handler) { domReadyEvent.add(handler); }; 1455 domReadyEvent.init(); 1456 1457 1458 /* Create ImageFlow instances when the DOM structure has been loaded */ 1459 domReady(function() 1460 { 1461 var instanceOne = new ImageFlow(); 1462 instanceOne.init({ ImageFlowID: 'myImageFlow', 1463 onClick: function() { return hs.expand(this, 1464 { src: this.getAttribute('longdesc') } ); } }); 1465 // instanceOne.init({ ImageFlowID:'myImageFlow' }); 1466 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |