Guest User

photogallery.js

a guest
May 3rd, 2011
531
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. // Gallery
  3. //
  4. (function ($) {
  5.     $.fn.mediagallery = function (opts) {
  6.         return this.each(function () {
  7.             var $this = $(this);
  8.  
  9.             // Merge options
  10.             var options = $.extend(true, {}, $.fn.mediagallery.defaults, opts);
  11.  
  12.             //jQuery.fx.interval = options.animationInterval;
  13.  
  14.             // Data
  15.             var data = options.data;
  16.  
  17.             // Current
  18.             var current = options.current;
  19.  
  20.             // Width
  21.             var itemWidth = 0;
  22.  
  23.             // In touch move
  24.             var inTouchMove = false;
  25.  
  26.             var isWebkitTransform = (function () {
  27.                 //if ($('body').hasClass('android')) return false; // geen webkit voor android atm
  28.  
  29.                 var div = document.createElement('div');
  30.                 div.innerHTML = '<div style="-webkit-transition:color 1s linear;"></div>';
  31.                 var cssTransitionsSupported = (div.firstChild.style.webkitTransition !== undefined);
  32.                 delete div;
  33.                 return cssTransitionsSupported;
  34.             })();
  35.  
  36.             // Navigation
  37.  
  38.             var navContainer = $this.find(options.selectors.nav.self);
  39.             var nav = {
  40.                 self: navContainer,
  41.                 prev: navContainer.find(options.selectors.nav.prev),
  42.                 next: navContainer.find(options.selectors.nav.next),
  43.                 pgnr: navContainer.find(options.selectors.nav.pgnr)
  44.             };
  45.  
  46.             // Media
  47.             var mediaContainer = $this.find(options.selectors.media.self);
  48.             var media = {
  49.                 self: mediaContainer,
  50.                 item: mediaContainer.find(options.selectors.media.item),
  51.                 prev: mediaContainer.find(options.selectors.media.prev),
  52.                 next: mediaContainer.find(options.selectors.media.next)
  53.             };
  54.  
  55.             // Carousel
  56.             var carouselContainer = $this.find(options.selectors.carousel.self);
  57.             var carousel = {
  58.                 self: carouselContainer,
  59.                 items: carouselContainer.find(options.selectors.carousel.item)
  60.             };
  61.  
  62.             // Scroller
  63.             var scroller = {
  64.                 container: $this.find('#prop-media-scroller-holder'),
  65.                 self: $this.find('#prop-media-scroller')
  66.             };
  67.  
  68.             //
  69.             // Previous item
  70.             //
  71.             var previous = function (smooth) {
  72.                 if (current > 0) {
  73.                     select(current - 1, smooth);
  74.                 }
  75.                 return false;
  76.             };
  77.  
  78.             //
  79.             // Next item
  80.             //
  81.             var next = function (smooth) {
  82.                 if (current < data.length - 1) {
  83.                     select(current + 1, smooth);
  84.                 }
  85.                 return false;
  86.             };
  87.  
  88.             //
  89.             // Select item
  90.             //
  91.             var select = function (idx, smooth) {
  92.                 // Deselect previously selected item
  93.                 carousel.items.eq(current).removeClass(options.classNames.selected);
  94.  
  95.                 // last item was?
  96.                 var previousIdx = current;
  97.  
  98.                 // Store index of selected item
  99.                 current = idx;
  100.  
  101.                 // Select item
  102.                 carousel.items.eq(current).addClass(options.classNames.selected);
  103.  
  104.                 // Display item in gallery
  105.                 refresh(smooth, previousIdx);
  106.  
  107.                 return false;
  108.             };
  109.  
  110.             //
  111.             // Refresh gallery
  112.             //
  113.             var refresh = function (smooth, previousIdx) {
  114.                 if (smooth && previousIdx !== current) {
  115.                     repositionContainer(current * itemWidth, options.animationSpeed, function () {
  116.                         inTouchMove = false;
  117.                         setImages();
  118.                     });
  119.                 } else {
  120.                     setImages(true); // set correct images and force reposition
  121.                 }
  122.                 refreshUi();
  123.             };
  124.  
  125.             var refreshUi = function () {
  126.                 // Navigation: previous
  127.                 if (current > 0) {
  128.                     nav.prev.removeClass(options.classNames.disabled);
  129.                 } else {
  130.                     nav.prev.addClass(options.classNames.disabled);
  131.                 }
  132.  
  133.                 // Navigation: next
  134.                 if (current < data.length - 1) {
  135.                     nav.next.removeClass(options.classNames.disabled);
  136.                 } else {
  137.                     nav.next.addClass(options.classNames.disabled);
  138.                 }
  139.  
  140.                 // Navigation: current item number
  141.                 nav.pgnr.html(current + 1);
  142.  
  143.                 // toggle media prev/next buttons
  144.                 media.prev.toggle(!nav.prev.hasClass(options.classNames.disabled));
  145.                 media.next.toggle(!nav.next.hasClass(options.classNames.disabled));
  146.             };
  147.  
  148.             //
  149.             // Scroll element into view
  150.             //
  151.             var scrollIntoView = function (obj, offset) {
  152.                 $.smoothScroll({ scrollTop: (obj.offset().top + (offset || 0)) });
  153.             };
  154.  
  155.             //
  156.             // Reserve space for item
  157.             //
  158.             var reserveSpace = function () {
  159.                 // Use expected dimensions ratio for guidance
  160.                 var ratio = options.dimensions.height / options.dimensions.width;
  161.  
  162.                 // Use CSS values for min. and max. dimensions
  163.                 var minHeight = parseInt(media.item.css('min-width'), 10) * ratio;
  164.                 var maxHeight = parseInt(media.item.css('max-width'), 10) * ratio;
  165.  
  166.                 // Calculate expected height based on current width
  167.                 var height = media.self.width() * ratio;
  168.  
  169.                 if (height < minHeight) height = minHeight;
  170.                 if (height > maxHeight) height = maxHeight;
  171.  
  172.                 media.self.height(height);
  173.             };
  174.  
  175.             //
  176.             // Get absolute URL
  177.             //
  178.             var getAbsoluteUrl = function (url) {
  179.                 return options.baseUrl + url;
  180.             };
  181.  
  182.             //
  183.             // Apply handlers
  184.             //
  185.  
  186.             // Navigation: previous / next
  187.             nav.prev.add(nav.next).bind('click', function () {
  188.                 // Determine previous or next
  189.                 if (this === nav.prev.get(0)) {
  190.                     previous();
  191.                 } else if (this === nav.next.get(0)) {
  192.                     next();
  193.                 }
  194.  
  195.                 return false;
  196.             });
  197.  
  198.             // Media navigation: previous / next
  199.             var currentAtMousedown;
  200.             media.prev.add(media.next).bind('click', function () {
  201.                 if (inTouchMove || currentAtMousedown !== current) return false;
  202.  
  203.                 // Determine previous or next
  204.                 if (this === media.prev.get(0)) {
  205.                     select(current - 1, false);
  206.                 } else if (this === media.next.get(0)) {
  207.                     select(current + 1, false);
  208.                 }
  209.  
  210.                 return false;
  211.             }).mousedown(function () {
  212.                 currentAtMousedown = current;
  213.             });
  214.  
  215.             // Carousel select
  216.             carousel.items.bind('click', function () {
  217.                 // Select item
  218.                 select(carousel.items.index(this));
  219.  
  220.                 // Scroll media into view
  221.                 scrollIntoView(media.self);
  222.  
  223.                 return false;
  224.             });
  225.  
  226.             // Swipe events
  227.             $(document).ready(function () {
  228.                 var prevSwipe = 0;
  229.                 var prevDx = 0;
  230.  
  231.                 var $this = scroller.self;
  232.  
  233.                 $(media.self).wipe({
  234.                     events: {
  235.                         wipeStart: function () {
  236.                             if (inTouchMove) {
  237.                                 // zijn we nog in de touch move? dan stop anim
  238.                                 if (isWebkitTransform) {
  239.                                     $this.css({
  240.                                         '-webkit-transition-duration': '0ms'
  241.                                     });
  242.                                 } else {
  243.                                     $this.stop(true, true);
  244.                                 }
  245.                             }
  246.  
  247.                             setImages();
  248.                         },
  249.                         wipe: function (dx, dy) {
  250.                             inTouchMove = true;
  251.  
  252.                             var curDt = new Date().getTime();
  253.  
  254.                             // we updaten max elke 15 ms.
  255.                             // $(this).css({ left: dx });
  256.  
  257.                             // aan de zijkanten mag je niet zover meer door
  258.                             var baseLine = current * itemWidth;
  259.  
  260.                             if ((current === 0 && dx > 0) || (current === data.length - 1 && dx < 0)) {
  261.                                 dx = 0.4 * dx;
  262.                             }
  263.  
  264.                             repositionContainer(baseLine - dx, 0);
  265.  
  266.                             prevSwipe = curDt;
  267.                         },
  268.                         wipeEnd: function (dx, dy) {
  269.                             if (dx < 0 && (Math.abs(dx) > itemWidth * 0.2) && data[current + 1]) {
  270.                                 // animeer naar volgende afbeelding
  271.                                 next(true);
  272.                             } else if (dx > 0 && (Math.abs(dx) > itemWidth * 0.2) && data[current - 1]) {
  273.                                 // animeer naar vorige afbeelding
  274.                                 previous(true);
  275.                             } else {
  276.                                 var baseLine = current * itemWidth;
  277.  
  278.                                 repositionContainer(baseLine, options.animationSpeed);
  279.                                 setTimeout(function () { inTouchMove = false; }, options.animationSpeed);
  280.                             }
  281.                         }
  282.                     },
  283.                     minTimeBetweenSwipeEvents: 0
  284.                 });
  285.             });
  286.  
  287.             // Set correct swipe images
  288.             var setImages = function (forceReposition) {
  289.                 if (forceReposition) {
  290.                     repositionContainer(current * itemWidth, 0);
  291.                 }
  292.  
  293.                 // we zetten altijd vorige / current / volgende
  294.                 if (data[current - 1] && !scroller.self.find('img:eq(' + (current - 1) + ')').attr('src')) {
  295.                     scroller.self.find('img:eq(' + (current - 1) + ')').attr('src', data[current - 1]);
  296.                 }
  297.  
  298.                 if (!scroller.self.find('img:eq(' + (current) + ')').attr('src')) {
  299.                     scroller.self.find('img:eq(' + current + ')').attr('src', data[current]);
  300.                 }
  301.  
  302.                 if (data[current + 1] && !scroller.self.find('img:eq(' + (current + 1) + ')').attr('src')) {
  303.                     scroller.self.find('img:eq(' + (current + 1) + ')').attr('src', data[current + 1]);
  304.                 }
  305.             };
  306.  
  307.             // toggle media prev/next buttons
  308.             media.prev.toggle(!nav.prev.hasClass(options.classNames.disabled));
  309.             media.next.toggle(!nav.next.hasClass(options.classNames.disabled));
  310.  
  311.             var repositionContainer = function (x, duration, finishedCallback) {
  312.                 x = (x | 0);
  313.  
  314.                 finishedCallback = finishedCallback || function () { };
  315.  
  316.                 if (!isWebkitTransform) {
  317.                     if (!duration) {
  318.                         scroller.self.css({ left: -x });
  319.                         finishedCallback();
  320.                     } else {
  321.                         scroller.self.animate({ left: -x }, duration, finishedCallback);
  322.                     }
  323.                 } else {
  324.                     // webkit on anim finished
  325.                     var cb = function () {
  326.                         finishedCallback();
  327.                         scroller.self.unbind('webkitTransitionEnd');
  328.                     }
  329.                     scroller.self.bind('webkitTransitionEnd', cb);
  330.  
  331.                     scroller.self.css({
  332.                         '-webkit-transform': 'translate(' + -x + 'px,0px)',
  333.                         '-webkit-transition-duration': (duration || 0) + 'ms',
  334.                         '-webkit-backface-visibility': 'hidden',
  335.                         '-webkit-transition-property': '-webkit-transform'
  336.                     });
  337.                 }
  338.             };
  339.  
  340.             // when loaded, set positioning correct
  341.             var reserveSwipeSpace = function () {
  342.                 if (scroller.self.find('img').length === data.length) { // reposition
  343.                     var height = media.self.height();
  344.  
  345.                     if (height > options.dimensions.height) {
  346.                         height = options.dimensions.height;
  347.                         media.self.height(height);
  348.                     }
  349.  
  350.                     itemWidth = (height * (options.dimensions.width / options.dimensions.height) | 0);
  351.  
  352.                     for (var ix = 0; ix < data.length; ix++) {
  353.                         scroller.self.find('img:eq(' + ix + ')').css({ height: height, width: itemWidth, left: ix * itemWidth });
  354.                     }
  355.  
  356.                     setImages(true);
  357.  
  358.                     scroller.container.css({ left: ($('body').width() / 2) - (itemWidth / 2) });
  359.                     scroller.container.width(itemWidth);
  360.  
  361.                     return;
  362.                 }
  363.  
  364.                 //  eerste keer
  365.                 var temporaryImage = new Image();
  366.                 temporaryImage.onload = function () {
  367.                     var height = media.self.height();
  368.  
  369.                     if (height > options.dimensions.height) {
  370.                         height = options.dimensions.height;
  371.                         media.self.height(height);
  372.                     }
  373.  
  374.                     itemWidth = (height * (options.dimensions.width / options.dimensions.height) | 0);
  375.  
  376.                     for (var ix = 0; ix < data.length; ix++) {
  377.                         var obj = $('<img/>').css({ height: height, width: itemWidth, position: 'absolute', left: ix * itemWidth });
  378.                         scroller.self.append(obj);
  379.                     }
  380.  
  381.                     media.item.remove(); // remove media.self
  382.  
  383.                     setImages(true);
  384.  
  385.                     // container zetten
  386.                     scroller.container.css({ left: ($('body').width() / 2) - (itemWidth / 2) });
  387.                     scroller.container.width(itemWidth);
  388.                 };
  389.                 // fire in the hole!
  390.                 temporaryImage.src = media.item.attr('src');
  391.             };
  392.  
  393.             // Reflow on orientation change or screensize change
  394.             $(window).bind('orientationchange', function () {
  395.                 reserveSpace();
  396.                 reserveSwipeSpace();
  397.             });
  398.             $(window).trigger('orientationchange');
  399.  
  400.             window.onresize = function () {
  401.                 reserveSpace();
  402.                 reserveSwipeSpace();
  403.             };
  404.  
  405.             return this;
  406.         });
  407.     };
  408.  
  409.     // Default options
  410.     $.fn.mediagallery.defaults = {
  411.         // Classnames
  412.         classNames: {
  413.             disabled: 'disabled',
  414.             selected: 'selected'
  415.         },
  416.  
  417.         // Current pic
  418.         current: 0,
  419.  
  420.         // Selectors
  421.         selectors: {
  422.             nav: {
  423.                 self: '.nav-pg',
  424.                 prev: '.nav-pg-prev a.button-pg',
  425.                 next: '.nav-pg-next a.button-pg',
  426.                 pgnr: '.nav-pg-current'
  427.             },
  428.  
  429.             media: {
  430.                 self: '.prop-media-img',
  431.                 item: 'img.current',
  432.                 prev: '.prop-media-prev',
  433.                 next: '.prop-media-next'
  434.             },
  435.  
  436.             carousel: {
  437.                 self: '.prop-media-carousel',
  438.                 item: 'a.thumb-media'
  439.             }
  440.         },
  441.  
  442.         // Media
  443.         data: [
  444.         // Array of strings
  445.         ],
  446.  
  447.         dimensions: {
  448.             width: 600,
  449.             height: 400
  450.         },
  451.  
  452.         animationSpeed: 300,
  453.         animationInterval: 0
  454.     };
  455. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment