') popup.document.write('') popup.document.write('') popup.document.write('
'+list+'
') popup.document.write('') } else if (val !== "") { console.log('Not implemented.') //http://stackoverflow.com/questions/3975648/how-to-set-content-disposition-attachment-via-javascript $(wrapper + " #dropdowns").append(' ') } else { } $(wrapper + " #downloads #def").attr('selected','selected') }) } function setregexps() { var REGEXPS = new Object(); var n = $(wrapper + " #dropdowns #sortby option:selected").index() || 1 REGEXPS["Title"] = "Show subset of images according to filter on attribute" REGEXPS["Titleshort"] = "-Filters-" REGEXPS["Values"] = new Array() n = n-1 if (GALLERYINFO['attributes']["Values"][n]) { if (GALLERYINFO['attributes']["Values"][n]["Filters"]) { if (!(n == 0 && GALLERYINFO['attributes']["Values"][n]["Filters"].length == 1)) { for (i = 0; i < GALLERYINFO['attributes']["Values"][n]["Filters"].length; i++) { REGEXPS["Values"][i] = new Object() REGEXPS["Values"][i]["Title"] = GALLERYINFO['attributes']["Values"][n]["Filters"][i]["Title"] REGEXPS["Values"][i]["Value"] = GALLERYINFO['attributes']["Values"][n]["Filters"][i]["Value"] } console.log("setdropdowns.setregexps(): Setting regexp filter dropdown.") dropdown("regexp", REGEXPS, wrapper + " #dropdowns") } } else { console.log("setdropdowns.setregexps(): No regexp filters. Not displaying drop-down.") $(wrapper + " #regexp").remove() } } var qs = $.parseQueryString(); if (VIVIZ["galleries"][galleryid]["defaultRegExp"] && !qs["regexp"]) { console.log("setdropdowns(): Setting regexp filter value based on gallery configuration.") $(wrapper + " #regexp").val(VIVIZ["galleries"][galleryid]["defaultRegExp"]) } $(wrapper + ' #dropdowns #regexp').unbind('change') $(wrapper + ' #dropdowns #regexp').change(function () { //viviz.triggerreset = false; updatehash('regexp') }) } } function setWH(el, type) { console.log("setWH(): Computing width and height of " + type + " images based on image size and options.") var ar = el.naturalWidth/el.naturalHeight // Compute pixels if given fractions. if (VIVIZ["galleries"][galleryid][type+"Width"]) { if (VIVIZ["galleries"][galleryid][type+"Width"] <= 1.0) { console.log('setWH(): Converting ' + type + 'Width to pixels.') VIVIZ["galleries"][galleryid][type+"Width"] = el.naturalWidth*VIVIZ["galleries"][galleryid][type+"Width"] } } if (VIVIZ["galleries"][galleryid][type+"Height"]) { if (VIVIZ["galleries"][galleryid][type+"Height"] <= 1.0) { console.log('setWH(): Converting ' + type + 'Height to pixels.') VIVIZ["galleries"][galleryid][type+"Height"] = el.naturalHeight*VIVIZ["galleries"][galleryid][type+"Height"] } } // Compute un-specified width or height. if (VIVIZ["galleries"][galleryid][type+"Width"] && !VIVIZ["galleries"][galleryid][type+"Height"]) { console.log('setWH(): ' + type + 'Width known but Height unknown. Using aspect ratio to compute.') VIVIZ["galleries"][galleryid][type+"Height"] = VIVIZ["galleries"][galleryid][type+"Width"]/ar } if (VIVIZ["galleries"][galleryid][type+"Height"] && !VIVIZ["galleries"][galleryid][type+"Width"]) { console.log('setWH(): ' + type + 'Height known but Width unknown. Using aspect ratio to compute.') VIVIZ["galleries"][galleryid][type+"Width"] = VIVIZ["galleries"][galleryid][type+"Height"]*ar } if (!VIVIZ["galleries"][galleryid][type+"Height"]) { console.log('setWH(): ' + type + 'Height unknown. Using naturalHeight.') VIVIZ["galleries"][galleryid][type+"Height"] = el.naturalHeight } if (!VIVIZ["galleries"][galleryid][type+"Width"]) { console.log('setWH(): ' + type + 'Width unknown. Using naturalWidth.') VIVIZ["galleries"][galleryid][type+"Width"] = el.naturalWidth } VIVIZ["galleries"][galleryid][type+"NaturalHeight"] = el.naturalHeight VIVIZ["galleries"][galleryid][type+"NaturalWidth"] = el.naturalWidth return true } function thumblist() { console.log("thumblist(): Called.") var galleryid = $(wrapper + " #id").val() var SORTBY = $(wrapper + " #sortby").val() var ORDER = $(wrapper + " #order").val() var regexp = $(wrapper + " #regexp :selected").attr('value') var SORTBYS = GALLERYINFO['attributes'] var ORDERS = GALLERYINFO['orders'] //http://stackoverflow.com/a/2450976 function shuffle(array) { var currentIndex = array.length, temporaryValue, randomIndex; // While there remain elements to shuffle... while (0 !== currentIndex) { // Pick a remaining element... randomIndex = Math.floor(Math.random() * currentIndex); currentIndex -= 1; // And swap it with the current element. temporaryValue = array[currentIndex]; array[currentIndex] = array[randomIndex]; array[randomIndex] = temporaryValue; } return array; } // http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone function clone(obj){ if (obj == null || typeof(obj) != 'object') return obj; var temp = new obj.constructor(); // changed (twice) for (var key in obj) temp[key] = clone(obj[key]); return temp; } // Test decoding of of first file only. var msg = testdecode(GALLERYINFO["fullfiles"][0][0]) if (msg !== "") {error(msg, true); return;} var msg = testdecode(GALLERYINFO["thumbfiles"][0][0]) if (msg !== "") {error(msg, true); return;} var INFOjs = new Array(); for (j = 0; j < GALLERYINFO["fullfiles"].length; j++) { INFOjs[j] = new Object(); INFOjs[j]["FullFile"] = decodeURIComponent(GALLERYINFO["fullfiles"][j][0]); INFOjs[j]["ThumbFile"] = decodeURIComponent(GALLERYINFO["thumbfiles"][j][0]); // This is a confusing way to do things. if (Object.keys(SORTBYS).length > 0) { for (z = 0;z < SORTBYS["Values"].length;z++) { INFOjs[j][SORTBYS["Values"][z]["Value"]] = GALLERYINFO["fullfiles"][j][z]; } } INFOjs[j]["ImageNumber"] = j; } state = galleryid+SORTBY+ORDER+regexp; if (typeof(thumblist.cache) != 'object') { thumblist.cache = new Object(); } if ( thumblist.cache[state] ) { console.log('thumblist(): Using cached thumblist.'); return thumblist.cache[state]; } I = new Array(); if (regexp) { var REGEXP = new RegExp(regexp); if (typeof(INFOjs[0][SORTBY]) == "string") { var k = 0; for (var i = 0; i < INFOjs.length; i++) { if (INFOjs[i][SORTBY].match(REGEXP)) { I[i] = k; k = k+1; } } } else { //regexp = regexp.replace('gt','>').replace('ge','<=').replace('lt','<').replace('le','<='); //regexp = regexp.replace('and','&').replace('&','&'); //regexp = regexp.replace('<','<'); //regexp = regexp.replace('>','>'); var k = 0; var re = new RegExp(SORTBY, "g"); console.log("thumblist(): Testing RegExp: " + regexp); for (var i = 0; i < INFOjs.length; i++) { var test = regexp.replace(re, INFOjs[i][SORTBY]); if (eval(test)) { I[i] = k; k = k+1; } } } console.log("thumblist(): RegExp " + regexp + " removed " + (INFOjs.length-k) + "/" + INFOjs.length + " images in subset."); if (I.length > 0) { var INFOr = new Array(); for (i = 0; i < I.length; i++) { INFOr[I[i]] = INFOjs[i]; } var INFOrs = clone(INFOr); } else { return []; } } else { var INFOrs = clone(INFOjs) } if (ORDER.match("ascending")) { //console.log('thumblist.js: Sorting by attribute ' + SORTBY + " in ascending order."); if (typeof(INFOrs[0][SORTBY]) == "string") { //console.log('thumblist.js: Sorting attribute ' + SORTBY + " as string."); INFOrs.sort(function(a,b) { return a[SORTBY].localeCompare(b[SORTBY]); }); } else { //console.log('thumblist.js: Sorting attribute ' + SORTBY + " as number."); INFOrs.sort(function(a, b){ return a[SORTBY] - b[SORTBY]; }); } } if (ORDER.match("descending")){ //console.log('thumblist.js: Sorting by attribute ' + SORTBY + " in descending order.") if (typeof(INFOrs[0][SORTBY]) == "string") { //console.log('thumblist.js: Sorting attribute ' + SORTBY + " as string.") INFOrs.sort(function(a,b) { return b[SORTBY].localeCompare(a[SORTBY]) }); } else { //console.log('thumblist.js: Sorting attribute ' + SORTBY + " as number.") INFOrs.sort(function(a,b){ return b[SORTBY] - a[SORTBY] }) } //console.log('thumblist.js: First image is now ' + INFOrs[0]) } if (ORDER.match("random")) { //console.log('thumblist.js: Sorting by attribute ' + SORTBY + " in random order.") INFOrs = shuffle(INFOrs); } if ((!ORDER.match("random")) & (typeof(thumblist.cache[state]) != 'object')) { thumblist.cache[state] = new Object(); thumblist.cache[state] = INFOrs; } var qs = $.parseQueryString(); if (parseInt(qs["number"]) > INFOrs.length) { warning("Number of images in subset < number in query string. Resetting number to 1.", true, Infinity); VIVIZ["galleries"][galleryid]["defaultFirstImage"] = 1; updatehash("number",1) } return INFOrs } function gallery() { $('button').each(function () {tooltip($(this).attr('id'))}) $("#thumb" + gallerynumber).parent().hide() $("#gallery" + gallerynumber).parent().show() setthumbs() var resizeTimer; $(window).on('resize', function(e) { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { settabledims(); }, 250); }); // Actions to take when a thumbnail is clicked. function setthumbbindings() { console.log("gallery.setthumbbindings(): Called.") var nowvisible = parseInt($(wrapper).attr('nowvisible')); var lastvisible = parseInt($(wrapper).attr('lastvisible')); if (isNaN(nowvisible)) { console.log("gallery.setthumbbindings(): nowvisible is NaN. Setting nowvisible attribute on " + wrapper + " to 1."); nowvisible = 1; $(wrapper).attr('nowvisible', '1'); } else { nowvisible = $(this).attr('id'); console.log("gallery.setthumbbindings(): Setting nowvisible attribute on " + wrapper + " to " + nowvisible + "."); $(wrapper).attr('nowvisible', nowvisible); } if (isNaN(lastvisible)) { console.log("gallery.setthumbbindings(): lastvisible is NaN. Setting nowvisible attribute on " + wrapper + " to 1."); lastvisible = 1; $(wrapper).attr('lastvisible', '1'); } console.log("gallery.setthumbbindings():" + " Setting class on thumb #" + lastvisible + " to inactive."); $(wrapper + " #gallerythumbframe #" + lastvisible) .removeClass('active').addClass('inactive'); console.log("gallery.setthumbbindings():" + " Setting class on thumb #" + nowvisible + " to active."); $(wrapper + " #gallerythumbframe #" + nowvisible) .removeClass('inactive').addClass('active'); console.log("gallery.setthumbbindings(): Setting stat string."); INFOjs = thumblist(); var statstr = "| #" + (nowvisible) + "/" + (INFOjs.length) + " for filter"; statstr = statstr + " | #" + (1+INFOjs[nowvisible-1].ImageNumber) + "/" + $(wrapper).attr('totalingallery') + " in gallery | "; for (var z = 1;z < GALLERYINFO['attributes']["Values"].length;z++) { statstr = statstr + GALLERYINFO['attributes']["Values"][z].Title + " = "; var key = GALLERYINFO['attributes']["Values"][z].Value if (GALLERYINFO['attributes']["Values"][z].Format) { statstr = statstr + sprintf(GALLERYINFO['attributes']["Values"][z].Format, parseFloat(INFOjs[nowvisible-1][GALLERYINFO['attributes']["Values"][z].Value])); } else { statstr = statstr + INFOjs[nowvisible-1][key]; } if (GALLERYINFO['attributes']["Values"][z].Unit) { statstr = statstr + " [" + GALLERYINFO['attributes']["Values"][z].Unit + "] " + " | "; } else { statstr = statstr + " | "; } } $(wrapper + ' #attributes').html(statstr); var qs = $.parseQueryString() console.log("gallery.sethumbbindings(): Calling updatehash('number',"+ nowvisible + ").") updatehash('number', nowvisible); //$(wrapper + " #fullframe img[id=" + lastvisible + "]").css("opacity","0.4"); console.log("gallery.sethumbbindings(): Hiding full image #" + lastvisible + "."); $(wrapper + " #fullframe img[id=" + lastvisible + "]").hide(); // Load full image. console.log("gallery.sethumbbindings(): Calling loadfull."); loadfull($(this).attr('id')); // Update lastvisible attribute on wrapper. console.log("gallery.sethumbbindings(): Setting lastvisible attribute on " + wrapper + " to " + nowvisible + "."); $(wrapper).attr("lastvisible", nowvisible); // Scroll thumbnail list console.log("gallery.sethumbbindings(): Scrolling #gallerythumbframe to #" + nowvisible + "."); $(wrapper + " #gallerythumbframe").scrollTo(this, 0, { duration: 0, offset: 0 }); } function setthumbs() { console.log('gallery.setthumbs(): Called.'); var INFOjs = thumblist() // Set attributes used by lazy loader $(wrapper).attr('totalvisible', INFOjs.length) $(wrapper).attr('totalingallery',GALLERYINFO["totalingallery"]) var thumbframe = $(wrapper + ' #gallerythumbframe') // Clear any previous scroll binding. (Lazy load uses this.) thumbframe.unbind('scroll') if (INFOjs.length == 0) { $(wrapper + ' #attributes').html('No images in subset.') return } firstimage(VIVIZ["galleries"][galleryid]["defaultFirstImage"]); // TODO: (?) Detect bad images: // https://github.com/desandro/imagesloaded // http://stackoverflow.com/questions/821516/browser-independent-way-to-detect-when-image-has-been-loaded // http://stackoverflow.com/questions/3877027/jquery-callback-on-image-load-even-when-the-image-is-cached // Find first valid thumbnail function firstimage(f) { console.log("gallery.firstimage(): Called." + " Setting thumb #" + (f) + " into DOM."); if (f == VIVIZ["galleries"][galleryid]["defaultFirstImage"]) { setcontrolbindings(); } $('') .appendTo($(wrapper + ' #gallerythumbframe')) .attr("id",f) .attr("src", VIVIZ["galleries"][galleryid]["thumbdirdecoded"] + INFOjs[f-1].ThumbFile) .error(function () { // First image is bad. console.log("gallery.firstimage.error(): Error event when setting thumb image " + (f) + " is bad."); $(this).addClass("error") $(this).removeClass("firstimage") warning("Thumbnail image " + (f) + " could not be loaded.", true, 1000); // This triggers .load //$(this).attr("src", "css/transparent.png"); $(this).attr("src", transparent); // Need to do this here and in .load in case error // event is triggered after .load event of first non- // error image. console.log("gallery.firstimage.error(): Setting dimensions on image to " + VIVIZ["galleries"][galleryid]["thumbWidth"] + "x" + VIVIZ["galleries"][galleryid]["thumbHeight"] + "."); $(this).css("height", VIVIZ["galleries"][galleryid]["thumbHeight"]); $(this).css("width", VIVIZ["galleries"][galleryid]["thumbWidth"]); //$(this).remove(); if (f == INFOjs.length) { warning("No images could be loaded.", true, Infinity) console.log("No images could be loaded.") $(wrapper + " #workingfullframe").css('visibility','hidden') if ($(wrapper + " #fullframe").width() > 0) $(wrapper + " #fullframe").width('') if ($(wrapper + " #fullframe").height() > 0) $(wrapper + " #fullframe").height('') return } firstimage(f+1) }) .load(function () { if ($(this).hasClass('error')) return; //if (f > VIVIZ["config"]["defaultFirstImage"]) { if (f == VIVIZ["galleries"][galleryid]["defaultFirstImage"]+1) { if (VIVIZ["galleries"][galleryid]["defaultFirstImage"] > 1) { warning("The selected thumbnail image in this subset could not be loaded.", true, 2000) } else { warning("The first thumbnail image in this subset could not be loaded.", true, 2000) } } else { //warning("The first " + (VIVIZ["config"]["defaultFirstImage"]-f+1) + " images" + " in this subset could not be loaded.",true) } //} // Trigger load of the first full image. $(wrapper).attr('nowvisible', f) console.log("gallery.firstimage.load(): First successful thumbnail image load.") console.log("gallery.firstimage.load(): Applying click bindings and then clicking it to trigger load of full image.") $(this).bind('click', setthumbbindings).click() // Scroll to top. $(wrapper + " #gallerythumbframe").scrollTo(0); console.log('gallery.firstimage.load(): First thumbnail has natural dimensions = ' +this.naturalWidth+'x'+this.naturalHeight+'.'); // Set height of thumbnail image - setWH() // Modifies VIVIZ["galleries"][galleryid] var tmp = setWH(this, 'thumb'); $(this).css("height",VIVIZ["galleries"][galleryid]["thumbHeight"]); $(this).css("width",VIVIZ["galleries"][galleryid]["thumbWidth"]); //setTimeout(function () { var l = $(wrapper + ' #gallerythumbframe img.error').length; console.log("gallery.firstimage.load(): Setting dimensions on " + (l) + " images with class error to " + VIVIZ["galleries"][galleryid]["thumbWidth"] + "x" + VIVIZ["galleries"][galleryid]["thumbHeight"] + "."); $(wrapper + ' #gallerythumbframe img.error').css("height",VIVIZ["galleries"][galleryid]["thumbHeight"]); $(wrapper + ' #gallerythumbframe img.error').css("width",VIVIZ["galleries"][galleryid]["thumbWidth"]); //}, 0); if (VIVIZ["galleries"][galleryid]["defaultFirstImage"] > 1) { console.log("gallery.firstimage.load(): First image to show > 1. Inserting spacers before first image."); for (var i = 1; i < VIVIZ["galleries"][galleryid]["defaultFirstImage"]; i++) { $('') .prependTo($(wrapper + ' #gallerythumbframe')) //.attr("src", "css/transparent.png") .attr("src", transparent) .css("height",VIVIZ["galleries"][galleryid]["thumbHeight"]) .css("width",VIVIZ["galleries"][galleryid]["thumbWidth"]) } } console.log('gallery.firstimage.load(): First thumbnail set to ' + 'have dimensions = ' + VIVIZ["galleries"][galleryid]["thumbWidth"] + 'x' + VIVIZ["galleries"][galleryid]["thumbHeight"] + '.'); $(wrapper + ' #gallerythumbframe').attr('data-thumb-length', INFOjs.length); // Set attribute that indicates which thumbnail is active. $(wrapper + ' #gallerythumbframe').attr('data-thumb-displayed', f); setscrollbinding(); // Lazy Load images. var maxLength = INFOjs.length; var max = VIVIZ["galleries"][galleryid]["lazyLoadMax"] || VIVIZ["config"]["lazyLoadMax"] if (INFOjs.length > max) { maxLength = max; } if (maxLength + f > INFOjs.length) { maxLength = INFOjs.length-f; } loadmore("both"); }) } } function settabledims(el,callback) { console.log("gallery.settabledims(): Called.") // http://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes $.scrollbarWidth=function(){var a,b,c;if(c===undefined){a=$('
').appendTo('body');b=a.children();c=b.innerWidth()-b.height(99).innerWidth();a.remove()}return c}; // Set height of thumb strip to be full height of image. $(wrapper + ' #gallerythumbframe') .height(VIVIZ["galleries"][galleryid]["fullHeight"]); $('#filename').hide() tw = VIVIZ["galleries"][galleryid]["thumbWidth"]; th = VIVIZ["galleries"][galleryid]["thumbHeight"]; fw = VIVIZ["galleries"][galleryid]["fullWidth"]; fh = VIVIZ["galleries"][galleryid]["fullHeight"]; // hc = height of controls hc = $("#gallery1").outerHeight()-$("#fullframe img").outerHeight(); // height of controls ho = $("#gallery1").outerHeight() - hc; hf = $(window).height() - hc; wo = $("#gallery1").outerWidth(); wf = $(window).width(); console.log('height: wrapper = ' + ho + '; window = ' + hf); console.log('width: wrapper = ' + wo + '; window = ' + wf); sfh = hf/ho; // height scale factor sfw = wf/wo; // width scale factor console.log('height: win/body = ' + sfh); console.log('width: win/body = ' + sfw); sf = Math.min(sfw,sfh); // d = extra space for border d = $('#gallerythumbframe img').outerWidth() - $('#gallerythumbframe img').width(); $('#gallerythumbframe').height(sf*fh); $('#gallerythumbframe').width(sf*tw+2*d); $('#fullframe img').width(Math.floor(sf*fw)); $('#fullframe img').height(Math.floor(sf*fh)); $('#gallerythumbframe img').width(Math.floor(sf*tw)); $('#gallerythumbframe img').height(Math.floor(sf*th)); VIVIZ["galleries"][galleryid]["thumbWidth"] = Math.floor(sf*tw); VIVIZ["galleries"][galleryid]["thumbHeight"] = Math.floor(sf*th); VIVIZ["galleries"][galleryid]["fullWidth"] = Math.floor(sf*fw); VIVIZ["galleries"][galleryid]["fullHeight"] = Math.floor(sf*fh); if (!settabledims.called) { settabledims.called = 1; settabledims(); } if (VIVIZ["galleries"][galleryid]["play"] || VIVIZ["play"]) { $(wrapper + " #play").click() } if (callback) { callback(); } } function loadfull(id) { id = parseInt(id); console.log("gallery.loadfull(): Called with image object with id = " + id + "."); if (id > INFOjs.length) {return} if ($(wrapper + " #fullframe img[id="+id+"]").length == 1) { console.log("gallery.loadfull(): " + "Found hidden full image in DOM. Showing."); $(wrapper + " #fullframe img[id=" + id + "]").show(); prepnext(id) setfilename(id) return; } // Show loading indicator console.log("gallery.loadfull(): Showing loading indicator.") $(wrapper + ' #workingfullframe').css('visibility','visible'); // Place empty image element in DOM. console.log("gallery.loadfull(): Placing empty img element with id = " + id + " in DOM."); $(wrapper + " #fullframe").prepend(''); console.log("gallery.loadfull(): Setting attributes and binding" + " load event on # " + id + "."); $(wrapper + " #fullframe img[id="+id+"]") .unbind('load') .error(function () { $(wrapper + ' #workingfullframe').css('visibility','hidden'); console.log("-- gallery.loadfull(): Error " + "loading full image #" + id + "."); //$(this).attr("src","css/transparent.png") $(this).attr("src",transparent) $(this).addClass("class","error") warning("The full image for this thumbnail could " + "not be loaded.", true) // Above set will trigger load event so following not needed. //$(this).trigger('load') }) .css("height", VIVIZ["galleries"][galleryid]["fullHeight"] || 400) .css('width', VIVIZ["galleries"][galleryid]['fullWidth'] || 400) .attr('src', VIVIZ["galleries"][galleryid]["fulldirdecoded"] + INFOjs[parseInt(id)-1]["FullFile"]) .load(function() { console.log("gallery.loadfull(): Load event for full image #" + id + "."); // Hide loading indicator console.log("gallery.loadfull(): Hiding loading indicator."); $(wrapper + ' #workingfullframe').css('visibility', 'hidden'); // Undo width and height set when dom is reset. if ($(wrapper + " #fullframe").width() > 0) $(wrapper + " #fullframe").width('') if ($(wrapper + " #fullframe").height() > 0) $(wrapper + " #fullframe").height('') if ($("#"+id).hasClass('firstimage')) { console.log("gallery.loadfull(): " + "First full image load event. Full image has dimensions " + this.naturalWidth + "x" + this.naturalHeight + ". Setting table dimensions."); $(wrapper + " #fullframe").height(''); var tmp = setWH(this, 'full'); // Set height of full image. console.log("gallery.loadfull(): " + "Setting full image height on #" + id + "."); $(this).css("height", VIVIZ["galleries"][galleryid]["fullHeight"]); $(this).css('width', VIVIZ["galleries"][galleryid]['fullWidth']) // After this function sets VIVIZ[galleryid] dimensions, // then call prepnext(), which uses these dimensions. console.log("gallery.loadfull(): Calling " + "settabledims() with callback prepnext(" + id + ")."); settabledims(this, function () {prepnext(id)}) } else { prepnext(id) } console.log("gallery.loadfull(): Calling setfilename(" + id + ")."); setfilename(id) }) function prepnext(id) { // If next few images not in DOM, load them. console.log("gallery.loadfull.prepnext(): Called with id = " + id + ".") var idn = parseInt(id) + 1 if (idn > INFOjs.length) {return} var ido = idn var Nlazy = VIVIZ["galleries"][galleryid]["lazyLoadMax"] || VIVIZ["config"]["lazyLoadMax"] || 3 // Always have next Nlazy full images set in DOM. // TODO: If play button hit, start loading more. while (idn < ido + Nlazy) { if (idn > INFOjs.length) {break} if ($(wrapper + " #fullframe img[id="+idn+"]").length == 0) { console.log("gallery.loadfull.prepnext(): Setting full image with id = " + idn + "."); $(wrapper + " #fullframe").prepend(''); $(wrapper + " #fullframe img[id="+idn+"]") .css('height',VIVIZ["galleries"][galleryid]['fullHeight']) .css('width',VIVIZ["galleries"][galleryid]['fullWidth']) .attr('src',VIVIZ["galleries"][galleryid]["fulldirdecoded"] + INFOjs[idn-1]["FullFile"]) .error(function () { //$(this).attr("src", "css/transparent.png") $(this).attr("src", transparent) $(this).attr("class","error") $(this).height(VIVIZ["galleries"][galleryid]["fullHeight"]); $(this).width(VIVIZ["galleries"][galleryid]["fullWidth"]); }) .load(function () { console.log("gallery.loadfull.prepnext(): Full image #" + $(this).attr('id') + " load event.") if ($(wrapper + " #fullframe img[id="+(parseInt($(this).attr('id'))-1)+"]").hasClass("error")) { console.log("gallery.loadfull.prepnext(): Previous full image did not load. Setting full image dimensions and setting table dimensions.") var tmp = setWH(this, 'full'); // Set height of full image. console.log("gallery.loadfull.prepnext(): Setting full image height on #" + id + "."); $(this).css("height",VIVIZ["galleries"][galleryid]["fullHeight"]); $(this).css('width',VIVIZ["galleries"][galleryid]['fullWidth']) // After this function sets VIVIZ[galleryid] dimensions, // then call prepnext(), which uses these dimensions. console.log("gallery.loadfull(): Calling settabledims() with callback prepnext(" + id + ")."); settabledims(this, function () { console.log("gallery.loadfull(): Calling setfilename(" + id + ")."); setfilename(id) }); } }) } idn = idn+1 } } function setfilename(id) { console.log("gallery.loadfull.setfilename(): Called."); $(wrapper + " #filename").html(''); var wo = $(wrapper).width() $(wrapper + " #filename").append(""); var href = VIVIZ["galleries"][galleryid]["fulldirdecoded"] + INFOjs[parseInt(id-1)]["FullFile"]; var fname = INFOjs[parseInt(id-1)]["FullFile"]; if (fname.match("&")) { // URL is not a file but a URL with query parameters. fname = href; } $(wrapper + " #filename a") .attr('href', href) .css("white-space", "nowrap") .html(fname); var wx = $(wrapper + " #filename").width(); while (wx > wo) { console.log("gallery.loadfull.setfilename(): " + wrapper + " width "+wo) console.log("gallery.loadfull.setfilename(): " + "#filename div width "+wx) // Fraction to remove. 0.9 is to account for nonuniformity // of charcter width. r = 0.9*wo/wx console.log("gallery.loadfull.setfilename(): " + "Reduction factor: 0.9*" + wo + "/" + wx) l = fname.length nr = l-r*l console.log("gallery.loadfull.setfilename(): " + "Number of characters to remove: " + nr) c = l/2 console.log("gallery.loadfull.setfilename(): Center value: " + c) console.log("gallery.loadfull.setfilename(): " + "Number of characters to keep: " + nr) fnamer = fname.substr(0,Math.floor(c-nr/2)) + " ... " + fname.substr(Math.ceil(c+nr/2),l) $(wrapper + " #filename a").text(fnamer); wx = $(wrapper + " #filename").width(); } } } function loadmore(direction, Nshown, scrollEvent) { var Navail = parseInt($(wrapper + ' #gallerythumbframe').attr('data-thumb-length')); Nshown = Nshown || parseInt($(wrapper + " #gallerythumbframe > img.active").attr("id")); var Nlazy = VIVIZ["galleries"][galleryid]["lazyLoadMax"] || VIVIZ["config"]["lazyLoadMax"] var firstidx = parseInt(VIVIZ["galleries"][galleryid]["defaultFirstImage"])-1; Nbefore = 0; if (firstidx > 0) { Nbefore = Nlazy; } // Number of blocks of Nlazy images to fill document height. var d = Math.max(Nlazy, Nshown)*VIVIZ["galleries"][galleryid]["thumbHeight"]; var Nfill = $(window).height()/(d) // If Nfill > 1, we need to load more images initially // to trigger appearance of scroll bar. if (Nfill > 1) { Nlazy = Math.ceil(Nfill*Nlazy) } var tic = new Date().getTime() var slowwarn = false var imgstr = ''; if (direction === "both" || direction === "forward") { for (var j = Nshown + 1; j < Nshown + Nlazy; j++) { if ($("#gallerythumbframe img[id='" + (j) + "']").length > 0) { console.log("gallery.loadmore(): Found thumb with id = " + (j) + " in DOM. Not appending."); continue; } if (j == INFOjs.length + 1) break; var last = $("#gallerythumbframe img").last(); var bottom = parseInt(last.attr('id')); console.log("gallery.loadmore(): Bottom image is #" + bottom + ". Inserting thumb #" + bottom + " after #" + (j) + "."); var el = $(imgstr) .css("height", $("#gallerythumbframe > img.active").height()) .css("width", $("#gallerythumbframe > img.active").width()) .css("background-image", "url(css/ajax-loader-slow.gif") .css("background-repeat", "no-repeat") .css("background-size","100%") .css("background-position","center") .insertAfter(last); setel(el,j); } } if (direction === "both" || direction === "backward") { for (var j = Nshown-1; j > Nshown-Nlazy-2; j--) { if (j < 1) continue; if ($("#gallerythumbframe img[id='" + (j) + "']").length > 0) { console.log("gallery.loadmore(): Found thumb with id = " + (j) + " in DOM. Not prepending."); continue; } var first = $("#gallerythumbframe img").not(".spacer").first(); var top = parseInt(first.attr('id')); console.log("gallery.loadmore(): Top non-spacer image is #" + top + ". Inserting thumb #" + (j) + " before #" + top + "."); var lastspacer = $("#gallerythumbframe .spacer").last(); //var el = $(imgstr) var el = $(lastspacer) .removeClass("spacer") .css("height", $("#gallerythumbframe > img.active").height()) .css("width", $("#gallerythumbframe > img.active").width()) .css("background-image", "url(css/ajax-loader-slow.gif") .css("background-repeat", "no-repeat") .css("background-size","100%") .css("background-position","center") setel(el,j); } } function setel(el,j) { $(el) .attr("id",j) .addClass("gallerythumbbrowse") .addClass("lazyload") .attr("src", VIVIZ["galleries"][galleryid]["thumbdirdecoded"] + INFOjs[j-1].ThumbFile) .bind('click',setthumbbindings) .attr("title",imgtitle(INFOjs[j-1])) .error(function () { $(this).addClass("error") //$(this).attr("src","css/transparent.png") $(this).attr("src",transparent) $(this).css("background-image", "") }) .load(function () { var active = $(wrapper + " #gallerythumbframe img.active"); $(this).css("background-image", "") if (!scrollEvent) { $(wrapper + " #gallerythumbframe") .scrollTo(active, 0, { duration: 80, offset: 0 }); } if ((slowwarn == false) && (new Date().getTime() - tic > 3000)) { slowwarn = true; } }) } } function imgtitle(obj) { //http://stackoverflow.com/questions/5612787/converting-javascript-object-to-string var str = ''; var k = 0; for (var p in obj) { if (obj.hasOwnProperty(p)) { if (isNaN(parseInt(p))) str += p + ':' + obj[p] + '\n'; } k = k+1; } return str; } function setcontrolbindings() { var si = false; // Show/Hide thumb button $(wrapper + " #showhidethumb").unbind('click'); $(wrapper + " #showhidethumb").click(function(){ //console.log($(wrapper + " #gallerythumbframe").css('display')) if ($(wrapper + " #gallerythumbframe").css('display') === "block") { console.log("gallery.setcontrolbindings: Hiding gallerythumbframe."); $(wrapper + " #gallerythumbframe").hide() setcontrolbindings.marginleft = $("#fullframe").css('margin-left'); $("#fullframe").css('margin-left','0'); $(wrapper + ' #showhidethumb').text('+'); $(wrapper + ' #showhidethumb').attr('title','Show thumbnails') } else { console.log("gallery.setcontrolbindings: Showing gallerythumbframe."); $(wrapper + " #gallerythumbframe").css('visibility','visible') console.log("gallery.setcontrolbindings: Setting margin-left to " + setcontrolbindings.marginleft); $("#fullframe").css('margin-left',setcontrolbindings.marginleft) $(wrapper + " #gallerythumbframe").show() $(wrapper + ' #showhidethumb').text('x'); $(wrapper + ' #showhidethumb').attr('title','Hide thumbnails') } }) if (VIVIZ["config"]["showThumbstrip"] == false) { if (typeof(VIVIZ["galleries"][galleryid]["showThumbstrip"]) !== "undefined") { if (VIVIZ["galleries"][galleryid]["showThumbstrip"] == false) { $("#showhidethumb").click() } } } $(wrapper + " #stop").unbind('click'); $(wrapper + " #stop").click( function () { if (typeof(si) === "number") { clearInterval(si); si = false; } } ) $(wrapper + " #play").unbind('click'); $(wrapper + " #play").click( function () { if (typeof(si) === "number") { return // already playing. //clearInterval(si); } $("#next").click(); si = setInterval( function () { $("#next").click(); }, VIVIZ["galleries"][galleryid]["frameRate"] || VIVIZ["frameRate"]); } ) // Time step buttons $(wrapper + " #next").unbind('click'); $(wrapper + ' #next').click(function(){ var lastvisible = parseInt($(wrapper).attr('lastvisible')); if (lastvisible == parseInt($(wrapper).attr('totalvisible'))) { // This finds the first image set according to number parameter // in hash, which may not be the first image in subset. var nowvisible = parseInt($(wrapper + " #gallerythumbframe img").not(".error").attr('id')); } else { var nowvisible = lastvisible + 1; } console.log("gallery.setcontrolbindings: Next button clicked." + " Clicking on #" + nowvisible + ".") $(wrapper + " #gallerythumbframe #" + nowvisible).click(); var length = parseInt($('#gallerythumbframe').attr('data-thumb-length')); var shown = parseInt($("#gallerythumbframe > img").last().attr("id")); var max = VIVIZ["galleries"][galleryid]["lazyLoadMax"] || VIVIZ["lazyLoadMax"] var f = Math.ceil(nowvisible/max) - nowvisible/max if (f < 0.5) loadmore("forward"); }); $(wrapper + " #previous").unbind('click'); $(wrapper + ' #previous').click(function(){ var lastvisible = parseInt($(wrapper).attr('lastvisible')); if (lastvisible == 1) { var nowvisible = parseInt($(wrapper).attr('totalvisible')); } else { var nowvisible = lastvisible - 1; } $(wrapper + " #" + nowvisible).click(); var max = VIVIZ["galleries"][galleryid]["lazyLoadMax"] || VIVIZ["lazyLoadMax"] var first = parseInt($(wrapper + " #gallerythumbframe > img").first().attr("id")); if (nowvisible-first < max) { loadmore("backward"); } }) $(wrapper + " #last").unbind('click'); $(wrapper + ' #last').click(function () { var last = parseInt($(wrapper).attr("totalvisible")); // Need to re-set application here because clicking // on a spacer does not do anything. updatehash('number', last, true) }); $(wrapper + " #first").unbind('click'); $(wrapper + ' #first').click(function(){ // Need to re-set application here because clicking // on a spacer does not do anything. updatehash('number', 1, true) }); } function setscrollbinding() { if (typeof(setscrollbinding.lastoffset) === "undefined") { setscrollbinding.lastoffset = $(wrapper + " #gallerythumbframe").scrollTop().valueOf(); } var debugscroll = false; $(wrapper + ' #gallerythumbframe').scroll(function(e){ if (debugscroll) console.log("gallery.setscrollbinding(): Scroll event.") var currentoffset = $(wrapper + " #gallerythumbframe").scrollTop().valueOf(); var rel = setscrollbinding.lastoffset - currentoffset; setscrollbinding.lastoffset = currentoffset; if (debugscroll) { if (rel > 0) { console.log("gallery.setscrollbinding(): Scroll put lower image #s in view."); } else { console.log("gallery.setscrollbinding(): Scroll put higher image #s in view."); } } var elem = $(this); var Nlazy = VIVIZ["galleries"][galleryid]["lazyLoadMax"] || VIVIZ["config"]["lazyLoadMax"] var Nshown = parseInt($(wrapper + " #gallerythumbframe > img.active").attr("id")); // Determine number of thumbnails above active one that exist in view. var activetop = $(wrapper + " #gallerythumbframe > img.active").offset().top; var frametop = $(wrapper + " #gallerythumbframe").offset().top; var frameouterHeight = $(wrapper + " #gallerythumbframe").outerHeight(); var frameinnerHeight = $(wrapper + " #gallerythumbframe").innerHeight(); var framedel = frameouterHeight - frameinnerHeight; var rel2 = activetop - frametop; var Nshown2 = Math.floor(rel2/VIVIZ["galleries"][galleryid]["thumbHeight"]); if (debugscroll) { console.log("gallery.setscrollbinding(): Position of active relative to top of document = " + activetop); console.log("gallery.setscrollbinding(): Position of active gallerythumbframe to top of document = " + frametop); console.log("gallery.setscrollbinding(): outerHeight - innerHeight of gallerythumbframe = " + frameinnerHeight + " - " + frameouterHeight + " = " + framedel); console.log("gallery.setscrollbinding(): Offset of active relative to top of gallerythumbframe = " + rel); console.log("gallery.setscrollbinding(): Scroll distance to top of active thumb = " + rel); console.log("gallery.setscrollbinding(): Scroll distance in units of thumbHeight = " + Nshown2); } if (rel < 0) { if (debugscroll) console.log("gallery.setscrollbinding(): Scroll put higher image #s in view."); direction = "forward"; // Need to append Nshown = Nshown - Nshown2; if (debugscroll) console.log("gallery.setscrollbinding(): Last image fully visible in #gallerythumbframe is #" + Nshown + "."); Nlast = parseInt($("#gallerythumbframe img").not(".spacer").last().attr("id")); if (debugscroll) console.log("gallery.setscrollbinding(): Last image in DOM in #gallerythumbframe is #" + Nlast + "."); if ((Nlast-Nshown) < Nlazy) { if (debugscroll) console.log("gallery.setscrollbinding(): Number of images below last fully visible image < Nlazy. Calling loadmore('forward', true)"); loadmore(direction, Nshown, true); } else { if (debugscroll) console.log("gallery.setscrollbinding(): Number of images below last fully visible image >= Nlazy. Not calling loadmore('forward', true)"); } } else { if (debugscroll) console.log("gallery.setscrollbinding(): Scroll put lower image #s in view."); direction = "backward"; // Scroll down. Need to prepend. Nshown = Nshown - Nshown2 - 1; if (debugscroll) console.log("gallery.setscrollbinding(): First image fully visible in #gallerythumbframe is #" + Nshown + "."); Nfirst = parseInt($("#gallerythumbframe img").not(".spacer").first().attr("id")); if (debugscroll) console.log("gallery.setscrollbinding(): First image in DOM in #gallerythumbframe is #" + Nfirst + "."); if (debugscroll) console.log("gallery.setscrollbinding(): Number of images in DOM above it = " + (Nshown-Nfirst) + "."); if ((Nshown-Nfirst) < Nlazy) { if (debugscroll) console.log("gallery.setscrollbinding(): Number of hidden images above it < Nlazy. Calling loadmore('forwward, true')"); loadmore(direction, Nshown, true); } } }) } } function thumb() { tooltip("slider1") $(wrapper + ' button').each(function () {tooltip($(this).attr('id'))}) $("#gallery" + gallerynumber).parent().hide() $("#thumb" + gallerynumber).parent().show() setthumbs() function setthumbbindings() { console.log('thumb.setthumbbindings(): Setting bindings on ' + wrapper); if (!setthumbbindings.active) setthumbbindings.active = {}; $(wrapper + ' .thumbbrowse').unbind('click'); $(wrapper + ' .thumbbrowse').unbind('hover'); $(wrapper + ' .thumbbrowseoverlay').unbind('click'); $(wrapper + ' .thumbbrowseoverlay').unbind('hover'); function setfilename(jq) { $(wrapper + " #filename").html(''); $(wrapper + " #filename").append(""); $(wrapper + " #filename a").attr('href',jq.src.replace(GALLERYINFO['thumbdir'],GALLERYINFO['fulldir'])).text(jq.src.replace(GALLERYINFO['thumbdir'],"")); } function positionoverlay(el) { // Where does this 30 pixels come from? // 30 is $(wrapper + ' #thumbbrowseoverlay').position().{left,right} // Align upper left corners var lt = [$(el).offset().left,$(el).position().top] if (setthumbbindings.overlayDimensions) { // If overlay dimensions known (first overlay loaded) console.log("thumb.positionoverlay(): Overlay dimensions known.") // Offset is relative to document. // Position is relative to the offset of the parent. var elo = wrapper + ' #thumbbrowseoverlay' console.log("Overlay offset left: " + $(elo).offset().left) console.log("Overlay offset top: " + $(elo).offset().top) console.log("Overlay position left: " + $(elo).position().left) console.log("Overlay position top: " + $(elo).position().top) console.log("Overlay width: " + $(elo).width()) console.log("Overlay height: " + $(elo).height()) console.log("Element offset left: " + $(el).offset().left) console.log("Element offset top: " + $(el).offset().top) console.log("Element position left: " + $(el).position().left) console.log("Element position top: " + $(el).position().top) console.log("Element width: " + $(el).width()) console.log("Element height: " + $(el).height()) console.log('Window width: ' + $(window).width()) console.log('Window height: ' + $(window).height()) if ($(el).offset().left > $(window).width()/2) { var lt = [$(el).offset().left-setthumbbindings.overlayDimensions[0]+$(el).outerWidth(),$(el).position().top] } } return lt } // Overlay on click. $(wrapper + ' .thumbbrowse').click(function () { console.log("Thumb click event.") // When switching form gallery to thumb view // last active image in gallery is given a class // of initial so it is easier to see where one left off. // This removes the class when an image is clicked in // the thumbnail view. $(wrapper + " .initial").removeClass('initial'); setthumbbindings.active = this $(setthumbbindings.active).addClass("active") lt = positionoverlay(this) console.log(lt) $(wrapper + ' #thumbbrowseoverlay').parent().prepend('') $(wrapper + ' #thumboverlayloading').css("left", lt[0]).css("top", lt[1]).fadeIn(2000) // http://stackoverflow.com/questions/3877027/jquery-callback-on-image-load-even-when-the-image-is-cached $(wrapper + ' #thumbbrowseoverlay').unbind('load') console.log("Loading overlay.") $(wrapper + ' #thumbbrowseoverlay') .show() .attr("src", $(this).attr("srcfull")) .css("left", lt[0]) .css("top", lt[1]) .error(function () { console.log("Overlay error event.") $(wrapper + ' #thumboverlayloading').remove() $(this).hide() $(setthumbbindings.active).removeClass("active") }) .one("load",function () { console.log("Overlay load event.") setthumbbindings.overlayOffset = [$(wrapper + ' #thumbbrowseoverlay').offset().left, $(wrapper + ' #thumbbrowseoverlay').offset().top] setthumbbindings.overlayPosition = [$(wrapper + ' #thumbbrowseoverlay').position().left, $(wrapper + ' #thumbbrowseoverlay').position().top] setthumbbindings.overlayDimensions = [$(wrapper + ' #thumbbrowseoverlay').outerWidth(), $(wrapper + ' #thumbbrowseoverlay').height()] lt = positionoverlay(setthumbbindings.active) console.log(lt) $(this).css("left", lt[0]) $(this).css("top", lt[1]) $(wrapper + ' #thumboverlayloading').remove() }).each(function() { //if(this.complete) $(this).load(); }) }) // If image is clicked on, close. $(wrapper + ' #thumbbrowseoverlay').click(function(){ console.log("Overlay clicked.") $(wrapper + ' #thumbbrowseoverlay').hide() console.log($(setthumbbindings.active).hasClass("loaderror")) $(setthumbbindings.active).removeClass("active") }) // If image is hovered on and then a hover-out event occurs, close. $(wrapper + ' #thumbbrowseoverlay').hover( function(event){ // Hover in event. console.log("Overlay hover in event.") }, function(){ // Hover out event console.log("Overlay hover out event.") $(wrapper + ' #thumbbrowseoverlay').hide() $(setthumbbindings.active).removeClass("active") }) } function setthumbs() { window.onresize = function onresize() { console.log("thumb.setthumbs(): Zoom or resize event."); } thumb.Nset = 0; // # Set in DOM. thumb.Nloaded = 0; // # For which load event triggered. // Note that we don't have a way of determining when image is // visible or when image size has changed. // This is set to a value by slider change. var newWidth = false; var newHeight = false; var th = 100; // Initial thumb height var tw = 100; // Initial thumb width // Get list of thumbnails in order determined by drop-downs. var INFOjs = thumblist() // Maximum number of thumbnails to load. Will change after we // know how many images fit per row. var maxLength = Math.min(INFOjs.length, VIVIZ["galleries"][galleryid]["lazyLoadMax"] || VIVIZ["config"]["lazyLoadMax"]) // Trigger setting of maxLength images in DOM. loadmore() setscrolltrigger() function loadmore() { // thumb.Nset may change, so get current value. var Nset = thumb.Nset if ($(wrapper).height() < $(window).height()) { console.log("thumb.loadmore(): Called. Nset = " + Nset) console.log("thumb.loadmore(): $(wrapper).height() = " + $(wrapper).height()) console.log("thumb.loadmore(): $(window).height() = " + $(window).height()) console.log("thumb.loadmore(): Loading more images because vertical space is available.") for (var j = Nset; j < Nset+maxLength; j++) { loadone(j) } // This sets bindings on everything. May take a long // time when many are shown. setthumbbindings() } } function objToString (obj) { var str = '' for (var p in obj) { if (obj.hasOwnProperty(p)) {str += p + ':' + obj[p] + '\n'} } return str; } function setslider() { $( "#slider1" ).change(function () { console.log("thumb.setslider(): Slider value changed to " + this.value) newWidth = tw*this.value/4; newHeight = th*this.value/4; $('.thumbbrowse').css('width', newWidth); $('.thumbbrowse').css('height', newHeight); setpadding() loadmore() }) } function setpadding(el) { return; // This never worked well, so // #thumbbrowseframe text-align:center was used. // If one tries, I would use text-align:center // then calculate the b = (offset of the first image // relative to left of #thumbbrowseframe), change // #text-align:left, and then // $("#thumbbrowseframe").css('padding-left', Math.floor(b/2)) // The problem with the following is that the calculated // images per row does not always match what is actually // in browser. I don't know why. // Set left padding so that block of images is centered. // Could avoid this call if #thumbbrowseframe text-align:center was used, // except that if there is an un-filled last row // the images will be centered instead of left-justified. img_ow = $(wrapper + " #thumbbrowseframe img:first").outerWidth() if (!img_ow) { // Use actual element instead of querying DOM. // (Element may be loaded, setpadding() called, but // element may not yet be in DOM.) img_ow = $(el).outerWidth() console.log("thumb.setpadding(): Image " + $(el).attr('id') + " outer width = " + img_ow) } else { console.log("thumb.setpadding(): First image outer width = " + img_ow) } var frame_iw = $("#thumbbrowseframe").innerWidth() console.log("thumb.setpadding(): Inner width of thumbbrowseframe = " + frame_iw) // Only modify padding of #thumbbrowseframe if first image // size has changed or innerWidth has changed. if (typeof(setpadding.last_frame_ow) !== 'undefined') { // Only modify padding if iw or x has changed. if ((setpadding.last_frame_ow == frame_ow) && (setpadding.last_img_ow == img_ow)) { return; } } setpadding.last_frame_iw = frame_iw; setpadding.last_img_ow = img_ow; var pl = parseInt($("#thumbbrowseframe").css('padding-left').replace('px',"")) var pr = parseInt($("#thumbbrowseframe").css('padding-right').replace('px',"")) console.log("thumb.setpadding(): padding-left/right of thumbbrowseframe = " + pl + "/" + pr) a = frame_iw/img_ow console.log("thumb.setpadding(): Expected # images per row = " + Math.floor(a)); b = (a - Math.floor(a))*img_ow if (b < 1) { // Sometimes # images per row calculated does not match actual. // This only sometimes fixes this. //console.log("thumb.setpadding(): Probable # images per row = " + Math.floor(a)-1); //b = img_ow } if (INFOjs.length < Math.floor(a)) { // # of images is less than number of images possible per row. console.log('thumb.setpadding(): Total # images in row ' + INFOjs.length) b = frame_iw - img_ow*INFOjs.length } console.log("thumb.setpadding(): Total extra space = " + b); console.log("thumb.setpadding(): Setting left padding to " + Math.floor(b/2)) $("#thumbbrowseframe").css('padding-left', Math.floor(b/2)) } function loadone(i) { var fixed = false; if (i > INFOjs.length-1) return; thumb.Nset = thumb.Nset+1; if (thumb.Nset == INFOjs.length-1) { $("#instructions").html("All images requested."); $("#instructions2").html("All images requested."); } var src = VIVIZ["galleries"][galleryid]["thumbdirdecoded"] + INFOjs[i]['ThumbFile']; var srcfull = VIVIZ["galleries"][galleryid]["fulldirdecoded"] + INFOjs[i]['FullFile']; $('') .width(newWidth || tw || 100) .attr("src", src) .attr("srcfull", srcfull) .attr("id",i) .css("height",newHeight || th || 100) .attr("title",objToString(INFOjs[i])) .error(function () { $(this).removeClass("loading"); $(this).addClass("loaderror"); //$(this).attr("src","css/transparent.png"); $(this).attr("src", transparent); $(this).width(newWidth || tw || 100); $(this).height(newHeight || th || 100); if (th) { //$('.loaderror').css('height',th); } if (tw > 0 && !fixed) { //fixed = true; //$(".loaderror").width(tw); } }) .load(function () { $(this).removeClass("loading"); // See caveats at https://api.jquery.com/load-event/ // This checks if load event was fired after error event // (and after class was set, hopefully.) var err = $(this).hasClass('loaderror') thumb.Nloaded = thumb.Nloaded + 1 if (!loadone.first && !err) { console.log("thumb.setthumbs.loadone(): First thumbnail loaded.") loadone.first = true // Set thumbWidth and Height in VIVIZ["galleries"][galleryid] var tmp = setWH(this, 'thumb') tw = VIVIZ["galleries"][galleryid]["thumbWidth"] th = VIVIZ["galleries"][galleryid]["thumbHeight"] setslider() } else { console.log("thumb.setthumbs.loadone(): Thumbnail loaded.") } //$(this).click().click() qs = $.parseQueryString() if (qs["number"]) { var initial = parseInt(qs["number"]); } if (i == initial-1) { //xx $(window).scrollTo(this,0) $(this).addClass('initial') } w = Math.floor(newWidth) || tw h = Math.floor(newHeight) || th console.log('thumb.loadone(): Setting width and height of ' + $(this).attr('id') + ' to ' + w + ' and ' + h ); $(this).width(w) $(this).height(h) setpadding(this) loadmore() }) .appendTo($(wrapper + ' #thumbbrowseframe')) } function fillrow(el) { var delta = 0; if (!el) { //el = $(wrapper + " #thumbbrowseframe img:first") } if (loadone.first) { console.log("thumb.setthumbs.fillrow(): #thumbbrowseframe " + "innerWidth:" + $("#thumbbrowseframe").innerWidth()) img_ow = $(wrapper + " #thumbbrowseframe img:first").outerWidth() console.log("thumb.setthumbs.fillrow(): #thumbbrowseframe " + "img:first outerWidth:" + img_ow) if (!img_ow) { // Use actual element instead of querying DOM. // (Element may be loaded, setpadding() called, but // element may not yet be in DOM.) img_ow = $(el).outerWidth() console.log("thumb.fillrow(): Image " + $(el).attr('id') + " outer width = " + img_ow) } else { console.log("thumb.fillrow(): First image outer width = " + img_ow) } var a = Math.floor($("#thumbbrowseframe").innerWidth()/$(el).outerWidth()) console.log("thumb.setthumbs.fillrow(): Images per row = " + a) if (maxLength < a) { console.log("thumb.setthumbs.fillrow(): Changing maxLength from " + maxLength + " to " + a) maxLength = a } else { var c = a*Math.ceil(maxLength/a) console.log("thumb.setthumbs.fillrow(): Changing maxLength from " + maxLength + " to " + c) maxLength = c } console.log("thumb.setthumbs.fillrow(): thumb.Nset = " + thumb.Nset) var delta = a - (thumb.Nset % a) if (delta == a) { // Last row is full delta = 0 } console.log("thumb.setthumbs.fillrow(): Room for " + delta + " more images") } if (!isFinite(delta)) { console.log("thumb.setthumbs.fillrow(): Delta is not finite") return } Nl = thumb.Nset; for (var j = Nl; j < Nl+delta; j++) { loadone(j) } } function setscrolltrigger() { $(window).unbind('scroll'); $(window).scroll(function (e) { var Nset = thumb.Nset if (Nset + maxLength > INFOjs.length - 1) { console.log("thumb.setthumbs.setscrolltrigger(): Nset + maxLength > # images. Resetting maxLength.") maxLength = INFOjs.length-Nset for (var j = Nset; j < Nset+maxLength; j++) { loadone(j) } setthumbbindings() $(window).unbind('scroll') } // Hidden space below is // $(document).height() - ($(window).scrollTop() + $(window).height()) // Want hidden space to be at least 2*th if (2*th + $(window).scrollTop() + $(window).height() >= $(document).height()) { console.log("thumb.setthumbs.setscrolltrigger(): Scroll triggered & criteria satisfied.") console.log("thumb.setthumbs.setscrolltrigger(): maxLength = " + maxLength + ", first thumbheight = " + th) console.log("thumb.setthumbs.setscrolltrigger(): " + "2*th + $(window).scrollTop() + $(window).height() = " + (2*th + $(window).scrollTop() + $(window).height())) console.log("thumb.setthumbs.setscrolltrigger(): $(document).height() = " + ($(document).height())) // TODO: The following code is duplicated in loadmore(). for (var j = Nset; j < Nset+maxLength; j++) { loadone(j) } setthumbbindings() } else { console.log("thumb.setthumbs.setscrolltrigger(): Scroll triggered, but criteria not satisfied.") } }) } } } }