viernes, 4 de febrero de 2011

Hide initial image in galleria

I found a problem upgrading from old galleria 1.0 to 1.2. I'm working on a site with several galleries. With the old galleria 1.0 no image was shown until the user clicked on a thumbnail. So, the designer put a background image in every gallery layer, that should only be visible when galleria is loaded and before any image is shown. Like a wellcome-to-this-gallery image. However, the brand new (wonderfull) galleria 1.2 allways shows the first image right after loading, and I couldn't find any option to change this and make the background visible until the user clicks.

As I'm doing a kind of workshop in web programming, I spent a lot of time trying to find a solution. And I found up to three different solutions (or workarounds) to this.

Before going on, there's something I want to clarify: I didn't want to mess with galleria's code. No hard-coding. So, everything should be done from inside the 'extend' option or the theme.

1. First approach: making the visible image invisible. The idea is to simply set, at first, the showing images' 'opacity' to 0. But there are two problems:
- First, it must be done after the image is shown, or galleria will show the image anyway.
- Second, galleria "thinks" it's already showing the first image. So, as the clicknext option is activated, if the user clicks in the stage, the second image will be shown. And if the user clicks in the first thumbnail, nothing will happen. To fix this, we cheat galleria setting the active image to -1.


$(document).ready(function(){
$('#main_image').galleria({
clicknext: true,
show_info: false,
show_counter: false,
show_imagenav: false,
thumb_crop: true,
thumb_fit: false,
thumb_quality: false,
transition: "flash",
transition_initial: "none",
extend: function() {
// First, we set the container's 'background-color' to 'transparent',
// to see what's behind.
var colorFondo = this.$('container').css('background-color');
this.$('container').css('background-color', "transparent");
// Then, we hide the image. It's enough to set the opacity of
// the stage images to 0, galleria will later show them correctly.
// But remember: this must be done *after* the first image is shown.
this.bind(Galleria.IMAGE, this.proxy(function(e) {
$('.galleria-images .galleria-image').css('opacity', "0");
// Fixing the active image problem.
this.setIndex(-1);
// Finally, we put back the container's 'background-color'
//when another image is to be shown.
this.bind(Galleria.LOADSTART, this.proxy(function(e) {
this.$('container').css('background-color', colorFondo);
this.unbind(e);
}));
this.unbind(e);
}));
}
});
});



2. Second approach: hiding the whole stage. Problems:
- Galleria doesn't care about stage visibility. So we must make it visible again when the user clicks on any thumbnail.
- The clicknext option will not work until the stage is visible again.


$(document).ready(function(){
$('#main_image').galleria({
clicknext: true,
show_info: false,
show_counter: false,
show_imagenav: false,
thumb_crop: true,
thumb_quality: false,
transition: "flash",
extend: function() {
var colorFondo = this.$('container').css('background-color'),
transicion = this.getOptions('transition');
// Hiding the stage.
this.$('stage').hide();
// We also remove the transition, to avoid any ugly flash effect
// when showing again the stage.
this.setOptions('transition', "none");
this.$('container')
// We set container's 'background-color' to 'transparent',
// to see what's behind.
.css('background-color', "transparent")
// Then, when the user clicks on any thumbnail...
.find('.galleria-thumbnails .galleria-image')
.one('click', this.proxy(function() {
// ...we set back container's 'background-color',...
this.$('container').css('background-color', colorFondo);
// ...hide 'loader' (otherwise it will stay bothering),...
this.$('loader').hide();
// ...show back the stage (with a litte delay,
// to avoid the previous image flashing),..
this.$('stage')
.delay(this.getOptions('transition_speed') / 2)
.fadeIn(this.proxy(function() {
// ...and, when 'stage' has shown,
// set back the original transition.
this.setOptions('transition', transicion);
}));
}));
}
});
});



3. Third approach: put the background image as the first one in galleria, and then remove it from the gallery. I don't like this solution, because it's a little bit tricky. Problems:
- There's no method in galleria's API to remove an image from a loaded gallery! We have to build it!
- When removing an image, the indexes of the remaining images will probably stay incorrect. We have to fix them.


$(document).ready(function(){
$('#main_image').galleria({
clicknext: true,
show_info: false,
show_counter: false,
show_imagenav: false,
thumb_crop: true,
thumb_fit: false,
thumb_quality: false,
transition: "flash",
transition_initial: "none",
extend: function() {
// Once our "wellcome image" is shown...
this.bind(Galleria.IMAGE, function(e) {
// ...we remove it from the gallery.
this.removeImage(0);
// The active image index will be wrong if we've removed
// the active image or one with a lower index. We have to fix it.
// Beware!: setting a NaN or out of range index can cause troubles.
// If we've removed the active image, we set -1 as the active
// (this will load any thumbnail the user clicks on,
// or the first image if clicks on the stage)
// If we've removed one below the active one,
// we have to subtract 1 from the index.
// In our case...
this.setIndex(-1);
// Finally, we update the carousel.
this.updateCarousel();
this.unbind(e);
});
}
}).animate({'opacity': 1}, 1000);
});

// Method for removing an image from an existing gallery.
// It's passed de index of the image to remove.
Galleria.prototype.removeImage = function(index) {
// Getting sure the index is correct before going on.
index = parseInt(index);
if(isNaN(index)) return this;
index = Math.min(this.getDataLength() - 1 , Math.max(index, 0));
// We have to remove 3 things: the element inside '_data' array,
// the element inside '_thumbnails' array and the element from the DOM
this._data.splice(index, 1);
$(this._thumbnails[index].container).remove();
this._thumbnails.splice(index, 1);
// Finally, we fix up the indexes:
// '_thumbnails[].id' and data inside thumbnails containers.
for(var i = index; i < this._thumbnails.length; i++) {
$(this._thumbnails[i].container).data('index', i);
this._thumbnails[i].id = i;
}
return this;
};


I don't like this last option, but I think many people can be interested in the 'removeImage' function. I'm not even sure the function is all correct. Possibly there're missing tasks, but it works for now.

No hay comentarios:

Publicar un comentario