3 var global_disabled_opacity = 0.1;
4 var global_default_opacity = 0.7;
5 var global_highlight_opacity = 1.0;
6 var global_infobox = true;
11 return [window.innerWidth * dpr, window.innerHeight * dpr];
16 return window.devicePixelRatio || 1;
20 * pr0n can resize to any size we'd like, but we're much more likely
21 * to have this set of fixed-resolution screens cached, so to increase
22 * performance, we round down to the closest fit and use that. This
23 * function is a pessimal estimate of what thumbnail size we can _always_
24 * fit on the screen -- it's right if and only if all images are 4:3
25 * (and landscape). If individual size information is available, use
26 * pick_image_size, below.
48 function max_image_size(screen_size)
51 for (i = 0; i < fixed_sizes.length; ++i) {
52 if (screen_size[0] >= fixed_sizes[i][0] && screen_size[1] >= fixed_sizes[i][1]) {
53 return fixed_sizes[i];
59 function pick_image_size(screen_size, image_size)
62 for (i = 0; i < fixed_sizes.length; ++i) {
63 // this is a duplicate of pr0n's resizing code, hope for no floating-point
65 var thumbxres = fixed_sizes[i][0];
66 var thumbyres = fixed_sizes[i][1];
67 var width = image_size[0];
68 var height = image_size[1];
70 if (!(thumbxres >= width && thumbyres >= height)) {
71 var sfh = width / thumbxres;
72 var sfv = height / thumbyres;
80 width = Math.floor(width);
81 height = Math.floor(height);
84 if (screen_size[0] >= width && screen_size[1] >= height) {
85 // be sure _not_ to return a reference
86 return [ fixed_sizes[i][0], fixed_sizes[i][1], width, height ];
92 function replace_image_element(url, element_id, parent_node)
94 var img = document.getElementById(element_id);
96 if (img.src === url) {
99 img.parentNode.removeChild(img);
102 img = document.createElement("img");
106 parent_node.appendChild(img);
110 function rename_element(old_name, new_name)
112 // Remove any element that's in the way.
113 var elem = document.getElementById(new_name);
115 elem.parentNode.removeChild(elem);
118 elem = document.getElementById(old_name);
125 function display_image(width, height, evt, filename, element_id)
127 var url = window.location.origin + "/" + evt + "/" + width + "x" + height + "/" + filename;
128 var main = document.getElementById("iehack");
129 var preload = document.getElementById("preload");
130 var dpr = find_dpr();
132 // See if we have a preload going on that we can reuse.
133 if (element_id == "image" && preload !== null && preload.src == url) {
134 rename_element("preload_box", "image_box");
135 img = rename_element("preload", "image");
137 img = replace_image_element(url, element_id, main);
139 img.style.position = "absolute";
140 img.style.left = "0px";
141 img.style.top = "0px";
142 img.style.transformOrigin = "top left";
143 img.style.transform = "scale(" + (1.0 / dpr) + ")";
145 if (element_id == "image") {
146 // Update the "download original" link.
147 var original_url = window.location.origin + "/" + evt + "/original/" + filename;
148 document.getElementById("origdownload").href = original_url;
150 // If it's a raw image, show a JPEG link.
151 var fulldownload = document.getElementById("fulldownload");
152 if (filename.match(/\.(nef|cr2)$/i)) {
153 fulldownload.style.display = "block";
154 var full_url = window.location.origin + "/" + evt + "/" + filename;
155 document.getElementById("fulldownloadlink").href = full_url;
156 origdownload.innerHTML = "Download original image (RAW)";
158 fulldownload.style.display = "none";
159 origdownload.innerHTML = "Download original image";
163 if (global_infobox) {
166 url = window.location.origin + "/" + evt + "/" + width + "x" + height + "/box/" + filename;
168 url = window.location.origin + "/" + evt + "/" + width + "x" + height + "@" + dpr.toFixed(2) + "/box/" + filename;
170 var boximg = replace_image_element(url, element_id + "_box", main);
172 boximg.style.position = "absolute";
173 boximg.style.left = "0px";
174 boximg.style.bottom = "-1px";
175 boximg.style.transformOrigin = "bottom left";
176 boximg.style.transform = "scale(" + (1.0 / dpr) + ")";
178 var boximg = document.getElementById(element_id + "_box");
179 if (boximg !== null) {
180 boximg.parentNode.removeChild(boximg);
187 function display_image_num(num, element_id)
189 var screen_size = find_width();
192 if (global_image_list[num][2] == -1) {
193 // no size information, use our pessimal guess
194 adjusted_size = max_image_size(screen_size);
196 adjusted_size = pick_image_size(screen_size, [ global_image_list[num][2], global_image_list[num][3] ]);
199 var img = display_image(adjusted_size[0], adjusted_size[1], global_image_list[num][0], global_image_list[num][1], element_id);
201 if (element_id == "image") {
202 // we want to shrink the box as much as possible if we know the true
206 // replace the anchor part (if any) with the image number
207 window.location.hash = "#" + (num+1);
213 function prepare_preload(img, num)
215 // cancel any pending preload
216 var preload = document.getElementById("preload");
217 if (preload !== null) {
218 preload.parentNode.removeChild(preload);
221 var preload_box = document.getElementById("preload_box");
222 if (preload_box !== null) {
223 preload_box.parentNode.removeChild(preload_box);
226 // grmf -- IE doesn't fire onload if the image was loaded from cache, so check for
227 // completeness first; should at least be _somewhat_ better
229 display_image_num(num, "preload");
231 img.onload = function() { display_image_num(num, "preload"); };
235 function can_go_next()
237 return (global_image_num < global_image_list.length - 1);
240 function can_go_previous()
242 return (global_image_num > 0);
245 function set_opacity(id, amount)
247 var elem = document.getElementById(id);
249 // If optionmenu is visible, options is also visible.
250 if (id === "options" && amount < 0.7) {
251 var optionmenu = document.getElementById("optionmenu");
252 if (optionmenu.style.display === "block") {
256 elem.style.opacity = amount;
259 function center_image(num)
261 var screen_size = find_width();
262 var dpr = find_dpr();
265 if (global_image_list[num][2] == -1) {
266 // no size information, use our pessimal guess
267 var adjusted_size = max_image_size(screen_size);
268 width = adjusted_size[0];
269 height = adjusted_size[1];
271 // use the exact information
272 var adjusted_size = pick_image_size(screen_size, [ global_image_list[num][2], global_image_list[num][3] ]);
273 width = adjusted_size[2];
274 height = adjusted_size[3];
277 // center the image on-screen
278 var main = document.getElementById("main");
279 main.style.position = "absolute";
280 main.style.left = (((screen_size[0] - width) / 2) / dpr) + "px";
281 main.style.top = (((screen_size[1] - height) / 2) / dpr) + "px";
282 main.style.width = (width / dpr) + "px";
283 main.style.height = (height / dpr) + "px";
284 main.style.lineHeight = (height / dpr) + "px";
289 var img = display_image_num(global_image_num, "image");
291 prepare_preload(img, global_image_num + 1);
294 set_opacity("previous", can_go_previous() ? global_default_opacity : global_disabled_opacity);
295 set_opacity("next", can_go_next() ? global_default_opacity : global_disabled_opacity);
296 set_opacity("close", global_default_opacity);
297 set_opacity("options", global_default_opacity);
300 function go_previous()
302 if (!can_go_previous()) {
306 var img = display_image_num(--global_image_num, "image");
307 if (can_go_previous()) {
308 set_opacity("previous", global_default_opacity);
309 prepare_preload(img, global_image_num - 1);
311 set_opacity("previous", global_disabled_opacity);
313 set_opacity("next", can_go_next() ? global_default_opacity : global_disabled_opacity);
318 if (!can_go_next()) {
322 var img = display_image_num(++global_image_num, "image");
324 set_opacity("next", global_default_opacity);
325 prepare_preload(img, global_image_num + 1);
327 set_opacity("next", global_disabled_opacity);
329 set_opacity("previous", can_go_previous() ? global_default_opacity : global_disabled_opacity);
334 if (global_image_num > 0) {
335 window.location = global_return_url + '#' + (global_image_num + 1);
337 window.location = global_return_url;
341 function toggle_optionmenu()
343 var optionmenu = document.getElementById("optionmenu");
344 if (optionmenu.style.display === "block") {
345 optionmenu.style.display = "none";
347 optionmenu.style.display = "block";
348 set_opacity("options", 0.7);
351 window['toggle_optionmenu'] = toggle_optionmenu;
353 function draw_text(msg)
355 // remove any text we might have left
356 var text = document.getElementById("text");
358 text.parentNode.removeChild(text);
361 text = document.createElement("p");
363 text.style.position = "absolute";
364 text.style.color = "white";
365 text.style.lineHeight = "24px";
366 text.style.font = "24px verdana, arial, sans-serif";
367 text.innerHTML = msg;
369 var main = document.getElementById("main");
370 main.appendChild(text);
372 text.style.left = (main.clientWidth - text.clientWidth) / 2 + "px";
373 text.style.top = (main.clientHeight - text.clientHeight) / 2 + "px";
376 function fade_text(opacity)
378 set_opacity("text", opacity);
384 setTimeout(function() { fade_text(opacity); }, 30);
386 var text = document.getElementById("text");
388 text.parentNode.removeChild(text);
393 function select_image(evt, filename, selected)
396 draw_text("Selecting " + filename + "...");
398 draw_text("Unselecting " + filename + "...");
401 var req = new XMLHttpRequest();
402 req.open("POST", window.location.origin + "/select", false);
403 req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
404 req.send("event=" + evt + "&filename=" + filename + "&selected=" + selected);
406 setTimeout(function() { fade_text(0.99); }, 30);
409 function key_down(which)
411 if (which == 39) { // right
413 set_opacity("next", global_highlight_opacity);
415 } else if (which == 37) { // left
416 if (can_go_previous()) {
417 set_opacity("previous", global_highlight_opacity);
419 } else if (which == 27) { // escape
420 set_opacity("close", global_higlight_opacity);
422 check_for_hash_change();
426 function key_up(which) {
427 if (which == 39) { // right
429 set_opacity("next", global_default_opacity);
432 } else if (which == 37) { // left
433 if (can_go_previous()) {
434 set_opacity("previous", global_default_opacity);
437 } else if (which == 27) { // escape
438 set_opacity("close", global_default_opacity);
440 } else if (which == 32 && global_select) { // space
441 select_image(global_image_list[global_image_num][0], global_image_list[global_image_num][1], 1);
442 } else if (which == 85 && global_select) { // u
443 select_image(global_image_list[global_image_num][0], global_image_list[global_image_num][1], 0);
445 check_for_hash_change();
449 function parse_image_num(default_value) {
450 var num = parseInt(window.location.hash.substr(1));
451 if (num >= 1 && num <= global_image_list.length) { // and then num != NaN
454 return default_value;
457 window['parse_image_num'] = parse_image_num;
459 function check_for_hash_change() {
460 var num = parse_image_num(-1);
461 if (num != -1 && num != global_image_num) {
462 global_image_num = num;
467 function toggle_immersive() {
468 if (global_default_opacity == 0.7) {
469 global_disabled_opacity = 0.0;
470 global_default_opacity = 0.0;
471 global_highlight_opacity = 0.2;
472 global_infobox = false;
473 document.getElementById('immersivetoggle').innerHTML = 'Show decorations';
475 global_disabled_opacity = 0.1;
476 global_default_opacity = 0.7;
477 global_highlight_opacity = 1.0;
478 global_infobox = true;
479 document.getElementById('immersivetoggle').innerHTML = 'Hide all decorations';
483 window['toggle_immersive'] = toggle_immersive;
485 window.onload = function() {
487 setInterval(check_for_hash_change, 1000);
489 var body = document.body;
490 body.onresize = function() { relayout(); };
491 body.onkeydown = function(evt) { key_down(evt.keyCode); };
492 body.onkeyup = function(evt) { key_up(evt.keyCode); };
493 body.onhashchange = function() { check_for_hash_change(); };
494 body.onclick = function() { check_for_hash_change(); };
496 var previous = document.getElementById('previous');
497 previous.onmousedown = function() { if (can_go_previous()) { set_opacity('previous', global_highlight_opacity); } };
498 previous.onmouseup = function() { if (can_go_previous()) { set_opacity('previous', global_default_opacity); go_previous(); } };
499 previous.onmouseout = function() { if (can_go_previous()) { set_opacity('previous', global_default_opacity); } };
501 var next = document.getElementById('next');
502 next.onmousedown = function() { if (can_go_next()) { set_opacity('next', global_highlight_opacity); } };
503 next.onmouseup = function() { if (can_go_next()) { set_opacity('next', global_default_opacity); go_next(); } };
504 next.onmouseout = function() { if (can_go_next()) { set_opacity('next', global_default_opacity); } };
506 var close = document.getElementById('close');
507 close.onmousedown = function() { set_opacity('close', global_highlight_opacity); };
508 close.onmouseup = function() { set_opacity('close', global_default_opacity); do_close(); };
509 close.onmouseout = function() { set_opacity('close', global_default_opacity); };
511 var options = document.getElementById('options');
512 options.onmousedown = function() { set_opacity('options', global_highlight_opacity); };
513 options.onmouseup = function() { set_opacity('options', global_default_opacity); toggle_optionmenu(); };
514 options.onmouseout = function() { set_opacity('options', global_default_opacity); };