Pimping Fancybox jQuery Lightbox

wp-carousel-20

I love fancybox. It’s a great and flexible jQuery lightbox, but I decided there were a couple of things I needed it to do that it doesn’t, so I dived into the code head first and added a couple of features. Be warned that you need to edit the file jquery.fancybox-1.3.1.js to implement them.

Combined add and fire / show / open
Yes I know you can do this with $.fancybox(content, options)

It’s tough to add the fancybox listener and fire it at the same time, for example onclick or using a live event. That annoyed me in some circumstances. Previously I have resorted to adding fancybox to anchors on hover so it could fire onclick:

$('a.fancybox').mouseover(function()
{
    $(this).fancybox();
});

But that’s not cool. So I added the option to the core.

 
// replace
	$.fn.fancybox = function(options){
		$(this)
 
// with
	$.fn.fancybox = function(options)
	{
		if(options === 1)
		{
			options = {now:true};
		}
 
		$(this)

and

 
// replace
		});
 
		return this;
	};
 
	$.fancybox = function(obj) {
 
// with
 
		});
 
		if(options.now)
		{
			$(this).click();
		}
 
		return this;
	};
 
	$.fancybox = function(obj) {

You can fire it in two ways. If you are also including options then fire it on add by including now:true as an option like:

 
$(this).fancybox({
 
    now:true,
    showCloseButton : false,
    enableEscapeButton : false
 
});

or if you are not setting options then fire it on add like:

 
// note the (1)
$(this).fancybox(1);

Either way, fancybox should now open / fire / show as soon as you attach it to an element.

And for my next trick….

Stop lightbox vertical movement

The default behavour is for fancybox to centre itself on vertical or horizontal scroll or window resize. I needed (see the final tweak) the box to stay still vertically even if I scrolled, but stay centre horizontally.

To implement this I made this change:

 
// replace
 
		to.top	= view[3] + ((view[1] - ((wrap.height() - titleh) + (shadow * 2 ))) * 0.5);
		to.left	= view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5);
 
		to.top	= Math.max(view[3] + margin, to.top);
		to.left	= Math.max(view[2] + margin, to.left);
 
// with
 
                if(currentOpts.centerTopOnScroll)
                {
		    to.top	= view[3] + ((view[1] - ((wrap.height() - titleh) + (shadow * 2 ))) * 0.5);
		    to.top	= Math.max(view[3] + margin, to.top);
                }
 
		to.left	= view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5);
		to.left	= Math.max(view[2] + margin, to.left);

and then add that new option to the defaults:

 
// replace
 
		centerOnScroll		:	false,
 
// with
 
		centerOnScroll		:	false,
		centerTopOnScroll	:	true,

You can then include the new option centerTopOnScroll:false to keep the top position static even on horizontal scroll.

The final change I have made is:

Clone the position and dimensions of an element

This tweak allows you to specify an element to clone. The original lightbox created will then be in the position and have the dimensions of the specified element. I bolded original because you can then alter the dimensions and positions yourself using jquery or by updating the content.

To implement this:

 
// replace
 
			final_pos = fancybox_get_zoom_to();
 
			fancybox_process_title();
 
// with
 
			if(currentOpts.clonePosition)
			{
				// get final_pos from the element we are cloning
				var pos = currentOpts.elementToClone.offset();
 
				final_pos = {
								height:currentOpts.elementToClone.outerHeight(),
								width:currentOpts.elementToClone.outerWidth(),
								left:pos.left,
								top:pos.top
							};
			}
			else
			{
				final_pos = fancybox_get_zoom_to();
			}
 
			fancybox_process_title();

and

 
// replace (after the previous change for vertical scroll)
 
to.left	= view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5);
to.left	= Math.max(view[2] + margin, to.left);
 
// with
 
if(currentOpts.clonePosition)
{
	to.left = currentOpts.elementToClone.offset().left
}
else
{
	to.left	= view[2] + ((view[0] - (wrap.width() + (shadow * 2 ))) * 0.5);
}
 
to.left	= Math.max(view[2] + margin, to.left);

You then have the choice of including new options:

 
clonePosition:true
elementToClone:$('#element') // a jquery element

So there you have it.

Combined add and fire / show / open
Stop lightbox vertical movement
Clone the position and dimensions of an element

One comment.

  1. Dear Harry

    I am not very good at coding, but tell me if I am mistaken if I think that with a slight modification of your “clone position” tweak you can give Fancybox position capabilities?

    Such as Open to position absolute, top “X”, left “y”

    How would you modify the code to do such thing?