topical media & game development

talk show tell print

lib-jquery-plugin-captify-captify.js / js



  /* jQuery Captify Plugin
  * 
  * Copyright (C) 2008 Brian Reavis
  * Licenced under the MIT license
  *
  * Date: 2008-2-27 [Fri, 27 Feb 2009] 
  */
  jQuery.fn.extend({
          captify: function(o) {
                  var o = .extend({
                          speedOver: 'fast',                                // speed of the mouseover effect
                          speedOut: 'normal',                                // speed of the mouseout effect
                          hideDelay: 500,                                        // how long to delay the hiding of the caption after mouseout (ms)
                          animation: 'slide',                                // 'fade', 'slide', 'always-on'
                          prefix: '',                                                // text/html to be placed at the beginning of every caption
                          opacity: '0.35',                                // opacity of the caption on mouse over
                          className: 'caption-bottom',        // the name of the CSS class to apply to the caption box         
                          position: 'bottom',                                // position of the caption (top or bottom)         
                          spanWidth: '100%'                                // caption span % of the image
                  }, o);
                  this.each(function() {
                          var img = this;
                          this.load(function() {
                                  this = img;
                                  if (this.hasInit) {
                                          return false;
                                  }
                                  this.hasInit = true;
                                  var over_caption = false;
                                  var over_img = false;
  
                                  //pull the label from another element if there is a 
                                  //valid element id inside the rel="..." attribute, otherwise,
                                  //just use the text in the alt="..." attribute.
                                  var captionLabelSrc = $('#' + this.attr('rel'));
                                  var captionLabelHTML = !captionLabelSrc.length ? this.attr('alt') : captionLabelSrc.html();
                                  captionLabelSrc.remove();
                                  var toWrap = this.parent && this.parent.tagName == 'a' ? this.parent : this;
                                  var wrapper = toWrap.wrap('<div></div>').parent();
                                  wrapper.css({
                                          overflow: 'hidden',
                                          padding: 0,
                                          fontSize: 0.1
                                  })
                                  wrapper.addClass('caption-wrapper');
                                  wrapper.width(this.width());
                                  wrapper.height(this.height());
  
                                  //transfer the margin and border properties from the image to the wrapper
                                  .map(['top', 'right', 'bottom', 'left'], function(i) {
                                          wrapper.css('margin-' + i, img.css('margin-' + i));
                                          .map(['style', 'width', 'color'], function(j) {
                                                  var key = 'border-' + i + '-' + j;
                                                  wrapper.css(key, img.css(key));
                                          });
                                  });
                                  img.css({ border: '0 none' });
  
                                  //create two consecutive divs, one for the semi-transparent background,
                                  //and other other for the fully-opaque label
                                  var caption = $('div:last', wrapper.append('<div></div>')).addClass(o.className);
                                  var captionContent = $('div:last', wrapper.append('<div></div>')).addClass(o.className).append(o.prefix).append(captionLabelHTML);
  
                                  //override hiding from CSS, and reset all margins (which could have been inherited)
                                  $('*', wrapper).css({ margin: 0 }).show();
  
                                  //ensure the background is on bottom
                                  var captionPositioning = jQuery.browser.msie ? 'static' : 'relative';
                                  caption.css({
                                          zIndex: 1,
                                          position: captionPositioning,
                                          opacity: o.animation == 'fade' ? 0 : o.opacity,
                                          width: o.spanWidth
                                  });
  
                                  if (o.position == 'bottom'){
                                          var vLabelOffset = parseInt(caption.css('border-top-width').replace('px', '')) + parseInt(captionContent.css('padding-top').replace('px', '')) - 1;
                                          captionContent.css('paddingTop', vLabelOffset);
                                  }
                                  //clear the backgrounds/borders from the label, and make it fully-opaque
                                  captionContent.css({
                                          position: captionPositioning,
                                          zIndex: 2,
                                          background: 'none',
                                          border: '0 none',
                                          opacity: o.animation == 'fade' ? 0 : 1,
                                          width: o.spanWidth
                                  });
                                  caption.width(captionContent.outerWidth());
                                  caption.height(captionContent.height());
  
                                  // represents caption margin positioning for hide and show states
                                  var topBorderAdj = (o.position == 'bottom' && jQuery.browser.msie) ? -4 : 0;
                                  var captionPosition = (o.position == 'top')
                                     ? { hide: -img.height() - caption.outerHeight() - 1, show: -img.height() }
                                     : { hide: 0, show: -caption.outerHeight() + topBorderAdj };
                                  
                                  //pull the label up on top of the background
                                  captionContent.css('marginTop', -caption.outerHeight());
                                  caption.css('marginTop', captionPosition[o.animation == 'fade' || o.animation == 'always-on' ? 'show' : 'hide']);
                                  
                                  //function to push the caption out of view
                                  var cHide = function() {
                                          if (!over_caption && !over_img){
                                                  var props = o.animation == 'fade'
                                                          ? { opacity: 0 }
                                                          : { marginTop: captionPosition.hide };
                                                  caption.animate(props, o.speedOut);
                                                  if (o.animation == 'fade'){
                                                          captionContent.animate({opacity: 0}, o.speedOver);
                                                  }
                                          }
                                  };
  
                                  if (o.animation != 'always-on'){
                                          //when the mouse is over the image
                                          this.hover(
                                                  function() {
                                                          over_img = true;
                                                          if (!over_caption) {
                                                                  var props = o.animation == 'fade'
                                                                          ? { opacity: o.opacity }
                                                                          : { marginTop: captionPosition.show };
                                                                  caption.animate(props, o.speedOver);
                                                                  if (o.animation == 'fade'){
                                                                          captionContent.animate({opacity: 1}, o.speedOver/2);
                                                                  }
                                                          }
                                                  },
                                                  function() {
                                                          over_img = false;
                                                          window.setTimeout(cHide, o.hideDelay);
                                                  }
                                          );
                                          //when the mouse is over the caption on top of the image (the caption is a sibling of the image)
                                          $('div', wrapper).hover(
                                                  function() { over_caption = true; },
                                                  function() { over_caption = false; window.setTimeout(cHide, o.hideDelay); }
                                          );
                                  }
                          });
                          //if the image has already loaded (due to being cached), force the load function to be called
                          if (this.complete || this.naturalWidth > 0) {
                                  img.trigger('load');
                          }
                  });
          }
  });


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.