diff options
Diffstat (limited to 'templates/fluid/scripts.js')
| -rw-r--r-- | templates/fluid/scripts.js | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/templates/fluid/scripts.js b/templates/fluid/scripts.js new file mode 100644 index 0000000..7c9bb97 --- /dev/null +++ b/templates/fluid/scripts.js @@ -0,0 +1,351 @@ + +/****************************** EXIF TABLE *********************************/ + +var exif_all_visible = false; + +function set_exif_params (table, icon, visible) { + if (visible) { + table.style.display = 'block'; + icon.style.opacity = 1.0; + } else { + table.style.display = 'none'; + icon.style.opacity = 0.23; + } +} + +function toggle_exif_visibility (id) { + var table = document.getElementById ('exif_table-' + id); + var icon = document.getElementById ('exif_icon-' + id); + set_exif_params (table, icon, icon.style.opacity != 1.0); +} + +function toggle_exif_all_visibility () { + exif_all_visible = !exif_all_visible; + for (var i = 1; table = document.getElementById ("exif_table-" + i); i++) { + var icon = document.getElementById ('exif_icon-' + i); + set_exif_params (table, icon, exif_all_visible); + } +} + + +/**************************** FULLSCREEN MODE *****************************/ + +/* https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode */ +/* FIXME: scrollbar reset in Chromium 40 */ +/* TODO: retain stream mode if active */ +function toggleFullScreen() { + if (!document.fullscreenElement && // alternative standard method + !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) { // current working methods + if (document.documentElement.requestFullscreen) { + document.documentElement.requestFullscreen(); + } else if (document.documentElement.msRequestFullscreen) { + document.documentElement.msRequestFullscreen(); + } else if (document.documentElement.mozRequestFullScreen) { + document.documentElement.mozRequestFullScreen(); + } else if (document.documentElement.webkitRequestFullscreen) { + document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } + } +} + + +/****************************** PHOTOSTREAM *******************************/ + +/* PHOTOSTREAM - INSTRUCTIONS: + * - photos should be embedded in <div id="photos"> + * - every photo should have id="photo-XXX" where XXX is index starting with 1 + * - total number of photos needs to be defined in the NUM_PHOTOS variable + */ + +var current_idx = 0; +var photostream_mode = false; +var scroll_timeout = 0; +var ignore_scroll_event = false; + +var enable_animations = false; +var animation_duration = 175; /* ms */ +var animation_steps = 17; + + + +/* Portions of code taken from Prototype JavaScript framework + * Copyright (c) 2005-2008 Sam Stephenson + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + */ + +function hasClassName (element, className) { + var elementClassName = element.className; + return (elementClassName.length > 0 && (elementClassName == className || + new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); +} + +function addClassName (element, className) { + if (!hasClassName(element, className)) + element.className += (element.className ? ' ' : '') + className; + return element; +} + +function removeClassName (element, className) { + element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').replace(/^\s+/, '').replace(/\s+$/, ''); + return element; +} + +function cumulativeOffset (element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; +} + + +/* http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js */ +/* http://matthewlein.com/experiments/easing.html */ +function fadein (el) { + var op = 0.35; + var t = 0; + var handler = setInterval (function () { + if (op >= 1.0) + clearInterval (handler); + el.style.opacity = op; + op += 1.0 / animation_steps; + t += animation_duration / animation_steps; + var c = 1.0 / animation_steps; + var d = animation_duration; + var b = 0.0; +// op += c - c * Math.cos(t/d * (Math.PI/2)); /* easeInSine */ +// op += c*(t/=d)*t + b; /* easeInQuad */ + }, animation_duration / animation_steps); +} + + +function do_show_photo (do_show, id) { + var elem = document.getElementById (id); + if (! elem) + return; + + if (do_show) { + addClassName (elem, "photostream-force-show"); + if (enable_animations) { + elem.style.opacity = 0.0; + fadein (elem); + } else { + elem.style.opacity = 1.0; + } + } else { + removeClassName (elem, "photostream-force-show"); + elem.style.opacity = 1.0; + } +} + +function start_photostream_mode () { + photostream_mode = true; + + if (NUM_PHOTOS <= 0) + return; + + var l = document.getElementsByClassName('photostream-hide'); + for (var i = 0; i < l.length; i++) + addClassName (l[i], "photostream-force-hide"); + + var elem = document.getElementById ("photostream-close"); + if (elem) + removeClassName (elem, "photostream-force-hide"); + + var elem = document.getElementById ("photostream-position-label"); + if (elem) + removeClassName (elem, "photostream-force-hide"); +} + +function cancel_photostream_mode () { + if (photostream_mode) { + photostream_mode = false; + do_show_photo (false); + + var l = document.getElementsByClassName('photostream-hide'); + for (var i = 0; i < l.length; i++) + removeClassName (l[i], "photostream-force-hide"); + + var elem = document.getElementById ("photostream-close"); + if (elem) + addClassName (elem, "photostream-force-hide"); + + var elem = document.getElementById ("photostream-position-label"); + if (elem) + addClassName (elem, "photostream-force-hide"); + } +} + +function update_position_label () { + var elem = document.getElementById ("photostream-position-label"); + if (elem) + elem.innerHTML = current_idx + " / " + NUM_PHOTOS; +} + +function scroll_to_photo (elem) { + var window_height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight; + var off = cumulativeOffset (elem); + + off[1] += (elem.offsetHeight - window_height) / 2; + /* Dirty workaround to ignore subsequent onScroll events */ + ignore_scroll_event = true; + setTimeout (function () {ignore_scroll_event=false;}, 200); + window.scrollTo (off[0], off[1]); +} + +function set_position (inc) { + var idx; + var elem; + + if (! photostream_mode) + start_photostream_mode (); + + idx = current_idx + inc; + if (idx < 1) + idx = 1; + if (idx > NUM_PHOTOS) + idx = NUM_PHOTOS; + + elem = document.getElementById ("photo-" + idx); + if (! elem) + return; + + do_show_photo (false, "photo-" + current_idx); + do_show_photo (false, "photo-" + current_idx + "-sep"); + do_show_photo (false, "photo-" + current_idx + "-ispc"); + + scroll_to_photo (elem); + do_show_photo (true, "photo-" + idx); + do_show_photo (true, "photo-" + idx + "-sep"); + do_show_photo (true, "photo-" + idx + "-ispc"); + + current_idx = idx; + update_position_label (); +} + +function check_position () { + var win_pos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; + var window_height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight; + var elem; + + current_idx = 0; + for (var i = 1; elem = document.getElementById ("photo-" + i); i++) { + /* Display the first photo when scrolled to the very top of the page */ + if (i == 1 && elem.offsetTop > win_pos + window_height / 2 - elem.clientHeight / 2 + 4) { + current_idx = 0; + break; + } + if (elem.offsetTop > win_pos + window_height / 2) + break; + current_idx = i; + } + + /* Update size buttons' anchors */ + var l = document.getElementsByClassName('size-button'); + for (var i = 0; i < l.length; i++) { + l[i].href = l[i].href.replace(/(#.*)/, ''); + if (current_idx > 0) + l[i].href += '#i' + current_idx; + } + update_position_label (); +} + +function schedule_check_position () { + clearTimeout (scroll_timeout); + scroll_timeout = setTimeout (check_position, 100); +} + + +/* Movement */ +function stop_event (event) { + event.preventDefault (); + event.stopPropagation (); +} + +function onKeyEvent (event) { + if (!event) + event = window.event; + if (!event) + return; + if (event.ctrlKey || event.altKey || event.metaKey) + return; + + var c = event.which ? event.which : event.keyCode; + + switch (c) { + case 32: /* Space */ + case 39: /* Right arrow */ + set_position (1); + stop_event (event); + break; + case 8: /* Backspace */ + if (photostream_mode) { + set_position (-1); + stop_event (event); + } + break; + case 37: /* Left arrow */ + set_position (-1); + stop_event (event); + break; + case 27: /* Escape */ + if (photostream_mode) { + cancel_photostream_mode (); + stop_event (event); + } + schedule_check_position (); + break; + case 68: /* d */ + toggle_exif_all_visibility (); + onResize (null); + break; + case 65: /* a */ + enable_animations = ! enable_animations; + break; + case 70: /* f */ + toggleFullScreen(); + break; + } +} + +function onScroll (event) { + if (ignore_scroll_event) + return; + if (photostream_mode) { + cancel_photostream_mode (); + stop_event (event); + } + schedule_check_position (); +} + +function onResize (event) { + if (photostream_mode) { + var elem = document.getElementById ("photo-" + current_idx); + if (! elem) + return; + scroll_to_photo (elem); + } +} + +function onLoad () { + document.addEventListener ("keydown", onKeyEvent, false); + window.addEventListener ("scroll", onScroll, false); + window.addEventListener ("resize", onResize, false); + schedule_check_position (); +} + +/* this should perform initialization while the page is still loading */ +onLoad(); |
