/*
-* © 2008-2014 Benoît Pin – Centre de recherche en informatique – MINES ParisTech
-* http://plinn.org
-* Licence Creative Commons http://creativecommons.org/licenses/by-nc/2.0/
-*
-*
+copyright 2008-2014 Benoit Pin - Centre de recherche en informatique - MINES ParisTech
+http://plinn.org
+Licence Creative Commons http://creativecommons.org/licenses/by-nc/2.0/
*/
var FilmSlider;
-
(function(){
var keyLeft = 37, keyRight = 39;
FilmSlider = function(filmBar, slider, ctxInfos, image, toolbar, breadcrumbs) {
var thisSlider = this;
this.filmBar = filmBar;
+ this.filmBarWidth = getObjectWidth(this.filmBar);
var film = filmBar.firstChild;
if (film.nodeType === 3) { film = film.nextSibling; }
this.film = film;
'out' : function(evt){thisSlider.mouseOutHandler(evt);}
};
- this.resizeSlider();
+ if (browser.isMobile) {
+ this.rail.className = 'hidden';
+ }
+ else {
+ this.resizeSlider();
+ }
this.addEventListeners();
};
-
-FilmSlider.prototype.resizeSlider = function(evt) {
- var filmBarWidth = getObjectWidth(this.filmBar);
- if (!filmBarWidth) {
- var thisSlider = this;
- addListener(window, 'load', function(evt){thisSlider.resizeSlider(evt);});
- return;
- }
+if (!browser.isMobile) {
+ FilmSlider.prototype.resizeSlider = function(evt) {
+ var filmBarWidth = this.filmBarWidth;
+ if (!filmBarWidth) { return; }
+ var filmWidth = this.slideSize * this.filmLength;
+ var sliderRatio = this.sliderRatio = filmBarWidth / filmWidth;
+ var sliderWidth = filmBarWidth * sliderRatio;
+ this.rail.style.width = filmBarWidth + 'px';
+ this.rail.style.display = 'block';
+ this.rail.style.visibility = 'visible';
+ if (sliderRatio < 1) {
+ this.slider.style.width = Math.round(sliderWidth) + 'px';
+ this.slider.style.visibility = 'visible';
+ }
+ else {
+ this.slider.style.visibility = 'hidden';
+ }
- var filmWidth = this.slideSize * this.filmLength;
- var sliderRatio = this.sliderRatio = filmBarWidth / filmWidth;
- var sliderWidth = filmBarWidth * sliderRatio;
- this.rail.style.width = filmBarWidth + 'px';
- this.rail.style.display = 'block';
- this.rail.style.visibility = 'visible';
- if (sliderRatio < 1) {
- this.slider.style.width = Math.round(sliderWidth) + 'px';
- this.slider.style.visibility = 'visible';
- }
- else {
- this.slider.style.visibility = 'hidden';
+ this.winSize = {'width' : getWindowWidth(),
+ 'height' : getWindowHeight()};
+ this.maxRightPosition = filmBarWidth - sliderWidth;
+ this.sliderSpeedRatio = - (filmBarWidth - sliderWidth) / (filmWidth - filmBarWidth);
+ if (!this.initialized) {
+ this.centerSlide(this.center);
+ this.selectedSlide = this.filmBar.getElementsByTagName('img')[this.center].parentNode;
+ this.initialized = true;
+ }
+ };
+}
+
+else {
+ // pas de barre de scroll horizontal pour les tablettes
+ FilmSlider.prototype.resizeSlider = function(evt) {
+ this.filmMaxX = - (getObjectWidth(this.film) - this.filmBarWidth);
+ if (!this.initialized) {
+ this.centerSlide(this.center);
+ this.selectedSlide = this.filmBar.getElementsByTagName('img')[this.center].parentNode;
+ this.initialized = true;
+ }
+ };
+}
+
+FilmSlider.prototype._checkSizeAfterLoad = function(evt) {
+ this._barSizes = [];
+ this.filmBarWidth = this._barSizes[this._barSizes.length] = getObjectWidth(this.filmBar);
+ this.resizeSlider();
+ var self = this;
+ this._checkSizeIntervalId = setInterval(function(evt){self._checkSize(evt);}, 25);
+ setTimeout(function(evt){self._checkSizeStability();}, 250);
+};
+
+FilmSlider.prototype._checkSize = function(evt) {
+ this._barSizes[this._barSizes.length] = getObjectWidth(this.filmBar);
+ if (this._barSizes.length >= 2 &&
+ this._barSizes[this._barSizes.length-2] !== this._barSizes[this._barSizes.length-1]) {
+ this.filmBarWidth = this._barSizes[this._barSizes.length-1];
+ this.initialized = false;
+ this.resizeSlider();
}
-
- this.winSize = {'width' : getWindowWidth(),
- 'height' : getWindowHeight()};
- this.maxRightPosition = filmBarWidth - sliderWidth;
- this.sliderSpeedRatio = - (filmBarWidth - sliderWidth) / (filmWidth - filmBarWidth);
- if (!this.initialized) {
- this.centerSlide(this.center);
- this.selectedSlide = this.filmBar.getElementsByTagName('img')[this.center].parentNode;
- this.initialized = true;
+};
+
+FilmSlider.prototype._checkSizeStability = function(evt) {
+ var self = this;
+ var i;
+ var checkAgain = function(evt){self._checkSizeStability();};
+ for (i=0 ; i<this._barSizes.length - 1 ; i++) {
+ if (this._barSizes[i] !== this._barSizes[i+1]) {
+ this._barSizes = [];
+ setTimeout(checkAgain, 250);
+ return;
+ }
}
+ clearInterval(this._checkSizeIntervalId);
+ delete this._barSizes;
+ delete this._checkSizeIntervalId;
};
FilmSlider.prototype.fitToScreen = function(evt) {
FilmSlider.prototype._fitToScreen = function(evt) {
var wh = getWindowHeight();
- var rb = getObjectTop(this.rail) + getObjectHeight(this.rail); // rail bottom
+ var rb;
+ if (!browser.isMobile) {
+ rb = getObjectTop(this.rail) + getObjectHeight(this.rail); // rail bottom
+ }
+ else {
+ rb = getObjectTop(this.filmBar) + getObjectHeight(this.filmBar); // film bottom
+ }
var delta = wh - rb;
var sh = getObjectHeight(this.stretchable);
var newSize = sh + delta;
var src = this.image.src.replace(imgRequestedSize, 'size=' + bestFitSize);
this.pendingImage.src = src;
}
+ this.adjustImage(this.image);
};
FilmSlider.prototype.getBestFitSize = function(ratio) {
return DEFAULT_IMAGE_SIZES[i];
};
-FilmSlider.prototype.centerSlide = function(slideIndex) {
- if (this.sliderRatio > 1) { return; }
- var filmBarWidth = getObjectWidth(this.filmBar);
- var x = slideIndex * this.slideSize;
- x = x - (filmBarWidth - this.slideSize) / 2.0;
- x = x * this.sliderSpeedRatio;
- var p = new Point( -x, 0 );
- this.setSliderPosition(p);
+FilmSlider.prototype.adjustImage = function(img) {
+ var dispWidth = parseInt(this.stretchable.style.width, 10);
+ var imgWidth = img.naturalWidth;
+ var dispHeight = parseInt(this.stretchable.style.height, 10);
+ var imgHeight = img.naturalHeight;
+ var ratio;
+
+ if (imgHeight > dispHeight) {
+ ratio = dispHeight / imgHeight;
+ imgWidth = imgWidth * ratio;
+ imgHeight = dispHeight;
+ }
+ if (imgWidth > dispWidth) {
+ ratio = dispWidth / imgWidth;
+ imgHeight = imgHeight * ratio;
+ imgWidth = dispWidth;
+ }
+ img.width = imgWidth;
+ img.height = imgHeight;
};
+if (!browser.isMobile) {
+ FilmSlider.prototype.centerSlide = function(slideIndex) {
+ if (this.sliderRatio > 1) { return; }
+ var filmBarWidth = getObjectWidth(this.filmBar);
+ var x = slideIndex * this.slideSize;
+ x = x - (filmBarWidth - this.slideSize) / 2.0;
+ x = x * this.sliderSpeedRatio;
+ var p = new Point( -x, 0 );
+ this.setSliderPosition(p);
+ };
+}
+else {
+ FilmSlider.prototype.centerSlide = function(slideIndex) {
+ var filmBarWidth = getObjectWidth(this.filmBar);
+ var x = slideIndex * this.slideSize;
+ x = x - (filmBarWidth - this.slideSize) / 2.0;
+ this.setFilmPosition(-x);
+ };
+}
+
FilmSlider.prototype.setSliderPosition = function(point) {
if(point.x < 0) { point.x = 0; }
if (point.x > this.maxRightPosition) { point.x = this.maxRightPosition; }
this.setFilmPosition(point);
};
-FilmSlider.prototype.setFilmPosition = function(point) {
- this.film.style.left = point.x / this.sliderSpeedRatio + 'px';
-};
+if (!browser.isMobile) {
+ FilmSlider.prototype.setFilmPosition = function(point) {
+ this.film.style.left = point.x / this.sliderSpeedRatio + 'px';
+ };
+}
+else {
+ FilmSlider.prototype.setFilmPosition = function(x) {
+ x = Math.min(0, x);
+ x = Math.max(this.filmMaxX, x);
+ this.film.style.left = String(x) + 'px';
+ };
+}
FilmSlider.prototype.getSliderPosition = function() {
var x = parseInt(this.slider.style.left, 10);
addListener(this.filmBar, 'click', function(evt){thisSlider.thumbnailClickHandler(evt);});
addListener(this.toolbar, 'click', function(evt){thisSlider.toolbarClickHandler(evt);});
addListener(window, 'load', function(evt){thisSlider.fitToScreen(evt);});
+ addListener(window, 'load', function(evt){thisSlider._checkSizeAfterLoad(evt);});
+ addListener(window, 'load', function(evt){thisSlider.startThumbnailsLoadQueue(evt);});
// dd listeners
addListener(this.slider, 'mousedown', this.ddHandlers.down);
else if (browser.isIE6up) {
addListener(this.filmBar, 'mousewheel', function(evt){thisSlider.mouseWheelHandler(evt);});
}
+ if (browser.isMobile) {
+ this.filmBar.addEventListener('touchstart', function(evt){thisSlider.touchStartHandler(evt);}, false);
+ this.filmBar.addEventListener('touchmove', function(evt){thisSlider.touchMoveHandler(evt);}, false);
+ this.filmBar.addEventListener('touchend', function(evt){thisSlider.touchEndHandler(evt);}, false);
+ }
addListener(document, 'keydown', function(evt){thisSlider.keyDownHandler(evt);});
addListener(document, 'keypress', function(evt){thisSlider.keyPressHandler(evt);});
}
};
+FilmSlider.prototype.translateImgUrl = function(url) {
+ var canonicalImgUrl;
+ if (this.ctxUrlTranslation[0]) {
+ canonicalImgUrl = url.replace(this.ctxUrlTranslation[0],
+ this.ctxUrlTranslation[1]);
+ }
+ else {
+ canonicalImgUrl = url;
+ }
+ return canonicalImgUrl;
+};
+
FilmSlider.prototype.thumbnailClickHandler = function(evt) {
var target = getTargetedObject(evt);
while (target.tagName !== 'A' && target !== this.filmBar) { target = target.parentNode; }
history.pushState(target.href, '', target.href);
var imgBaseUrl = target.href;
- var canonicalImgUrl;
- if (this.ctxUrlTranslation[0]) {
- canonicalImgUrl = imgBaseUrl.replace(this.ctxUrlTranslation[0],
- this.ctxUrlTranslation[1]);
- }
- else { canonicalImgUrl = imgBaseUrl; }
+ var canonicalImgUrl = this.translateImgUrl(imgBaseUrl);
var ajaxUrl = imgBaseUrl + '/photo_view_ajax';
var thisFS = this;
this.cartSlide.style.visibility='hidden';
- var metadataButton = this.buttons['edit_metadata']
+ var metadataButton = this.buttons.edit_metadata;
if (metadataButton) {
var metadataEditLink = metadataButton.parentNode;
- metadataEditLink.href = canonicalImgUrl + '/photo_edit_form'
+ metadataEditLink.href = canonicalImgUrl + '/photo_edit_form';
}
break;
case 4 :
hideProgressImage();
- if (req.status === '200') { thisFS.populateViewer(req); }
- // else
- // //window.location.href = target.href;
- // console.error(ajaxUrl);
-
- };
+ if (req.status === 200) { thisFS.populateViewer(req); }
+ break;
+ }
};
req.open("GET", ajaxUrl, true);
var newClasses = [];
var name, i;
- for (i in classes) {
+ for (i=0 ; i<classes.length ; i++) {
name = classes[i];
- if (name === 'displayed') { continue; }
- else { newClasses.push(name); }
+ if (name !== 'displayed') {
+ newClasses.push(name);
+ }
}
- this.selectedSlide.className = newClasses.join(' ')
+ this.selectedSlide.className = newClasses.join(' ');
// hightlight new displayed slide
this.selectedSlide = target;
FilmSlider.prototype.toolbarClickHandler = function(evt) {
var target = getTargetedObject(evt);
+ var button, link, url;
if(target.tagName === 'IMG' && target.getAttribute('name')) {
switch(target.getAttribute('name')) {
case 'previous' :
disableDefault(evt);
disablePropagation(evt);
- var button = target;
- var link = button.parentNode;
+ button = target;
+ link = button.parentNode;
link.blur();
this.loadSibling(true);
break;
case 'next' :
disableDefault(evt);
disablePropagation(evt);
- var button = target;
- var link = button.parentNode;
+ button = target;
+ link = button.parentNode;
link.blur();
this.loadSibling(false);
break;
return;
}
var main = document.getElementById('photo_viewer');
- var url = target.parentNode.href;
+ url = target.parentNode.href;
url = url.substring(0, url.length - '/zoom_view'.length);
var margins = {'top':0, 'right':-1, 'bottom':0, 'left':0};
this.mosaique = new Mosaique(main, url, margins);
case 'toggle_selection':
disableDefault(evt);
disablePropagation(evt);
- var button = target;
- var link = button.parentNode;
+ button = target;
+ link = button.parentNode;
link.blur();
var req = new XMLHttpRequest();
- var url = link.href;
+ url = link.href;
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
req.send("ajax=1");
case 'show_buyable':
disableDefault(evt);
disablePropagation(evt);
- var button = target;
- var link = button.parentNode;
+ button = target;
+ link = button.parentNode;
link.blur();
var slide = this.cartSlide;
slide.innerHTML = '';
};
}
+FilmSlider.prototype.touchStartHandler = function(evt) {
+ this.filmStartX = parseInt(this.film.style.left, 10);
+ this.touchStartX = evt.changedTouches[0].screenX;
+ this.touchStartTime = (new Date()).getTime();
+};
+
+FilmSlider.prototype.touchMoveHandler = function(evt) {
+ disableDefault(evt);
+ var delta = this.touchStartX - evt.changedTouches[0].screenX;
+ var posX = this.filmStartX - delta;
+ this.setFilmPosition(posX);
+ this.lastMoveTime = (new Date()).getTime();
+};
+
+FilmSlider.prototype.touchEndHandler = function(evt) {
+ var x = evt.changedTouches[0].screenX;
+ var delta = x - this.touchStartX;
+ if (delta) {
+ disableDefault(evt);
+ var now = (new Date()).getTime();
+ if (now - this.lastMoveTime < 100) {
+ // au delà de 100 ms de maintient, on annule l'inertie
+ var speed = delta / (now - this.touchStartTime);
+ var x0 = parseInt(this.film.style.left, 10);
+ var t0 = (new Date()).getTime();
+ var d = 500; // milisecondes
+ delta = 0;
+ var dt = 25;
+ var self = this;
+
+ var animate = function() {
+ // inertie
+ var t = (new Date()).getTime() - t0;
+ if (t < d) {
+ setTimeout(animate, dt);
+ delta = delta + (1-t/d) * speed * dt; // décelleration linéaire
+ self.setFilmPosition(x0 + delta);
+ }
+ };
+ animate();
+ }
+ }
+ this.touchStartX = undefined;
+};
+
+
FilmSlider.prototype.keyDownHandler = function(evt) {
- var evt = getEventObject(evt);
+ evt = getEventObject(evt);
switch (evt.keyCode) {
case keyLeft :
this.loadSibling(true);
FilmSlider.prototype.keyPressHandler = function(evt) {
var target = getTargetedObject(evt);
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') { return; }
- var evt = getEventObject(evt);
+ evt = getEventObject(evt);
var charPress = String.fromCharCode((evt.keyCode) ? evt.keyCode : evt.which);
switch(charPress) {
case 'f':
case 'F':
- raiseMouseEvent(this.buttons['full_screen'], 'click');
+ raiseMouseEvent(this.buttons.full_screen, 'click');
break;
}
};
FilmSlider.prototype.populateViewer = function(req) {
var elements = req.responseXML.documentElement.childNodes;
- for(var i=0 ; i < elements.length ; i++ ) {
+ var i;
+ for(i=0 ; i < elements.length ; i++ ) {
element = elements[i];
switch (element.nodeName) {
case 'fragment' :
if (dest) { dest.innerHTML = element.firstChild.nodeValue; }
break;
case 'imageattributes' :
- var link = this.buttons['back_to_portfolio'].parentNode;
- link.href = element.getAttribute('backToContextUrl');
- link = this.buttons['show_buyable'].parentNode;
+ var link = this.buttons.back_to_portfolio.parentNode;
+ link.href = element.getAttribute('back_to_context_url');
+ link = this.buttons.show_buyable.parentNode;
var buyable = element.getAttribute('buyable');
if(buyable === 'True') { link.className = null; }
else if(buyable === 'False') { link.className = 'hidden'; }
this.image.alt = element.getAttribute('alt');
- this.updateBreadcrumbs(element.getAttribute('lastBcUrl'),
+ this.updateBreadcrumbs(element.getAttribute('last_bc_url'),
element.getAttribute('img_id'));
break;
}
};
FilmSlider.prototype.refreshImage = function() {
+ this.adjustImage(this.pendingImage);
this.image.style.visibility = 'hidden';
this.image.src = this.pendingImage.src;
this.image.width = this.pendingImage.width;
FilmSlider.prototype.updateBreadcrumbs = function(url, title) {
if (this.hasBreadcrumbs) {
- this.lastBCElement.href = element.getAttribute('lastBcUrl');
- this.lastBCElement.innerHTML = element.getAttribute('img_id');
+ this.lastBCElement.href = url;
+ this.lastBCElement.innerHTML = title;
}
};
+FilmSlider.prototype.startThumbnailsLoadQueue = function(evt) {
+ var thumbnails = this.film.getElementsByTagName('img');
+ if (thumbnails.length === 1) { return; }
+ this.thumbnailsLoadingOrder = [];
+ var leftSize = this.center;
+ var rightSize = thumbnails.length - this.center - 1;
+ var i;
+ for (i=1 ; i<=Math.min(leftSize, rightSize) ; i++) {
+ this.thumbnailsLoadingOrder.push(thumbnails[this.center + i]);
+ this.thumbnailsLoadingOrder.push(thumbnails[this.center - i]);
+ }
+ if (leftSize > rightSize) {
+ for (i = this.center - rightSize - 1 ; i >= 0 ; i--) {
+ this.thumbnailsLoadingOrder.push(thumbnails[i]);
+ }
+ }
+ else if (leftSize < rightSize) {
+ for (i = this.center + leftSize + 1 ; i < thumbnails.length ; i++) {
+ this.thumbnailsLoadingOrder.push(thumbnails[i]);
+ }
+ }
+ var next = this.thumbnailsLoadingOrder.shift();
+ var self = this;
+ addListener(next, 'load', function(evt){self._loadNextThumb(evt);});
+ next.src = this.translateImgUrl(next.parentNode.href) + '/getThumbnail';
+};
+
+FilmSlider.prototype._loadNextThumb = function(evt) {
+ var next = this.thumbnailsLoadingOrder.shift();
+ if (!next) {return;}
+ var self = this;
+ addListener(next, 'load', function(evt){self._loadNextThumb(evt);});
+ next.src = this.translateImgUrl(next.parentNode.href) + '/getThumbnail';
+};
+
+
FilmSlider.prototype.startSlideShow = function() {
this.slideShowSlide = this.pendingSlideShowSlide = this.selectedSlide;
return this.slideShowSlide.href;
else {
var row = this.slideShowSlide.parentNode.parentNode;
var first = row.firstChild;
- if (first.nodeType===3)
- first = first.nextSibling;
+ if (first.nodeType===3) { first = first.nextSibling; }
this.pendingSlideShowSlide = first.getElementsByTagName('a')[0];
return this.pendingSlideShowSlide.href;
}
FilmSlider.prototype.stopSlideShow = function() {
raiseMouseEvent(this.slideShowSlide, 'click');
- var index = parseInt(this.selectedSlide.getAttribute('portfolio:position'));
+ var index = parseInt(this.selectedSlide.getAttribute('portfolio:position'), 10);
this.centerSlide(index);
};
}
Point.prototype.diff = function(point) { return new Point(this.x - point.x, this.y - point.y); };
Point.prototype.add = function(point) { return new Point(this.x + point.x, this.y + point.y); };
-Point.prototype.mul = function(k) { return new Point(this.x * k, this.y *k)};
+Point.prototype.mul = function(k) { return new Point(this.x * k, this.y *k); };
Point.prototype.toString = function() { return "(" + String(this.x) + ", " + String(this.y) + ")"; };
-})();
+}());