sábado, 22 de septiembre de 2012

Elijo ser bonobo

El ser humano es un animal cultural. Lo artificial en nosotras es lo natural. Sin cultura, tecnología y, en definitiva, artificios, jamás habríamos aparecido como especie. Eso nos diferencia y nos aleja terriblemente del resto de los animales; aunque haya algunos delfines y primates que muestren algunas de estas características, es de forma mucho más elemental y sencilla (esto es obvio).

Veo en los últimos años una clara tendencia científica y sociológica a buscar explicaciones biologicistas a nuestros comportamientos. Desde los "jipis" ecologistas (a los que me siento muy cercano, no pretendo ser despectivo) hasta las psicólogas evolucionistas y feminismos varios. Y, aunque me parece una gran acierto, no hay que pasarse.

Antes de ser homo sapiens, nuestros antepasados ya eran especies culturales, tecnológicas y artificiales. Sin esos elementos no habríamos pasado de bonobos ni habríamos podido colonizar otras regiones del planeta (nuestro endeble organismo, sin accesorios tecnológicos, solo está adaptado al clima tropical). Lo artificial es natural en el ser humano. Así pues, a la hora de buscar explicaciones a nuestros comportamientos, tirar de biología y comportamiento animal es (solo) una útil herramienta, no una verdad absoluta, aunque las conclusiones sean acertadas. Hay que tirar también del análisis sociológico y cultural. Si no, nuestros argumentos serán parciales, y nuestra conclusiones, por tanto, erróneas.

No somos ni chimpancés ni bonobos (por desgracia). Somos algo mucho más complejo, interesante y peligroso: somos cultura. Nuestras conductas cambian, evolucionan rápidamente. Como especie, nos adaptamos, aprendemos. Nuestros comportamientos son herederos de una acumulación de experiencias y conocimientos que no se apoyan sobre la lenta evolución de los genes, sino sobre la velozmente cambiante cultura. Vienen de nuestros antepasados, se acumulan en la memoria colectiva; antaño transmitida oralmente, desde hace siglos, y cada vez más, almacenada y transmitida en soportes tecnológicos.

Y aquí viene lo mejor: tenemos un cierto control sobre la cultura, una cierta capacidad de decisión. Podemos elegir (siempre como especie, somo sociedad) ser chimpancés o bonobos. No depende de nuestra naturaleza animal, sino de nuestra naturaleza cultural. Yo soy bonobo, no porque lo dicte mi naturaleza, sino porque quiero serlo. Porque lo he aprendido de los libros, de mis amigos, de mis padres y hermanos. De Susana Moo. De los filósofos griegos y alemanes. Del cine y la música. Lo he aprendido de los chimpancés y los bonobos, de las moscas, las libélulas, los elefantes y las lechugas. De la lluvia y el viento. De mi cuerpo.

Elijo ser bonobo. ¿Quién se apunta?

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.