/wojilu.Web/static/js/galleria/galleria-1.2.4.js
JavaScript | 4754 lines | 2796 code | 999 blank | 959 comment | 386 complexity | cf71846c52bb89258f17f867092deef9 MD5 | raw file
Possible License(s): MIT
Large files files are truncated, but you can click here to view the full file
- /**
- * @preserve Galleria v 1.2.4 2011-06-07
- * http://galleria.aino.se
- *
- * Copyright (c) 2011, Aino
- * Licensed under the MIT license.
- */
- /*global jQuery, navigator, Galleria, Image */
- (function( $ ) {
- // some references
- var undef,
- window = this,
- doc = window.document,
- $doc = $( doc ),
- $win = $( window ),
- // internal constants
- DEBUG = true,
- NAV = navigator.userAgent.toLowerCase(),
- HASH = window.location.hash.replace(/#\//, ''),
- IE = (function() {
- var v = 3,
- div = doc.createElement( 'div' ),
- all = div.getElementsByTagName( 'i' );
- do {
- div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->';
- } while ( all[0] );
- return v > 4 ? v : undef;
- }() ),
- DOM = function() {
- return {
- html: doc.documentElement,
- body: doc.body,
- head: doc.getElementsByTagName('head')[0],
- title: doc.title
- };
- },
- // list of Galleria events
- _eventlist = 'data ready thumbnail loadstart loadfinish image play pause progress ' +
- 'fullscreen_enter fullscreen_exit idle_enter idle_exit rescale ' +
- 'lightbox_open lightbox_close lightbox_image',
- _events = (function() {
- var evs = [];
- $.each( _eventlist.split(' '), function( i, ev ) {
- evs.push( ev );
- // legacy events
- if ( /_/.test( ev ) ) {
- evs.push( ev.replace( /_/g, '' ) );
- }
- });
- return evs;
- }()),
- // legacy options
- // allows the old my_setting syntax and converts it to camel case
- _legacyOptions = function( options ) {
- var n;
- if ( typeof options !== 'object' ) {
- // return whatever it was...
- return options;
- }
- $.each( options, function( key, value ) {
- if ( /^[a-z]+_/.test( key ) ) {
- n = '';
- $.each( key.split('_'), function( i, k ) {
- n += i > 0 ? k.substr( 0, 1 ).toUpperCase() + k.substr( 1 ) : k;
- });
- options[ n ] = value;
- delete options[ key ];
- }
- });
- return options;
- },
- _patchEvent = function( type ) {
- // allow 'image' instead of Galleria.IMAGE
- if ( $.inArray( type, _events ) > -1 ) {
- return Galleria[ type.toUpperCase() ];
- }
- return type;
- },
- // the internal timeouts object
- // provides helper methods for controlling timeouts
- _timeouts = {
- trunk: {},
- add: function( id, fn, delay, loop ) {
- loop = loop || false;
- this.clear( id );
- if ( loop ) {
- var old = fn;
- fn = function() {
- old();
- _timeouts.add( id, fn, delay );
- };
- }
- this.trunk[ id ] = window.setTimeout( fn, delay );
- },
- clear: function( id ) {
- var del = function( i ) {
- window.clearTimeout( this.trunk[ i ] );
- delete this.trunk[ i ];
- }, i;
- if ( !!id && id in this.trunk ) {
- del.call( _timeouts, id );
- } else if ( typeof id === 'undefined' ) {
- for ( i in this.trunk ) {
- if ( this.trunk.hasOwnProperty( i ) ) {
- del.call( _timeouts, i );
- }
- }
- }
- }
- },
- // the internal gallery holder
- _galleries = [],
- // the internal instance holder
- _instances = [],
- // flag for errors
- _hasError = false,
- // canvas holder
- _canvas = false,
- // the Utils singleton
- Utils = (function() {
- return {
- array : function( obj ) {
- return Array.prototype.slice.call(obj);
- },
- create : function( className, nodeName ) {
- nodeName = nodeName || 'div';
- var elem = doc.createElement( nodeName );
- elem.className = className;
- return elem;
- },
-
- // CSS3 transitions, added in 1.2.4
- animate : (function() {
-
- // detect transition
- var transition = (function( style ) {
- var props = 'transition WebkitTransition MozTransition OTransition'.split(' '),
- i;
-
- for ( i = 0; props[i]; i++ ) {
- if ( typeof style[ props[ i ] ] !== 'undefined' ) {
- return props[ i ];
- }
- }
- return false;
- }(( document.body || document.documentElement).style ));
-
- // map transitionend event
- var endEvent = {
- MozTransition: 'transitionend',
- OTransition: 'oTransitionEnd',
- WebkitTransition: 'webkitTransitionEnd',
- transition: 'transitionend'
- }[ transition ];
- // map bezier easing conversions
- var easings = {
- _default: [0.25, 0.1, 0.25, 1],
- galleria: [0.645, 0.045, 0.355, 1],
- galleriaIn: [0.55, 0.085, 0.68, 0.53],
- galleriaOut: [0.25, 0.46, 0.45, 0.94],
- ease: [0.25, 0, 0.25, 1],
- linear: [0.25, 0.25, 0.75, 0.75],
- 'ease-in': [0.42, 0, 1, 1],
- 'ease-out': [0, 0, 0.58, 1],
- 'ease-in-out': [0.42, 0, 0.58, 1]
- };
-
- // function for setting transition css for all browsers
- var setStyle = function( elem, value, suffix ) {
- var css = {};
- suffix = suffix || 'transition';
- $.each( 'webkit moz ms o'.split(' '), function() {
- css[ '-' + this + '-' + suffix ] = value;
- });
- elem.css( css );
- };
-
- // clear styles
- var clearStyle = function( elem ) {
- setStyle( elem, 'none', 'transition' );
- if ( Galleria.WEBKIT ) {
- setStyle( elem, 'translate3d(0,0,0)', 'transform' );
- if ( elem.data('revert') ) {
- elem.css( elem.data('revert') );
- elem.data('revert', null);
- }
- }
- };
-
- // various variables
- var change, strings, easing, syntax, revert, form, css;
-
- // the actual animation method
- return function( elem, to, options ) {
-
- // extend defaults
- options = $.extend({
- duration: 400,
- complete: function(){},
- stop: false
- }, options);
-
- // cache jQuery instance
- elem = $( elem );
-
- if ( !options.duration ) {
- elem.css( to );
- options.complete.call( elem[0] );
- return;
- }
- // fallback to jQuery’s animate if transition is not supported
- if ( !transition ) {
- elem.animate(to, options);
- return;
- }
-
- // stop
- if ( options.stop ) {
- // clear the animation
- elem.unbind( endEvent );
- clearStyle( elem );
- }
-
- // see if there is a change
- change = false;
- $.each( to, function( key, val ) {
- css = elem.css( key );
- if ( Utils.parseValue( css ) != Utils.parseValue( val ) ) {
- change = true;
- }
- // also add computed styles for FF
- elem.css( key, css );
- });
- if ( !change ) {
- window.setTimeout( function() {
- options.complete.call( elem[0] );
- }, options.duration );
- return;
- }
-
- // the css strings to be applied
- strings = [];
-
- // the easing bezier
- easing = options.easing in easings ? easings[ options.easing ] : easings._default;
-
- // the syntax
- syntax = ' ' + options.duration + 'ms' + ' cubic-bezier(' + easing.join(',') + ')';
-
- // add a tiny timeout so that the browsers catches any css changes before animating
- window.setTimeout(function() {
- // attach the end event
- elem.one(endEvent, (function( elem ) {
- return function() {
- // clear the animation
- clearStyle(elem);
-
- // run the complete method
- options.complete.call(elem[0]);
- };
- }( elem )));
-
- // do the webkit translate3d for better performance on iOS
- if( Galleria.WEBKIT && Galleria.TOUCH ) {
-
- revert = {};
- form = [0,0,0];
- $.each( ['left', 'top'], function(i, m) {
- if ( m in to ) {
- form[ i ] = ( Utils.parseValue( to[ m ] ) - Utils.parseValue(elem.css( m )) ) + 'px';
- revert[ m ] = to[ m ];
- delete to[ m ];
- }
- });
- if ( form[0] || form[1]) {
-
- elem.data('revert', revert);
-
- strings.push('-webkit-transform' + syntax);
-
- // 3d animate
- setStyle( elem, 'translate3d(' + form.join(',') + ')', 'transform');
- }
- }
-
- // push the animation props
- $.each(to, function( p, val ) {
- strings.push(p + syntax);
- });
- // set the animation styles
- setStyle( elem, strings.join(',') );
-
- // animate
- elem.css( to );
- },1 );
- };
- }()),
- forceStyles : function( elem, styles ) {
- elem = $(elem);
- if ( elem.attr( 'style' ) ) {
- elem.data( 'styles', elem.attr( 'style' ) ).removeAttr( 'style' );
- }
- elem.css( styles );
- },
- revertStyles : function() {
- $.each( Utils.array( arguments ), function( i, elem ) {
- elem = $( elem );
- elem.removeAttr( 'style' );
-
- elem.attr('style',''); // "fixes" webkit bug
- if ( elem.data( 'styles' ) ) {
- elem.attr( 'style', elem.data('styles') ).data( 'styles', null );
- }
- });
- },
- moveOut : function( elem ) {
- Utils.forceStyles( elem, {
- position: 'absolute',
- left: -10000
- });
- },
- moveIn : function() {
- Utils.revertStyles.apply( Utils, Utils.array( arguments ) );
- },
- hide : function( elem, speed, callback ) {
- elem = $(elem);
- // save the value if not exist
- if (! elem.data('opacity') ) {
- elem.data('opacity', elem.css('opacity') );
- }
- // always hide
- var style = { opacity: 0 };
- if (speed) {
- Utils.animate( elem, style, {
- duration: speed,
- complete: callback,
- stop: true
- });
- } else {
- elem.css( style );
- }
- },
- show : function( elem, speed, callback ) {
- elem = $(elem);
- // bring back saved opacity
- var saved = parseFloat( elem.data('opacity') ) || 1,
- style = { opacity: saved };
- // animate or toggle
- if (speed) {
- Utils.animate( elem, style, {
- duration: speed,
- complete: callback,
- stop: true
- });
- } else {
- elem.css( style );
- }
- },
-
-
- // enhanced click for mobile devices
- // we bind a touchstart and hijack any click event in the bubble
- // then we execute the click directly and save it in a separate data object for later
- optimizeTouch: (function() {
-
- var node,
- evs,
- fakes,
- travel,
- evt = {},
- handler = function( e ) {
- e.preventDefault();
- evt = $.extend({}, e, true);
- },
- attach = function() {
- this.evt = evt;
- },
- fake = function() {
- this.handler.call(node, this.evt);
- };
-
- return function( elem ) {
-
- $(elem).bind('touchstart', function( e ) {
- node = e.target;
- travel = true;
-
- while( node.parentNode && node != e.currentTarget && travel ) {
-
- evs = $(node).data('events');
- fakes = $(node).data('fakes');
-
- if (evs && 'click' in evs) {
-
- travel = false;
- e.preventDefault();
-
- // fake the click and save the event object
- $(node).click(handler).click();
-
- // remove the faked click
- evs.click.pop();
-
- // attach the faked event
- $.each( evs.click, attach);
-
- // save the faked clicks in a new data object
- $(node).data('fakes', evs.click);
-
- // remove all clicks
- delete evs.click;
- } else if ( fakes ) {
-
- travel = false;
- e.preventDefault();
-
- // fake all clicks
- $.each( fakes, fake );
- }
-
- // bubble
- node = node.parentNode;
- }
- });
- };
- }()),
- addTimer : function() {
- _timeouts.add.apply( _timeouts, Utils.array( arguments ) );
- return this;
- },
- clearTimer : function() {
- _timeouts.clear.apply( _timeouts, Utils.array( arguments ) );
- return this;
- },
- wait : function(options) {
- options = $.extend({
- until : function() { return false; },
- success : function() {},
- error : function() { Galleria.raise('Could not complete wait function.'); },
- timeout: 3000
- }, options);
- var start = Utils.timestamp(),
- elapsed,
- now,
- fn = function() {
- now = Utils.timestamp();
- elapsed = now - start;
- if ( options.until( elapsed ) ) {
- options.success();
- return false;
- }
- if (now >= start + options.timeout) {
- options.error();
- return false;
- }
- window.setTimeout(fn, 2);
- };
- window.setTimeout(fn, 2);
- },
- toggleQuality : function( img, force ) {
- if ( ( IE !== 7 && IE !== 8 ) || !img ) {
- return;
- }
- if ( typeof force === 'undefined' ) {
- force = img.style.msInterpolationMode === 'nearest-neighbor';
- }
- img.style.msInterpolationMode = force ? 'bicubic' : 'nearest-neighbor';
- },
- insertStyleTag : function( styles ) {
- var style = doc.createElement( 'style' );
- DOM().head.appendChild( style );
- if ( style.styleSheet ) { // IE
- style.styleSheet.cssText = styles;
- } else {
- var cssText = doc.createTextNode( styles );
- style.appendChild( cssText );
- }
- },
- // a loadscript method that works for local scripts
- loadScript: function( url, callback ) {
- var done = false,
- script = $('<scr'+'ipt>').attr({
- src: url,
- async: true
- }).get(0);
- // Attach handlers for all browsers
- script.onload = script.onreadystatechange = function() {
- if ( !done && (!this.readyState ||
- this.readyState === 'loaded' || this.readyState === 'complete') ) {
- done = true;
- // Handle memory leak in IE
- script.onload = script.onreadystatechange = null;
- if (typeof callback === 'function') {
- callback.call( this, this );
- }
- }
- };
- DOM().head.appendChild( script );
- },
- // parse anything into a number
- parseValue: function( val ) {
- if (typeof val === 'number') {
- return val;
- } else if (typeof val === 'string') {
- var arr = val.match(/\-?\d|\./g);
- return arr && arr.constructor === Array ? arr.join('')*1 : 0;
- } else {
- return 0;
- }
- },
- // timestamp abstraction
- timestamp: function() {
- return new Date().getTime();
- },
- // this is pretty crap, but works for now
- // it will add a callback, but it can't guarantee that the styles can be fetched
- // using getComputedStyle further checking needed, possibly a dummy element
- loadCSS : function( href, id, callback ) {
- var link,
- ready = false,
- length;
- // look for manual css
- $('link[rel=stylesheet]').each(function() {
- if ( new RegExp( href ).test( this.href ) ) {
- link = this;
- return false;
- }
- });
- if ( typeof id === 'function' ) {
- callback = id;
- id = undef;
- }
- callback = callback || function() {}; // dirty
- // if already present, return
- if ( link ) {
- callback.call( link, link );
- return link;
- }
- // save the length of stylesheets to check against
- length = doc.styleSheets.length;
- // add timestamp if DEBUG is true
- if ( DEBUG ) {
- href += '?' + Utils.timestamp();
- }
- // check for existing id
- if( $('#'+id).length ) {
- $('#'+id).attr('href', href);
- length--;
- ready = true;
- } else {
- link = $( '<link>' ).attr({
- rel: 'stylesheet',
- href: href,
- id: id
- }).get(0);
- window.setTimeout(function() {
- var styles = $('link[rel="stylesheet"], style');
- if ( styles.length ) {
- styles.get(0).parentNode.insertBefore( link, styles[0] );
- } else {
- DOM().head.appendChild( link );
- }
- if ( IE ) {
- // IE has a limit of 31 stylesheets in one document
- if( length >= 31 ) {
- Galleria.raise( 'You have reached the browser stylesheet limit (31)', true );
- return;
- }
- // todo: test if IE really needs the readyState
- link.onreadystatechange = function(e) {
- if ( !ready && (!this.readyState ||
- this.readyState === 'loaded' || this.readyState === 'complete') ) {
- ready = true;
- }
- };
- } else {
- // final test via ajax if not local
- if ( !( new RegExp('file://','i').test( href ) ) ) {
- $.ajax({
- url: href,
- success: function() {
- ready = true;
- },
- error: function(e) {
- // pass if origin is rejected in chrome for some reason
- if( e.isRejected() && Galleria.WEBKIT ) {
- ready = true;
- }
- }
- });
- } else {
- ready = true;
- }
- }
- }, 10);
- }
- if ( typeof callback === 'function' ) {
- Utils.wait({
- until: function() {
- return ready && doc.styleSheets.length > length;
- },
- success: function() {
- window.setTimeout( function() {
- callback.call( link, link );
- }, 100);
- },
- error: function() {
- Galleria.raise( 'Theme CSS could not load', true );
- },
- timeout: 10000
- });
- }
- return link;
- }
- };
- }()),
- // the transitions holder
- _transitions = (function() {
-
- var _slide = function(params, complete, fade, door) {
-
- var easing = this.getOptions('easing'),
- distance = this.getStageWidth(),
- from = { left: distance * ( params.rewind ? -1 : 1 ) },
- to = { left: 0 };
-
- if ( fade ) {
- from.opacity = 0;
- to.opacity = 1;
- }
-
- $(params.next).css(from);
-
- Utils.animate(params.next, to, {
- duration: params.speed,
- complete: (function( elems ) {
- return function() {
- complete();
- elems.css({
- left: 0
- });
- };
- }( $( params.next ).add( params.prev ) )),
- queue: false,
- easing: easing
- });
- if (door) {
- params.rewind = !params.rewind;
- }
- if (params.prev) {
-
- from = { left: 0 };
- to = { left: distance * ( params.rewind ? 1 : -1 ) };
-
- if ( fade ) {
- from.opacity = 1;
- to.opacity = 0;
- }
-
- $(params.prev).css(from);
- Utils.animate(params.prev, to, {
- duration: params.speed,
- queue: false,
- easing: easing,
- complete: function() {
- $(this).css('opacity', 0);
- }
- });
- }
- };
-
- return {
- fade: function(params, complete) {
- $(params.next).css('opacity',0).show();
- Utils.animate(params.next, {
- opacity: 1
- },{
- duration: params.speed,
- complete: complete
- });
- if (params.prev) {
- $(params.prev).css('opacity',1).show();
- Utils.animate(params.prev, {
- opacity: 0
- },{
- duration: params.speed
- });
- }
- },
- flash: function(params, complete) {
- $(params.next).css('opacity', 0);
- if (params.prev) {
- Utils.animate( params.prev, {
- opacity: 0
- },{
- duration: params.speed/2,
- complete: function() {
- Utils.animate( params.next, {
- opacity:1
- },{
- duration: params.speed,
- complete: complete
- });
- }
- });
- } else {
- Utils.animate( params.next, {
- opacity: 1
- },{
- duration: params.speed,
- complete: complete
- });
- }
- },
- pulse: function(params, complete) {
- if (params.prev) {
- $(params.prev).hide();
- }
- $(params.next).css('opacity', 0).show();
- Utils.animate(params.next, {
- opacity:1
- },{
- duration: params.speed,
- complete: complete
- });
- },
- slide: function(params, complete) {
- _slide.apply( this, Utils.array( arguments ) );
- },
- fadeslide: function(params, complete) {
- _slide.apply( this, Utils.array( arguments ).concat( [true] ) );
- },
-
- doorslide: function(params, complete) {
- _slide.apply( this, Utils.array( arguments ).concat( [false, true] ) );
- }
- };
- })();
- /**
- The main Galleria class
- @class
- @constructor
- @example var gallery = new Galleria();
- @author http://aino.se
- @requires jQuery
- */
- var Galleria = function() {
- var self = this;
-
- // the theme used
- this._theme = undef;
- // internal options
- this._options = {};
- // flag for controlling play/pause
- this._playing = false;
- // internal interval for slideshow
- this._playtime = 5000;
- // internal variable for the currently active image
- this._active = null;
- // the internal queue, arrayified
- this._queue = { length: 0 };
- // the internal data array
- this._data = [];
- // the internal dom collection
- this._dom = {};
- // the internal thumbnails array
- this._thumbnails = [];
- // internal init flag
- this._initialized = false;
-
- // internal firstrun flag
- this._firstrun = false;
- // global stagewidth/height
- this._stageWidth = 0;
- this._stageHeight = 0;
- // target holder
- this._target = undef;
- // instance id
- this._id = Math.random();
- // add some elements
- var divs = 'container stage images image-nav image-nav-left image-nav-right ' +
- 'info info-text info-title info-description ' +
- 'thumbnails thumbnails-list thumbnails-container thumb-nav-left thumb-nav-right ' +
- 'loader counter tooltip',
- spans = 'current total';
- $.each( divs.split(' '), function( i, elemId ) {
- self._dom[ elemId ] = Utils.create( 'galleria-' + elemId );
- });
- $.each( spans.split(' '), function( i, elemId ) {
- self._dom[ elemId ] = Utils.create( 'galleria-' + elemId, 'span' );
- });
- // the internal keyboard object
- // keeps reference of the keybinds and provides helper methods for binding keys
- var keyboard = this._keyboard = {
- keys : {
- 'UP': 38,
- 'DOWN': 40,
- 'LEFT': 37,
- 'RIGHT': 39,
- 'RETURN': 13,
- 'ESCAPE': 27,
- 'BACKSPACE': 8,
- 'SPACE': 32
- },
- map : {},
- bound: false,
- press: function(e) {
- var key = e.keyCode || e.which;
- if ( key in keyboard.map && typeof keyboard.map[key] === 'function' ) {
- keyboard.map[key].call(self, e);
- }
- },
- attach: function(map) {
- var key, up;
- for( key in map ) {
- if ( map.hasOwnProperty( key ) ) {
- up = key.toUpperCase();
- if ( up in keyboard.keys ) {
- keyboard.map[ keyboard.keys[up] ] = map[key];
- } else {
- keyboard.map[ up ] = map[key];
- }
- }
- }
- if ( !keyboard.bound ) {
- keyboard.bound = true;
- $doc.bind('keydown', keyboard.press);
- }
- },
- detach: function() {
- keyboard.bound = false;
- keyboard.map = {};
- $doc.unbind('keydown', keyboard.press);
- }
- };
- // internal controls for keeping track of active / inactive images
- var controls = this._controls = {
- 0: undef,
- 1: undef,
- active : 0,
- swap : function() {
- controls.active = controls.active ? 0 : 1;
- },
- getActive : function() {
- return controls[ controls.active ];
- },
- getNext : function() {
- return controls[ 1 - controls.active ];
- }
- };
- // internal carousel object
- var carousel = this._carousel = {
- // shortcuts
- next: self.$('thumb-nav-right'),
- prev: self.$('thumb-nav-left'),
- // cache the width
- width: 0,
- // track the current position
- current: 0,
- // cache max value
- max: 0,
- // save all hooks for each width in an array
- hooks: [],
- // update the carousel
- // you can run this method anytime, f.ex on window.resize
- update: function() {
- var w = 0,
- h = 0,
- hooks = [0];
- $.each( self._thumbnails, function( i, thumb ) {
- if ( thumb.ready ) {
- w += thumb.outerWidth || $( thumb.container ).outerWidth( true );
- hooks[ i+1 ] = w;
- h = Math.max( h, thumb.outerHeight || $( thumb.container).outerHeight( true ) );
- }
- });
- self.$( 'thumbnails' ).css({
- width: w,
- height: h
- });
- carousel.max = w;
- carousel.hooks = hooks;
- carousel.width = self.$( 'thumbnails-list' ).width();
- carousel.setClasses();
- self.$( 'thumbnails-container' ).toggleClass( 'galleria-carousel', w > carousel.width );
- // one extra calculation
- carousel.width = self.$( 'thumbnails-list' ).width();
- // todo: fix so the carousel moves to the left
- },
- bindControls: function() {
- var i;
- carousel.next.bind( 'click', function(e) {
- e.preventDefault();
- if ( self._options.carouselSteps === 'auto' ) {
- for ( i = carousel.current; i < carousel.hooks.length; i++ ) {
- if ( carousel.hooks[i] - carousel.hooks[ carousel.current ] > carousel.width ) {
- carousel.set(i - 2);
- break;
- }
- }
- } else {
- carousel.set( carousel.current + self._options.carouselSteps);
- }
- });
- carousel.prev.bind( 'click', function(e) {
- e.preventDefault();
- if ( self._options.carouselSteps === 'auto' ) {
- for ( i = carousel.current; i >= 0; i-- ) {
- if ( carousel.hooks[ carousel.current ] - carousel.hooks[i] > carousel.width ) {
- carousel.set( i + 2 );
- break;
- } else if ( i === 0 ) {
- carousel.set( 0 );
- break;
- }
- }
- } else {
- carousel.set( carousel.current - self._options.carouselSteps );
- }
- });
- },
- // calculate and set positions
- set: function( i ) {
- i = Math.max( i, 0 );
- while ( carousel.hooks[i - 1] + carousel.width >= carousel.max && i >= 0 ) {
- i--;
- }
- carousel.current = i;
- carousel.animate();
- },
- // get the last position
- getLast: function(i) {
- return ( i || carousel.current ) - 1;
- },
- // follow the active image
- follow: function(i) {
- //don't follow if position fits
- if ( i === 0 || i === carousel.hooks.length - 2 ) {
- carousel.set( i );
- return;
- }
- // calculate last position
- var last = carousel.current;
- while( carousel.hooks[last] - carousel.hooks[ carousel.current ] <
- carousel.width && last <= carousel.hooks.length ) {
- last ++;
- }
- // set position
- if ( i - 1 < carousel.current ) {
- carousel.set( i - 1 );
- } else if ( i + 2 > last) {
- carousel.set( i - last + carousel.current + 2 );
- }
- },
- // helper for setting disabled classes
- setClasses: function() {
- carousel.prev.toggleClass( 'disabled', !carousel.current );
- carousel.next.toggleClass( 'disabled', carousel.hooks[ carousel.current ] + carousel.width >= carousel.max );
- },
- // the animation method
- animate: function(to) {
- carousel.setClasses();
- var num = carousel.hooks[ carousel.current ] * -1;
- if ( isNaN( num ) ) {
- return;
- }
- Utils.animate(self.get( 'thumbnails' ), {
- left: num
- },{
- duration: self._options.carouselSpeed,
- easing: self._options.easing,
- queue: false
- });
- }
- };
- // tooltip control
- // added in 1.2
- var tooltip = this._tooltip = {
- initialized : false,
- open: false,
- init: function() {
- tooltip.initialized = true;
- var css = '.galleria-tooltip{padding:3px 8px;max-width:50%;background:#ffe;color:#000;z-index:3;position:absolute;font-size:11px;line-height:1.3' +
- 'opacity:0;box-shadow:0 0 2px rgba(0,0,0,.4);-moz-box-shadow:0 0 2px rgba(0,0,0,.4);-webkit-box-shadow:0 0 2px rgba(0,0,0,.4);}';
- Utils.insertStyleTag(css);
- self.$( 'tooltip' ).css('opacity', 0.8);
- Utils.hide( self.get('tooltip') );
- },
- // move handler
- move: function( e ) {
- var mouseX = self.getMousePosition(e).x,
- mouseY = self.getMousePosition(e).y,
- $elem = self.$( 'tooltip' ),
- x = mouseX,
- y = mouseY,
- height = $elem.outerHeight( true ) + 1,
- width = $elem.outerWidth( true ),
- limitY = height + 15;
- var maxX = self.$( 'container').width() - width - 2,
- maxY = self.$( 'container').height() - height - 2;
- if ( !isNaN(x) && !isNaN(y) ) {
- x += 10;
- y -= 30;
- x = Math.max( 0, Math.min( maxX, x ) );
- y = Math.max( 0, Math.min( maxY, y ) );
- if( mouseY < limitY ) {
- y = limitY;
- }
- $elem.css({ left: x, top: y });
- }
- },
- // bind elements to the tooltip
- // you can bind multiple elementIDs using { elemID : function } or { elemID : string }
- // you can also bind single DOM elements using bind(elem, string)
- bind: function( elem, value ) {
-
- // todo: revise if alternative tooltip is needed for mobile devices
- if (Galleria.TOUCH) {
- return;
- }
- if (! tooltip.initialized ) {
- tooltip.init();
- }
- var hover = function( elem, value) {
- tooltip.define( elem, value );
- $( elem ).hover(function() {
- Utils.clearTimer('switch_tooltip');
- self.$('container').unbind( 'mousemove', tooltip.move ).bind( 'mousemove', tooltip.move ).trigger( 'mousemove' );
- tooltip.show( elem );
- Galleria.utils.addTimer( 'tooltip', function() {
- self.$( 'tooltip' ).stop().show().animate({
- opacity:1
- });
- tooltip.open = true;
- }, tooltip.open ? 0 : 500);
- }, function() {
- self.$( 'container' ).unbind( 'mousemove', tooltip.move );
- Utils.clearTimer( 'tooltip' );
- self.$( 'tooltip' ).stop().animate({
- opacity: 0
- }, 200, function() {
- self.$( 'tooltip' ).hide();
- Utils.addTimer('switch_tooltip', function() {
- tooltip.open = false;
- }, 1000);
- });
- });
- };
- if ( typeof value === 'string' ) {
- hover( ( elem in self._dom ? self.get( elem ) : elem ), value );
- } else {
- // asume elemID here
- $.each( elem, function( elemID, val ) {
- hover( self.get(elemID), val );
- });
- }
- },
- show: function( elem ) {
- elem = $( elem in self._dom ? self.get(elem) : elem );
- var text = elem.data( 'tt' ),
- mouseup = function( e ) {
- // attach a tiny settimeout to make sure the new tooltip is filled
- window.setTimeout( (function( ev ) {
- return function() {
- tooltip.move( ev );
- };
- }( e )), 10);
- elem.unbind( 'mouseup', mouseup );
- };
- text = typeof text === 'function' ? text() : text;
- if ( ! text ) {
- return;
- }
- self.$( 'tooltip' ).html( text.replace(/\s/, ' ') );
- // trigger mousemove on mouseup in case of click
- elem.bind( 'mouseup', mouseup );
- },
- define: function( elem, value ) {
- // we store functions, not strings
- if (typeof value !== 'function') {
- var s = value;
- value = function() {
- return s;
- };
- }
- elem = $( elem in self._dom ? self.get(elem) : elem ).data('tt', value);
- tooltip.show( elem );
- }
- };
- // internal fullscreen control
- // added in 1.195
- // still kind of experimental
- var fullscreen = this._fullscreen = {
- scrolled: 0,
- active: false,
- keymap: self._keyboard.map,
- enter: function(callback) {
- fullscreen.active = true;
- // hide the image until rescale is complete
- Utils.hide( self.getActiveImage() );
- self.$( 'container' ).addClass( 'fullscreen' );
- fullscreen.scrolled = $win.scrollTop();
- // begin styleforce
- Utils.forceStyles(self.get('container'), {
- position: 'fixed',
- top: 0,
- left: 0,
- width: '100%',
- height: '100%',
- zIndex: 10000
- });
- var htmlbody = {
- height: '100%',
- overflow: 'hidden',
- margin:0,
- padding:0
- },
- data = self.getData();
- Utils.forceStyles( DOM().html, htmlbody );
- Utils.forceStyles( DOM().body, htmlbody );
- // temporarily attach some keys
- // save the old ones first in a cloned object
- fullscreen.keymap = $.extend({}, self._keyboard.map);
- self.attachKeyboard({
- escape: self.exitFullscreen,
- right: self.next,
- left: self.prev
- });
- // swap to big image if it’s different from the display image
- if ( data && data.big && data.image !== data.big ) {
- var big = new Galleria.Picture(),
- cached = big.isCached( data.big ),
- index = self.getIndex(),
- thumb = self._thumbnails[ index ];
- self.trigger( {
- type: Galleria.LOADSTART,
- cached: cached,
- index: index,
- imageTarget: self.getActiveImage(),
- thumbTarget: thumb
- });
- big.load( data.big, function( big ) {
- self._scaleImage( big, {
- complete: function( big ) {
- self.trigger({
- type: Galleria.LOADFINISH,
- cached: cached,
- index: index,
- imageTarget: big.image,
- thumbTarget: thumb
- });
- var image = self._controls.getActive().image;
- if ( image ) {
- $( image ).width( big.image.width ).height( big.image.height )
- .attr( 'style', $( big.image ).attr('style') )
- .attr( 'src', big.image.src );
- }
- }
- });
- });
- }
- // init the first rescale and attach callbacks
- self.rescale(function() {
- Utils.addTimer('fullscreen_enter', function() {
- // show the image after 50 ms
- Utils.show( self.getActiveImage() );
- if (typeof callback === 'function') {
- callback.call( self );
- }
- }, 100);
- self.trigger( Galleria.FULLSCREEN_ENTER );
- });
- // bind the scaling to the resize event
- $win.resize( function() {
- fullscreen.scale();
- } );
- },
- scale : function() {
- self.rescale();
- },
- exit: function(callback) {
- fullscreen.active = false;
- Utils.hide( self.getActiveImage() );
- self.$('container').removeClass( 'fullscreen' );
- // revert all styles
- Utils.revertStyles( self.get('container'), DOM().html, DOM().body );
- // scroll back
- window.scrollTo(0, fullscreen.scrolled);
- // detach all keyboard events and apply the old keymap
- self.detachKeyboard();
- self.attachKeyboard( fullscreen.keymap );
- self.rescale(function() {
- Utils.addTimer('fullscreen_exit', function() {
- // show the image after 50 ms
- Utils.show( self.getActiveImage() );
- if ( typeof callback === 'function' ) {
- callback.call( self );
- }
- }, 50);
- self.trigger( Galleria.FULLSCREEN_EXIT );
- });
- $win.unbind('resize', fullscreen.scale);
- }
- };
- // the internal idle object for controlling idle states
- var idle = this._idle = {
- trunk: [],
- bound: false,
- add: function(elem, to) {
- if (!elem) {
- return;
- }
- if (!idle.bound) {
- idle.addEvent();
- }
- elem = $(elem);
- var from = {},
- style;
- for ( style in to ) {
- if ( to.hasOwnProperty( style ) ) {
- from[ style ] = elem.css( style );
- }
- }
- elem.data('idle', {
- from: from,
- to: to,
- complete: true,
- busy: false
- });
- idle.addTimer();
- idle.trunk.push(elem);
- },
- remove: function(elem) {
- elem = jQuery(elem);
- $.each(idle.trunk, function(i, el) {
- if ( el.length && !el.not(elem).length ) {
- self._idle.show(elem);
- self._idle.trunk.splice(i, 1);
- }
- });
- if (!idle.trunk.length) {
- idle.removeEvent();
- Utils.clearTimer('idle');
- }
- },
- addEvent : function() {
- idle.bound = true;
- self.$('container').bind('mousemove click', idle.showAll );
- },
- removeEvent : function() {
- idle.bound = false;
- self.$('container').unbind('mousemove click', idle.showAll );
- },
- addTimer : function() {
- Utils.addTimer('idle', function() {
- self._idle.hide();
- }, self._options.idleTime );
- },
- hide : function() {
-
- if ( !self._options.idleMode ) {
- return;
- }
-
- self.trigger( Galleria.IDLE_ENTER );
- $.each( idle.trunk, function(i, elem) {
- var data = elem.data('idle');
- if (! data) {
- return;
- }
- elem.data('idle').complete = false;
-
- Utils.animate( elem, data.to, {
- duration: self._options.idleSpeed
- });
- });
- },
- showAll : function() {
- Utils.clearTim…
Large files files are truncated, but you can click here to view the full file