/* imageflow constructor */ function imageflow() { /* setting option defaults */ this.defaults = { animationspeed: 50, /* animation speed in ms */ aspectratio: 2.3, /* aspect ratio of the imageflow container (width divided by height) */ buttons: false, /* toggle navigation buttons */ captions: false, /* toggle captions */ circular: true, /* 循环 */ imagecursor: 'pointer', /* cursor type for all images - default is 'default' */ imageflowid: 'imageflow', /* default id of the imageflow container */ imagefocusm: 1.0, /* multiplicator for the focussed image size in percent */ imagefocusmax: 3, /* 左右二侧图片数量 */ imagepath: '', /* path to the images relative to the reflect_.php script */ imagescaling: true, /* toggle image scaling */ imagesheight: 0.66, /* 高宽比例 */ imagesm: 1.1, /* 图片深度 */ onclick: function () { document.location = this.url; }, /* onclick behaviour */ opacity: false, /* toggle image opacity */ opacityarray: [10, 8, 6, 4, 2], /* image opacity (range: 0 to 10) first value is for the focussed image */ percentlandscape: 118, /* scale landscape format */ percentother: 120, /* scale portrait and square format */ preloadimages: true, /* toggles loading bar (false: requires img attributes height and width) */ reflections: true, /* toggle reflections */ reflectionget: '', /* pass variables via the get method to the reflect_.php script */ reflectionp: 0.5, /* height of the reflection in percent of the source image */ reflectionpng: false, /* toggle reflect2.php or reflect3.php */ reflectpath: '', /* path to the reflect_.php script */ scrollbarp: 0.6, /* width of the scrollbar in percent */ slider: true, /* toggle slider */ slidercursor: 'e-resize', /* slider cursor type - default is 'default' */ sliderwidth: 14, /* width of the slider in px */ slideshow: true, /* toggle slideshow */ slideshowspeed: 3000, /* time between slides in ms */ slideshowautoplay: true, /* toggle automatic slideshow play on startup */ startid: 1, /* image id to begin with */ glidetostartid: true, /* toggle glide animation to start id */ startanimation: false, /* animate images moving in from the right on startup */ xstep: 90 /* step width on the x-axis in px */ }; /* closure for this */ var my = this; /* initiate imageflow */ this.init = function (options) { /* evaluate options */ for (var name in my.defaults) { this[name] = (options !== undefined && options[name] !== undefined) ? options[name] : my.defaults[name]; } /* try to get imageflow div element */ var imageflowdiv = document.getelementbyid(my.imageflowid); if (imageflowdiv) { /* set it global within the imageflow scope */ imageflowdiv.style.visibility = 'visible'; this.imageflowdiv = imageflowdiv; /* try to create xhtml structure */ if (this.createstructure()) { this.imagesdiv = document.getelementbyid(my.imageflowid + '_images'); this.captiondiv = document.getelementbyid(my.imageflowid + '_caption'); this.navigationdiv = document.getelementbyid(my.imageflowid + '_navigation'); this.scrollbardiv = document.getelementbyid(my.imageflowid + '_scrollbar'); this.sliderdiv = document.getelementbyid(my.imageflowid + '_slider'); this.buttonnextdiv = document.getelementbyid(my.imageflowid + '_next'); this.buttonpreviousdiv = document.getelementbyid(my.imageflowid + '_previous'); this.buttonslideshow = document.getelementbyid(my.imageflowid + '_slideshow'); this.indexarray = []; this.current = 0; this.imageid = 0; this.target = 0; this.memtarget = 0; this.firstrefresh = true; this.firstcheck = true; this.busy = false; /* set height of the imageflow container and center the loading bar */ var width = this.imageflowdiv.offsetwidth; var height = math.round(width / my.aspectratio); document.getelementbyid(my.imageflowid + '_loading_txt').style.paddingtop = ((height * 0.5) - 22) + 'px'; imageflowdiv.style.height = height + 'px'; /* init loading progress */ this.loadingprogress(); } } }; /* create html structure */ this.createstructure = function () { /* create images div container */ var imagesdiv = my.helper.createdocumentelement('div', 'images'); /* shift all images into the images div */ var node, version, src, imagenode; var max = my.imageflowdiv.childnodes.length; for (var index = 0; index < max; index++) { node = my.imageflowdiv.childnodes[index]; if (node && node.nodetype == 1 && node.nodename == 'img') { /* add 'reflect.php?img=' */ if (my.reflections === true) { version = (my.reflectionpng) ? '3' : '2'; src = my.imagepath + node.getattribute('src', 2); //src = my.reflectpath+'reflect'+version+'.php?img='+src+my.reflectionget; node.setattribute('src', src); } /* clone image nodes and append them to the images div */ imagenode = node.clonenode(true); imagesdiv.appendchild(imagenode); } } /* clone some more images to make a circular animation possible */ if (my.circular) { /* create temporary elements to hold the cloned images */ var first = my.helper.createdocumentelement('div', 'images'); var last = my.helper.createdocumentelement('div', 'images'); /* make sure, that there are enough images to use circular mode */ max = imagesdiv.childnodes.length; if (max < my.imagefocusmax) { my.imagefocusmax = max; } /* do not clone anything if there is only one image */ if (max > 1) { /* clone the first and last images */ var i; for (i = 0; i < max; i++) { /* number of clones on each side equals the imagefocusmax */ node = imagesdiv.childnodes[i]; if (i < my.imagefocusmax) { imagenode = node.clonenode(true); first.appendchild(imagenode); } if (max - i < my.imagefocusmax + 1) { imagenode = node.clonenode(true); last.appendchild(imagenode); } } /* sort the image nodes in the following order: last | originals | first */ for (i = 0; i < max; i++) { node = imagesdiv.childnodes[i]; imagenode = node.clonenode(true); last.appendchild(imagenode); } for (i = 0; i < my.imagefocusmax; i++) { node = first.childnodes[i]; imagenode = node.clonenode(true); last.appendchild(imagenode); } /* overwrite the imagesdiv with the new order */ imagesdiv = last; } } /* create slideshow button div and append it to the images div */ if (my.slideshow) { var slideshowbutton = my.helper.createdocumentelement('div', 'slideshow'); imagesdiv.appendchild(slideshowbutton); } /* create loading text container */ var loadingp = my.helper.createdocumentelement('p', 'loading_txt'); var loadingtext = document.createtextnode(' '); loadingp.appendchild(loadingtext); /* create loading div container */ var loadingdiv = my.helper.createdocumentelement('div', 'loading'); /* create loading bar div container inside the loading div */ var loadingbardiv = my.helper.createdocumentelement('div', 'loading_bar'); loadingdiv.appendchild(loadingbardiv); /* create captions div container */ var captiondiv = my.helper.createdocumentelement('div', 'caption'); /* create slider and button div container inside the scrollbar div */ var scrollbardiv = my.helper.createdocumentelement('div', 'scrollbar'); var sliderdiv = my.helper.createdocumentelement('div', 'slider'); scrollbardiv.appendchild(sliderdiv); if (my.buttons) { var buttonpreviousdiv = my.helper.createdocumentelement('div', 'previous', 'button'); var buttonnextdiv = my.helper.createdocumentelement('div', 'next', 'button'); scrollbardiv.appendchild(buttonpreviousdiv); scrollbardiv.appendchild(buttonnextdiv); } /* create navigation div container beneath images div */ var navigationdiv = my.helper.createdocumentelement('div', 'navigation'); navigationdiv.appendchild(captiondiv); navigationdiv.appendchild(scrollbardiv); /* update document structure and return true on success */ var success = false; if (my.imageflowdiv.appendchild(imagesdiv) && my.imageflowdiv.appendchild(loadingp) && my.imageflowdiv.appendchild(loadingdiv) && my.imageflowdiv.appendchild(navigationdiv)) { /* remove image nodes outside the images div */ max = my.imageflowdiv.childnodes.length; for (index = 0; index < max; index++) { node = my.imageflowdiv.childnodes[index]; if (node && node.nodetype == 1 && node.nodename == 'img') { my.imageflowdiv.removechild(node); } } success = true; } return success; }; /* manage loading progress and call the refresh function */ this.loadingprogress = function () { var p = my.loadingstatus(); if ((p < 100 || my.firstcheck) && my.preloadimages) { /* insert a short delay if the browser loads rapidly from its cache */ if (my.firstcheck && p == 100) { my.firstcheck = false; window.settimeout(my.loadingprogress, 100); } else { window.settimeout(my.loadingprogress, 40); } } else { /* hide loading elements */ document.getelementbyid(my.imageflowid + '_loading_txt').style.display = 'none'; document.getelementbyid(my.imageflowid + '_loading').style.display = 'none'; /* refresh imageflow on window resize - delay adding this event for the ie */ window.settimeout(my.helper.addresizeevent, 1000); /* call refresh once on startup to display images */ my.refresh(); /* only initialize navigation elements if there is more than one image */ if (my.max > 1) { /* initialize mouse, touch and key support */ my.mousewheel.init(); my.mousedrag.init(); my.touch.init(); my.key.init(); /* toggle slideshow */ if (my.slideshow) { my.slideshow.init(); } /* toggle scrollbar visibility */ if (my.slider) { my.scrollbardiv.style.visibility = 'visible'; } } } }; /* return loaded images in percent, set loading bar width and loading text */ this.loadingstatus = function () { var max = my.imagesdiv.childnodes.length; var i = 0, completed = 0; var image = null; for (var index = 0; index < max; index++) { image = my.imagesdiv.childnodes[index]; if (image && image.nodetype == 1 && image.nodename == 'img') { if (image.complete) { completed++; } i++; } } var finished = math.round((completed / i) * 100); var loadingbar = document.getelementbyid(my.imageflowid + '_loading_bar'); loadingbar.style.width = finished + '%'; /* do not count the cloned images */ if (my.circular) { i = i - (my.imagefocusmax * 2); completed = (finished < 1) ? 0 : math.round((i / 100) * finished); } var loadingp = document.getelementbyid(my.imageflowid + '_loading_txt'); var loadingtxt = document.createtextnode('正在加载,请稍候 ' + completed + '/' + i); loadingp.replacechild(loadingtxt, loadingp.firstchild); return finished; }; /* cache everything that only changes on refresh or resize of the window */ this.refresh = function () { /* cache global variables */ this.imagesdivwidth = my.imagesdiv.offsetwidth + my.imagesdiv.offsetleft; this.maxheight = math.round(my.imagesdivwidth / my.aspectratio); this.maxfocus = my.imagefocusmax * my.xstep; this.size = my.imagesdivwidth * 0.5; this.sliderwidth = my.sliderwidth * 0.5; this.scrollbarwidth = (my.imagesdivwidth - (math.round(my.sliderwidth) * 2)) * my.scrollbarp; this.imagesdivheight = math.round(my.maxheight * my.imagesheight); /* change imageflow div properties */ my.imageflowdiv.style.height = my.maxheight + 'px'; /* change images div properties */ my.imagesdiv.style.height = my.imagesdivheight + 'px'; /* change images div properties */ my.navigationdiv.style.height = (my.maxheight - my.imagesdivheight) + 'px'; /* change captions div properties */ my.captiondiv.style.width = my.imagesdivwidth + 'px'; my.captiondiv.style.paddingtop = math.round(my.imagesdivwidth * 0.02) + 'px'; /* change scrollbar div properties */ my.scrollbardiv.style.width = my.scrollbarwidth + 'px'; my.scrollbardiv.style.margintop = math.round(my.imagesdivwidth * 0.02) + 'px'; my.scrollbardiv.style.marginleft = math.round(my.sliderwidth + ((my.imagesdivwidth - my.scrollbarwidth) / 2)) + 'px'; /* set slider attributes */ my.sliderdiv.style.cursor = my.slidercursor; my.sliderdiv.onmousedown = function () { my.mousedrag.start(this); return false; }; if (my.buttons) { my.buttonpreviousdiv.onclick = function () { my.mousewheel.handle(1); }; my.buttonnextdiv.onclick = function () { my.mousewheel.handle(-1); }; } /* set the reflection multiplicator */ var multi = (my.reflections === true) ? my.reflectionp + 1 : 1; /* set image attributes */ var max = my.imagesdiv.childnodes.length; var i = 0; var image = null; for (var index = 0; index < max; index++) { image = my.imagesdiv.childnodes[index]; if (image !== null && image.nodetype == 1 && image.nodename == 'img') { this.indexarray[i] = index; /* set image attributes to store values */ image.url = image.getattribute('longdesc'); image.xposition = (-i * my.xstep); image.i = i; /* add width and height as attributes only once */ if (my.firstrefresh) { if (image.getattribute('width') !== null && image.getattribute('height') !== null) { image.w = image.getattribute('width'); image.h = image.getattribute('height') * multi; } else { image.w = image.width; image.h = image.height; } } /* check source image format. get image height minus reflection height! */ if ((image.w) > (image.h / (my.reflectionp + 1))) { /* landscape format */ image.pc = my.percentlandscape; image.pcmem = my.percentlandscape; } else { /* portrait and square format */ image.pc = my.percentother; image.pcmem = my.percentother; } /* change image positioning */ if (my.imagescaling === false) { image.style.position = 'relative'; image.style.display = 'inline'; } /* set image cursor type */ image.style.cursor = my.imagecursor; i++; } } this.max = my.indexarray.length; /* override dynamic sizes based on the first image */ if (my.imagescaling === false) { image = my.imagesdiv.childnodes[my.indexarray[0]]; /* set left padding for the first image */ this.totalimageswidth = image.w * my.max; image.style.paddingleft = (my.imagesdivwidth / 2) + (image.w / 2) + 'px'; /* override images and navigation div height */ my.imagesdiv.style.height = image.h + 'px'; my.navigationdiv.style.height = (my.maxheight - image.h) + 'px'; } /* handle startid on the first refresh */ if (my.firstrefresh) { /* reset variable */ my.firstrefresh = false; /* set imageid to the startid */ my.imageid = my.startid - 1; if (my.imageid < 0) { my.imageid = 0; } /* map image id range in cicular mode (ignore the cloned images) */ if (my.circular) { my.imageid = my.imageid + my.imagefocusmax; } /* make sure, that the id is smaller than the image count */ maxid = (my.circular) ? (my.max - (my.imagefocusmax)) - 1 : my.max - 1; if (my.imageid > maxid) { my.imageid = maxid; } /* toggle glide animation to start id */ if (my.glidetostartid === false) { my.moveto(-my.imageid * my.xstep); } /* animate images moving in from the right */ if (my.startanimation) { my.moveto(5000); } } /* only animate if there is more than one image */ if (my.max > 1) { my.glideto(my.imageid); } /* display images in current order */ my.moveto(my.current); }; /* main animation function */ this.moveto = function (x) { this.current = x; this.zindex = my.max; /* main loop */ for (var index = 0; index < my.max; index++) { var image = my.imagesdiv.childnodes[my.indexarray[index]]; var currentimage = index * -my.xstep; /* enabled image scaling */ if (my.imagescaling) { /* don't display images that are not conf_focussed */ if ((currentimage + my.maxfocus) < my.memtarget || (currentimage - my.maxfocus) > my.memtarget) { try { image.style.visibility = 'hidden'; image.style.display = 'none'; } catch (e) { } } else { try { var z = (math.sqrt(10000 + x * x) + 100) * my.imagesm; var xs = x / z * my.size + my.size; /* still hide images until they are processed, but set display style to block */ image.style.display = 'block'; /* process new image height and width */ var newimageh = (image.h / image.w * image.pc) / z * my.size; var newimagew = 0; switch (newimageh > my.maxheight) { case false: newimagew = image.pc / z * my.size; break; default: newimageh = my.maxheight; newimagew = image.w * newimageh / image.h; break; } var newimagetop = (my.imagesdivheight - newimageh) + ((newimageh / (my.reflectionp + 1)) * my.reflectionp); /* set new image properties */ image.style.left = xs - (image.pc / 2) / z * my.size + 'px'; if (newimagew && newimageh) { image.style.height = newimageh + 'px'; image.style.width = newimagew + 'px'; image.style.top = newimagetop + 'px'; } image.style.visibility = 'visible'; /* set image layer through zindex */ switch (x < 0) { case true: this.zindex++; break; default: this.zindex = my.zindex - 1; break; } /* change zindex and onclick function of the focussed image */ switch (image.i == my.imageid) { case false: image.onclick = function () { my.glideto(this.i); }; break; default: this.zindex = my.zindex + 1; if (image.url !== '') { image.onclick = my.onclick; } break; } image.style.zindex = my.zindex; } catch (e) { } } } /* disabled image scaling */ else { if ((currentimage + my.maxfocus) < my.memtarget || (currentimage - my.maxfocus) > my.memtarget) { image.style.visibility = 'hidden'; } else { image.style.visibility = 'visible'; /* change onclick function of the focussed image */ switch (image.i == my.imageid) { case false: image.onclick = function () { my.glideto(this.i); }; break; default: if (image.url !== '') { image.onclick = my.onclick; } break; } } my.imagesdiv.style.marginleft = (x - my.totalimageswidth) + 'px'; } x += my.xstep; } }; /* initializes image gliding animation */ this.glideto = function (imageid) { /* check for jumppoints */ var jumptarget, clonedimageid; if (my.circular) { /* trigger left jumppoint */ if (imageid + 1 === my.imagefocusmax) { /* set jump target to the same cloned image on the right */ clonedimageid = my.max - my.imagefocusmax; jumptarget = -clonedimageid * my.xstep; /* set the imageid to the last image */ imageid = clonedimageid - 1; } /* trigger right jumppoint */ if (imageid === (my.max - my.imagefocusmax)) { /* set jump target to the same cloned image on the left */ clonedimageid = my.imagefocusmax - 1; jumptarget = -clonedimageid * my.xstep; /* set the imageid to the first image */ imageid = clonedimageid + 1; } } /* calculate new image position target */ var x = -imageid * my.xstep; this.target = x; this.memtarget = x; this.imageid = imageid; /* display new caption */ var caption = ""; try { caption = my.imagesdiv.childnodes[imageid].getattribute('alt'); } catch (e) { } if (caption === '' || my.captions === false) { caption = ' '; } my.captiondiv.innerhtml = caption; /* set scrollbar slider to new position */ if (my.mousedrag.busy === false) { if (my.circular) { this.newsliderx = ((imageid - my.imagefocusmax) * my.scrollbarwidth) / (my.max - (my.imagefocusmax * 2) - 1) - my.mousedrag.newx; } else { this.newsliderx = (imageid * my.scrollbarwidth) / (my.max - 1) - my.mousedrag.newx; } my.sliderdiv.style.marginleft = (my.newsliderx - my.sliderwidth) + 'px'; } /* only process if opacity or a multiplicator for the focussed image has been set */ if (my.opacity === true || my.imagefocusm !== my.defaults.imagefocusm) { /* set opacity for centered image */ my.helper.setopacity(my.imagesdiv.childnodes[imageid], my.opacityarray[0]); my.imagesdiv.childnodes[imageid].pc = my.imagesdiv.childnodes[imageid].pc * my.imagefocusm; /* set opacity for the other images that are displayed */ var opacityvalue = 0; var rightid = 0; var leftid = 0; var last = my.opacityarray.length; for (var i = 1; i < (my.imagefocusmax + 1); i++) { if ((i + 1) > last) { opacityvalue = my.opacityarray[last - 1]; } else { opacityvalue = my.opacityarray[i]; } rightid = imageid + i; leftid = imageid - i; if (rightid < my.max) { my.helper.setopacity(my.imagesdiv.childnodes[rightid], opacityvalue); my.imagesdiv.childnodes[rightid].pc = my.imagesdiv.childnodes[rightid].pcmem; } if (leftid >= 0) { my.helper.setopacity(my.imagesdiv.childnodes[leftid], opacityvalue); my.imagesdiv.childnodes[leftid].pc = my.imagesdiv.childnodes[leftid].pcmem; } } } /* move the images to the jump target */ if (jumptarget) { my.moveto(jumptarget); } /* animate gliding to new x position */ if (my.busy === false) { my.busy = true; my.animate(); } }; /* animates image gliding */ this.animate = function () { switch (my.target < my.current - 1 || my.target > my.current + 1) { case true: my.moveto(my.current + (my.target - my.current) / 3); window.settimeout(my.animate, my.animationspeed); my.busy = true; break; default: my.busy = false; break; } }; /* used by user events to call the glideto function */ this.glideonevent = function (imageid) { /* interrupt slideshow on mouse wheel, keypress, touch and mouse drag */ if (my.slideshow) { my.slideshow.interrupt(); } /* glide to new imageid */ my.glideto(imageid); }; /* slideshow function */ this.slideshow = { direction: 1, init: function () { /* call start() if autoplay is enabled, stop() if it is disabled */ (my.slideshowautoplay) ? my.slideshow.start() : my.slideshow.stop(); }, interrupt: function () { /* remove interrupt event */ my.helper.removeevent(my.imageflowdiv, 'click', my.slideshow.interrupt); /* interrupt the slideshow */ my.slideshow.stop(); }, addinterruptevent: function () { /* a click anywhere inside the imageflow div interrupts the slideshow */ my.helper.addevent(my.imageflowdiv, 'click', my.slideshow.interrupt); }, start: function () { /* set button style to pause */ my.helper.setclassname(my.buttonslideshow, 'slideshow pause'); /* set onclick behaviour to stop */ my.buttonslideshow.onclick = function () { my.slideshow.stop(); }; /* set slide interval */ my.slideshow.action = window.setinterval(my.slideshow.slide, my.slideshowspeed); /* allow the user to always interrupt the slideshow */ window.settimeout(my.slideshow.addinterruptevent, 100); }, stop: function () { /* set button style to play */ my.helper.setclassname(my.buttonslideshow, 'slideshow play'); /* set onclick behaviour to start */ my.buttonslideshow.onclick = function () { my.slideshow.start(); }; /* clear slide interval */ window.clearinterval(my.slideshow.action); }, slide: function () { var newimageid = my.imageid + my.slideshow.direction; var reversedirection = false; /* reverse direction at the last image on the right */ if (newimageid === my.max) { my.slideshow.direction = -1; reversedirection = true; } /* reverse direction at the last image on the left */ if (newimageid < 0) { my.slideshow.direction = 1; reversedirection = true; } /* if direction is reversed recall this method, else call the glideto method */ (reversedirection) ? my.slideshow.slide() : my.glideto(newimageid); } }; /* mouse wheel support */ this.mousewheel = { init: function () { /* init mouse wheel listener */ if (window.addeventlistener) { my.imageflowdiv.addeventlistener('dommousescroll', my.mousewheel.get, false); } my.helper.addevent(my.imageflowdiv, 'mousewheel', my.mousewheel.get); }, get: function (event) { var delta = 0; if (!event) { event = window.event; } if (event.wheeldelta) { delta = event.wheeldelta / 120; } else if (event.detail) { delta = -event.detail / 3; } if (delta) { my.mousewheel.handle(delta); } my.helper.suppressbrowserdefault(event); }, handle: function (delta) { var change = false; var newimageid = 0; if (delta > 0) { if (my.imageid >= 1) { newimageid = my.imageid - 1; change = true; } } else { if (my.imageid < (my.max - 1)) { newimageid = my.imageid + 1; change = true; } } /* glide to next (mouse wheel down) / previous (mouse wheel up) image */ if (change) { my.glideonevent(newimageid); } } }; /* mouse dragging */ this.mousedrag = { object: null, objectx: 0, mousex: 0, newx: 0, busy: false, /* init mouse event listener */ init: function () { my.helper.addevent(my.imageflowdiv, 'mousemove', my.mousedrag.drag); my.helper.addevent(my.imageflowdiv, 'mouseup', my.mousedrag.stop); my.helper.addevent(document, 'mouseup', my.mousedrag.stop); /* avoid text and image selection while dragging */ my.imageflowdiv.onselectstart = function () { var selection = true; if (my.mousedrag.busy) { selection = false; } return selection; }; }, start: function (o) { my.mousedrag.object = o; my.mousedrag.objectx = my.mousedrag.mousex - o.offsetleft + my.newsliderx; }, stop: function () { my.mousedrag.object = null; my.mousedrag.busy = false; }, drag: function (e) { var posx = 0; if (!e) { e = window.event; } if (e.pagex) { posx = e.pagex; } else if (e.clientx) { posx = e.clientx + document.body.scrollleft + document.documentelement.scrollleft; } my.mousedrag.mousex = posx; if (my.mousedrag.object !== null) { var newx = (my.mousedrag.mousex - my.mousedrag.objectx) + my.sliderwidth; /* make sure, that the slider is moved in proper relation to previous movements by the glideto function */ if (newx < (-my.newsliderx)) { newx = -my.newsliderx; } if (newx > (my.scrollbarwidth - my.newsliderx)) { newx = my.scrollbarwidth - my.newsliderx; } /* set new slider position */ var step, imageid; if (my.circular) { step = (newx + my.newsliderx) / (my.scrollbarwidth / (my.max - (my.imagefocusmax * 2) - 1)); imageid = math.round(step) + my.imagefocusmax; } else { step = (newx + my.newsliderx) / (my.scrollbarwidth / (my.max - 1)); imageid = math.round(step); } my.mousedrag.newx = newx; my.mousedrag.object.style.left = newx + 'px'; if (my.imageid !== imageid) { my.glideonevent(imageid); } my.mousedrag.busy = true; } } }; /* safari touch events on the iphone and ipod touch */ this.touch = { x: 0, startx: 0, stopx: 0, busy: false, first: true, /* init touch event listener */ init: function () { my.helper.addevent(my.navigationdiv, 'touchstart', my.touch.start); my.helper.addevent(document, 'touchmove', my.touch.handle); my.helper.addevent(document, 'touchend', my.touch.stop); }, isonnavigationdiv: function (e) { var state = false; if (e.touches) { var target = e.touches[0].target; if (target === my.navigationdiv || target === my.sliderdiv || target === my.scrollbardiv) { state = true; } } return state; }, getx: function (e) { var x = 0; if (e.touches) { x = e.touches[0].pagex; } return x; }, start: function (e) { my.touch.startx = my.touch.getx(e); my.touch.busy = true; my.helper.suppressbrowserdefault(e); }, isbusy: function () { var busy = false; if (my.touch.busy) { busy = true; } return busy; }, /* handle touch event position within the navigation div */ handle: function (e) { if (my.touch.isbusy && my.touch.isonnavigationdiv(e)) { var max = (my.circular) ? (my.max - (my.imagefocusmax * 2) - 1) : (my.max - 1); if (my.touch.first) { my.touch.stopx = (max - my.imageid) * (my.imagesdivwidth / max); my.touch.first = false; } var newx = -(my.touch.getx(e) - my.touch.startx - my.touch.stopx); /* map x-axis touch coordinates in range of the imageflow width */ if (newx < 0) { newx = 0; } if (newx > my.imagesdivwidth) { newx = my.imagesdivwidth; } my.touch.x = newx; var imageid = math.round(newx / (my.imagesdivwidth / max)); imageid = max - imageid; if (my.imageid !== imageid) { if (my.circular) { imageid = imageid + my.imagefocusmax; } my.glideonevent(imageid); } my.helper.suppressbrowserdefault(e); } }, stop: function () { my.touch.stopx = my.touch.x; my.touch.busy = false; } }; /* key support */ this.key = { /* init key event listener */ init: function () { document.onkeydown = function (event) { my.key.handle(event); }; }, /* handle the arrow keys */ handle: function (event) { var charcode = my.key.get(event); switch (charcode) { /* right arrow key */ case 39: my.mousewheel.handle(-1); break; /* left arrow key */ case 37: my.mousewheel.handle(1); break; } }, /* get the current keycode */ get: function (event) { event = event || window.event; return event.keycode; } }; /* helper functions */ this.helper = { /* add events */ addevent: function (obj, type, fn) { if (obj.addeventlistener) { obj.addeventlistener(type, fn, false); } else if (obj.attachevent) { obj["e" + type + fn] = fn; obj[type + fn] = function () { obj["e" + type + fn](window.event); }; obj.attachevent("on" + type, obj[type + fn]); } }, /* remove events */ removeevent: function (obj, type, fn) { if (obj.removeeventlistener) { obj.removeeventlistener(type, fn, false); } else if (obj.detachevent) { /* the ie breaks if you're trying to detach an unattached event /msdn.microsoft.com/en-us/library/ms536411(vs.85).aspx */ if (obj[type + fn] === undefined) { alert('helper.removeevent » pointer to detach event is undefined - perhaps you are trying to detach an unattached event?'); } obj.detachevent('on' + type, obj[type + fn]); obj[type + fn] = null; obj['e' + type + fn] = null; } }, /* set image opacity */ setopacity: function (object, value) { if (my.opacity === true) { object.style.opacity = value / 10; object.style.filter = 'alpha(opacity=' + value * 10 + ')'; } }, /* create html elements */ createdocumentelement: function (type, id, optionalclass) { var element = document.createelement(type); element.setattribute('id', my.imageflowid + '_' + id); if (optionalclass !== undefined) { id += ' ' + optionalclass; } my.helper.setclassname(element, id); return element; }, /* set css class */ setclassname: function (element, classname) { if (element) { element.setattribute('class', classname); element.setattribute('classname', classname); } }, /* suppress default browser behaviour to avoid image/text selection while dragging */ suppressbrowserdefault: function (e) { if (e.preventdefault) { e.preventdefault(); } else { e.returnvalue = false; } return false; }, /* add functions to the window.onresize event - can not be done by addevent */ addresizeevent: function () { var otherfunctions = window.onresize; if (typeof window.onresize != 'function') { window.onresize = function () { my.refresh(); }; } else { window.onresize = function () { if (otherfunctions) { otherfunctions(); } my.refresh(); }; } } }; } /* domcontentloaded event handler - by tanny o'haley [4] */ var domreadyevent = { name: "domreadyevent", /* array of domcontentloaded event handlers.*/ events: {}, domreadyid: 1, bdone: false, domcontentloadedcustom: null, /* function that adds domcontentloaded listeners to the array.*/ add: function (handler) { /* 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.*/ if (!handler.$$domreadyid) { handler.$$domreadyid = this.domreadyid++; /* if the domcontentloaded event has happened, run the function. */ if (this.bdone) { handler(); } /* store the event handler in the hash table */ this.events[handler.$$domreadyid] = handler; } }, remove: function (handler) { /* delete the event handler from the hash table */ if (handler.$$domreadyid) { delete this.events[handler.$$domreadyid]; } }, /* function to process the domcontentloaded events array. */ run: function () { /* quit if this function has already been called */ if (this.bdone) { return; } /* flag this function so we don't do the same thing twice */ this.bdone = true; /* iterates through array of registered functions */ for (var i in this.events) { this.events[i](); } }, schedule: function () { /* quit if the init function has already been called*/ if (this.bdone) { return; } /* first, check for safari or khtml.*/ if (/khtml|webkit/i.test(navigator.useragent)) { if (/loaded|complete/.test(document.readystate)) { this.run(); } else { /* not ready yet, wait a little more.*/ settimeout(this.name + ".schedule()", 100); } } else if (document.getelementbyid("__ie_onload")) { /* second, check for ie.*/ return true; } /* check for custom developer provided function.*/ if (typeof this.domcontentloadedcustom === "function") { /* if dom methods are supported, and the body element exists (using a double-check including document.body, for the benefit of older moz builds [eg ns7.1] in which getelementsbytagname('body')[0] is undefined, unless this script is in the body section) */ if (typeof document.getelementsbytagname !== 'undefined' && (document.getelementsbytagname('body')[0] !== null || document.body !== null)) { /* call custom function. */ if (this.domcontentloadedcustom()) { this.run(); } else { /* not ready yet, wait a little more. */ settimeout(this.name + ".schedule()", 250); } } } return true; }, init: function () { /* if addeventlistener supports the domcontentloaded event.*/ if (document.addeventlistener) { document.addeventlistener("domcontentloaded", function () { domreadyevent.run(); }, false); } /* schedule to run the init function.*/ settimeout("domreadyevent.schedule()", 100); function run() { domreadyevent.run(); } /* just in case window.onload happens first, add it to onload using an available method.*/ if (typeof addevent !== "undefined") { addevent(window, "load", run); } else if (document.addeventlistener) { document.addeventlistener("load", run, false); } else if (typeof window.onload === "function") { var oldonload = window.onload; window.onload = function () { domreadyevent.run(); oldonload(); }; } else { window.onload = run; } /* for internet explorer */ /*@cc_on @if (@_win32 || @_win64) document.write("