View file default/javascript/jquery.touchslider.min.js

File size: 20.46Kb
/*
TouchSlider 0.95
Licensed under the MIT license.
http://touchslider.com
*/
/*jslint browser: true, undef: true, sloppy: true, vars: true, white: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
/*global WebKitCSSMatrix: false, jQuery: false, getComputedStyle: false */

function closeModal(param){
	// Возвращаем позицию и скроллинг
	$('body').css({'overflow' : 'auto', 'position' : 'static'});
	
	if (param == 1)
	{
		history.back();
	}
	
	// Закрываем окно
	document.getElementById('modal-object').style.display = 'none'; 
    document.getElementById("modal-content").innerHTML = '';
	return false;
}

// Показ ближайших фото
function photoDisplay(id, count)
{
	var photoY = document.getElementById('id-' + (id)).alt;
	var idY = $("#show_" + id).attr("title");
	
	var photoURL = document.getElementById('photo_' + (id)).title;
	document.getElementById('action').href = photoURL;
	
	var countComment = document.getElementById('count_' + (id)).title;
	document.getElementById('count_comment').innerHTML = countComment;
	document.getElementById('comment').href = photoURL + '?komm';

	if (count > 0)
	{
		var photoL = document.getElementById('id-' + (id + 1)).alt;
		var idL = $("#show_" + (id + 1)).attr("title");

		if (idL != photoL) {
			document.getElementById('id-' + (id + 1)).src = '/foto/foto640/' + photoL + '.jpg';
			
			document.getElementById('show_' + (id + 1)).title = photoL;
		}
	}	
	
	if (count > 1)
	{
		var photoL2 = document.getElementById('id-' + (id + 2)).alt;
		var idL2 = $("#show_" + (id + 2)).attr("title");
		
		
		if (idL2 != photoL2) {
			document.getElementById('id-' + (id + 2)).src = '/foto/foto640/' + photoL2 + '.jpg';
			document.getElementById('show_' + (id + 2)).title = photoL2;
		}	
	}
	
	if (id > 0)
	{
		var photoR = document.getElementById('id-' + (id - 1)).alt;
		var idR = $("#show_" + (id - 1)).attr("title");
		
		if (idR != photoR) {
			document.getElementById('id-' + (id - 1)).src = '/foto/foto640/' + photoR + '.jpg';
			document.getElementById('show_' + (id - 1)).title = photoR;
		}
	}	
	
	if (id > 1)
	{
		var photoR2 = document.getElementById('id-' + (id - 2)).alt;
		var idR2 = $("#show_" + (id - 2)).attr("title");	
		
		
		if (idR2 != photoR2) {
			document.getElementById('id-' + (id - 2)).src = '/foto/foto640/' + photoR2 + '.jpg';
			document.getElementById('show_' + (id - 2)).title = photoR2;
		}
	}

	if (idY != photoY) {
		document.getElementById('id-' + (id)).src = '/foto/foto640/' + photoY + '.jpg';
		document.getElementById('show_' + (id)).title = photoY;
	}
	
}

(function($, undefined) {
	window.touchSlider = function(options) {
		options = options || {};
		var namespace = options.namespace || "touchslider",
			container = $(options.container);

		if (container.length !== 1) { // 0 or >1
			container.each(function() {
				touchSlider({container: this});
			});
			return;
		}

		options = $.extend({
				autoplay: false,
				delay: 3000,
				margin: 5,
				viewport: "." + namespace + "-viewport",
				prev: "." + namespace + "-prev",
				next: "." + namespace + "-next",
				pagination: "." + namespace + "-nav-item",
				currentClass: namespace + "-nav-item-current",
				duration: 150,
				mouseTouch: true
				// [container, scroller]
			}, options);
			

		var ret = {
				current: 0,
				step: step,
				next: next,
				prev: prev,
				start: start,
				stop: stop
			},
			isTouchWebkit = "ontouchstart" in window && "WebKitCSSMatrix" in window,
			touchstart = "touchstart", touchmove = "touchmove", touchend = "touchend",
			viewport = $(options.viewport, container),
			scroller = options.scroller ? $(options.scroller, container) : viewport.children(),
			slides = scroller.children(),
			pagination = $(options.pagination, container);

		if (scroller.css("position") !== "absolute") {
			var viewportHeight = viewport.height();
			viewport.css({
				height: viewportHeight,
				position: "relative"
			});
			scroller.css({
				position: "absolute",
				left: 0,
				height: viewportHeight,
				width: 100000
			});
		}

		if (!isTouchWebkit) {
			touchstart = "mousedown";
			touchmove = "mousemove";
			touchend = "mouseup";
		}

		slides.css("position", "absolute");

		// crossLeft( element )
		// crossLeft( element, pixels, [duration] )
		// crossLeft( element, function(index), [duration] )
		var crossLeft = isTouchWebkit
				? function(elem, px, duration) {
					if (px === undefined) {
						return new WebKitCSSMatrix(getComputedStyle(elem.jquery ? elem[0] : elem).webkitTransform).e;
					}
					elem.css({
						webkitTransitionDuration: duration ? duration + "ms" : "0",
						// http://jsperf.com/typeof-function-vs-instanceof/3
						webkitTransform: function(i){
							return "translate3d(" + (typeof px === "number" ? px : px.call(this, i)) + "px,0,0)";
						}
					});
				}
				: function(elem, px) {
					if (px === undefined) {
						return parseInt((elem.jquery ? elem[0] : elem).style.left, 10);
					}

					elem.css("left", px);
				};

		if (isTouchWebkit) {
			slides
				.css({
					webkitTransitionProperty: "-webkit-transform",
					webkitTransitionTimingFunction: "cubic-bezier(0,0,0.25,1)"
				});
		}
		crossLeft(slides.not(slides[0]), 10000);
		crossLeft(slides.eq(0), 0);

		var switching = (function() {
			var inViewport = [0],
				endCoords = [0], // for calc when an animation
				toComplete = $.noop;

			return {
				moving: false,
				init: function() {
					scroller.bind("webkitTransitionEnd", function() {
						toComplete();
					});
				},
				to: function(toIndex, opt) {
					opt = opt || {};
					if (toIndex >= slides.length) {
						toIndex = 0;
					} else if (toIndex < 0){
						toIndex = slides.length - 1;
					}
					var duration = options.duration,
						node = slides.eq(toIndex),
						indexInViewport = $.inArray(toIndex, inViewport),
						nodeLeft = 0;

					// http://bugs.jquery.com/ticket/10364
					scroller.stop();

					switching.moving = true;
					clearTimeout(autoPlayTimeout);

					if (indexInViewport !== -1) {
						nodeLeft = endCoords[indexInViewport];
					// add node if not exist
					} else {
						var i, nodeIndex = slides.index(node);
						// set position in viewport
						indexInViewport = undefined;

						if (opt.dirX === -1) {
							endCoords.unshift(0);
							inViewport.unshift(nodeIndex);
						} else if (opt.dirX === 1) {
							endCoords.push(0);
							inViewport.push(nodeIndex);
						} else {
							for (i = inViewport.length - 1; i >= 0; i--){
								if (inViewport[i] < nodeIndex) {
									endCoords.splice(i + 1, 0, 0);
									inViewport.splice(i + 1, 0, nodeIndex);
									indexInViewport = 0; // temp
									break;
								}
							}
							if (indexInViewport === undefined) {
								endCoords.unshift(endCoords);
								inViewport.unshift(nodeIndex);
							}
						}
						indexInViewport = $.inArray(nodeIndex, inViewport);

						// set start coordinates
						if (indexInViewport === 0) {
							nodeLeft = endCoords[1] - (node.outerWidth() + options.margin);
							crossLeft(node, nodeLeft);
							endCoords[indexInViewport] = nodeLeft;
						} else if (indexInViewport === inViewport.length - 1) {
							nodeLeft = endCoords[indexInViewport - 1] + slides.eq(inViewport[indexInViewport - 1]).outerWidth() + options.margin;
							crossLeft(node, nodeLeft);
							endCoords[indexInViewport] = nodeLeft;
						} else {
							var nodeWidth = node.outerWidth();
							node.css("opacity", 0);
							// for example: inViewport = [0,1,2,3,4] and indexInViewport = 2
							// center, [2]
							nodeLeft = endCoords[indexInViewport+1] - Math.round((nodeWidth + options.margin) / 2);
							endCoords[indexInViewport] = nodeLeft;
							crossLeft(node, nodeLeft);

							// left calc, [0,1]
							var leftInL = nodeLeft, l = inViewport.length;
							for (i = indexInViewport - 1; i >= 0; i--) {
								leftInL -= slides.eq(inViewport[i]).outerWidth() + options.margin;
								endCoords[i] = leftInL;
							}

							// right calc, [3,4]
							var leftInR = nodeLeft;
							
							for (i = indexInViewport + 1; i < l; i++) {
								leftInR += slides.eq(inViewport[i]).outerWidth() + options.margin;
								endCoords[i] = leftInR;
							}

							for (i = 0; i < l; i++) {
								slides.eq(inViewport[i])
									.animate({ left: endCoords[i] }, {
										duration: duration,
										queue: false,
										complete: function() {
											if (node.is(this)) {
												node.animate({ opacity: 1 }, duration);
											}
										}
									});
							}
						}
					}

					if (opt.pxInMs) {
						duration = Math.min(Math.max(Math.round(Math.abs(crossLeft(scroller)) / opt.pxInMs), 100), duration);
					}

					toComplete = function() {
						crossLeft(slides.not(node), -10000);
						inViewport = [slides.index(node)];
						endCoords = [nodeLeft];
						if (opt.complete) {
							opt.complete();
						}
						switching.moving = false;
						autoPlay();
						
						photoDisplay(slides.index(node), document.getElementById('photo_count').title);
					};

					// go!
					if (!isTouchWebkit) {
						scroller.animate(
							{
								left: - nodeLeft
							}, {
								duration: duration,
								queue: false,
								complete: toComplete
						});
					} else {
						crossLeft(scroller, - nodeLeft, duration);
					}

					ret.current = toIndex;
					changedView(toIndex);
				},

				stop: function() {
					if (isTouchWebkit) {
						crossLeft(scroller, crossLeft(scroller));
					} else {
						scroller.stop();
					}
				},

				moveStart: function(e) {
					switching.moving = true;
					clearTimeout(autoPlayTimeout);
					scroller.stop();

					switching.startPageX = e.pageX;
					// if deceleration in progress
					var scrollerLeft = crossLeft(scroller),
						lastLeft;

					switching.leftCount = scrollerLeft;
					if (inViewport[0] === 0) {
						if (endCoords[0] + scrollerLeft > 0) {
							switching.leftCount = scrollerLeft + (endCoords[0] + scrollerLeft) * 3;
						}
					} else if (inViewport[inViewport.length - 1] === slides.length - 1) {
						lastLeft = endCoords[inViewport.length - 1] + scrollerLeft;
						if (lastLeft < 0) {
							switching.leftCount = scrollerLeft + lastLeft * 3;
						}
					}
				},

				move: function(e, previousPageX) {
					var diffX = e.pageX - previousPageX,
						scrollerLeft = crossLeft(scroller),
						first = slides.eq(inViewport[0]),
						lastIndex = inViewport.length - 1,
						last = slides.eq(inViewport[lastIndex]),
						add, addLeft, deceleration;

					switching.leftCount += diffX;
					// add slide to left
					if (diffX > 0) {
						// while is used in case of fast moving
						while (inViewport[0] !== 0 && scrollerLeft + endCoords[0] + diffX > options.margin) {
							add = slides.eq(inViewport[0] - 1); // or "first.index() - 1"
							addLeft = endCoords[0] - add.outerWidth() - options.margin;
							crossLeft(add, addLeft);
							endCoords.unshift(addLeft);
							inViewport.unshift(inViewport[0] - 1);
							lastIndex++;
							first = add;
						}
					}
					// deceleration in left
					if ((
						    (diffX > 0 && scrollerLeft + endCoords[0] + diffX > 0)
						 || (diffX < 0 && scrollerLeft + endCoords[0] > 0)
						) && inViewport[0] === 0
					) {
						deceleration = Math.min(Math.round((switching.leftCount + endCoords[0]) / 4), viewport.innerWidth() / 2);
						diffX = deceleration - (scrollerLeft + endCoords[0]);
					}

					// add slide to right
					if (diffX < 0) {
						while (!last.is(slides.last()) && scrollerLeft + endCoords[lastIndex] + diffX + last.outerWidth() + options.margin < viewport.innerWidth()) {
							add = slides.eq(inViewport[lastIndex] + 1);
							addLeft = endCoords[lastIndex] + last.outerWidth() + options.margin;
							crossLeft(add, addLeft);
							endCoords.push(addLeft);
							inViewport.push(inViewport[lastIndex++] + 1);
							last = add;
						}
					}
					// deceleration in right
					if ((
						    (diffX > 0 && scrollerLeft + endCoords[lastIndex] < 0)
						 || (diffX < 0 && scrollerLeft + endCoords[lastIndex] + diffX < 0)
						) && last.is(slides.last())
					) {
						deceleration = Math.max(Math.round((switching.leftCount + endCoords[lastIndex]) / 4), - viewport.innerWidth() / 2);
						diffX = deceleration - (scrollerLeft + endCoords[lastIndex]);
					}

					crossLeft(scroller, scrollerLeft + diffX);
				},

				moveEnd: function(e, pxInMs, directionX, startTime, distX, distY) {
					// TODO clear inViewport
					var inViewportLength = inViewport.length,
						scrollerLeft = crossLeft(scroller),
						toIndex = inViewportLength - 1,
						opt;
					if (endCoords[0] + scrollerLeft > 0) { // space in left
						toIndex = 0;
					} else if (endCoords[inViewport.length - 1] + scrollerLeft < 0) { // space in right
						/* nothing */
					} else {
						opt = {pxInMs: pxInMs};
						// maximum area
						var i, right,
							maximumInViewport = inViewportLength - 1,
							viewportWidth = viewport.innerWidth();
						for (i = 0 ; i < inViewportLength - 1; i++ ) { // no need check last
							right = endCoords[i] + slides.eq(inViewport[i]).outerWidth() + scrollerLeft;
							if (right > 0 && right > viewportWidth - (endCoords[i+1] + scrollerLeft)) {
								maximumInViewport = i;
								break;
							}
						}

						if (onFly) {
							toIndex = maximumInViewport;
						} else {
							var touched = inViewportLength - 1,
								scrollerOffsetLeft = Math.round(scroller.offset().left); // cast
							for (i = 0; i < inViewportLength; i++ ) {
								if (endCoords[i] + scrollerOffsetLeft > e.pageX) {
									touched = i - 1;
									break;
								}
							}
							toIndex = maximumInViewport;
							// 5% of diagonal
							if (maximumInViewport === touched &&
								e.timeStamp - startTime < 1000 &&
								distX + distY > Math.sqrt(Math.pow(viewport.height(), 2) + Math.pow(viewportWidth, 2)) * 0.05)
							{
								toIndex = Math.max(0, Math.min(inViewportLength - 1, toIndex + directionX));
							}
						}
					}

					toIndex = inViewport[toIndex];
					switching.to(toIndex, opt);
				}
			};
		}());

		switching.init();

		if (isTouchWebkit) {
			var onFly = false;
			scroller.bind("webkitTransitionStart", function() {
				onFly = true;
			});
			scroller.bind("webkitTransitionEnd", function() {
				onFly = false;
			});
		}

		function changedView(index) {
			pagination.removeClass(options.currentClass)
				.eq(index).addClass(options.currentClass);
		}

		// set item or next
		function step(toIndex, complete) {
			var currentIndex = ret.current;
			if (currentIndex !== toIndex) {
				toIndex = toIndex !== undefined ? toIndex : currentIndex + 1;

				switching.to(toIndex, { complete: complete });
				
			}
		}

		function next(complete) {
			switching.to(ret.current + 1, { dirX: 1, complete: complete });
		}

		function prev(complete) {
			
			switching.to(ret.current - 1, { dirX: -1, complete: complete });
		}

		/* Autoplay */
		var mouseInViewport = false,
			isPlay = false,
			autoPlayTimeout;

		viewport.hover(function() {
				clearTimeout(autoPlayTimeout);
				mouseInViewport = true;
			}, function() {
				mouseInViewport = false;
				autoPlay();
		});

		function autoPlay() {
			if (isPlay) {
				start();
			}
		}

		function start() {
			isPlay = true;
			if (!mouseInViewport) {
				clearTimeout(autoPlayTimeout);
				autoPlayTimeout = setTimeout(function() {
					if (!switching.moving && !mouseInViewport) {
						next();
					}
				}, options.delay);
			}
			return options.container;
		}

		function stop() {
			clearTimeout(autoPlayTimeout);
			isPlay = false;
			return options.container;
		}

		/* Navigation */
		// not use delegate(), for correct selection in mobile webkit
		pagination.click(function() {
			step(pagination.index(this));
		});

		// left/right button
		$(options.prev, container).click(function() {
			prev();
		});

		$(options.next, container).click(function() {
			next();
		});

		function initTouch() {
			var doc = $(document), startTime, defaultPrevented,
				moving = false, // if mouseup in stopPropogation area
				times, coords, // for accelerate
				startPageX, previousPageX, distX, absDistX, startLeft,
				startPageY, previousPageY, distY, absDistY,
				start = function(e) {
					if (e.which > 1) {
						
						return;
					}

					if (moving) {
						doc.triggerHandler(touchend + "." + namespace);
					}

					moving = false;
					defaultPrevented = false,
					startTime = e.timeStamp;
					distX = distY = 0;

					times = [0, 0, 0, startTime];

					// delegate to document for coorect touches length
					if (e.originalEvent.touches) {
						doc.one(touchstart, touchStart);
						return;
					}

					// no drag images
					e.preventDefault();

					startPageX = previousPageX = e.pageX;
					startPageY = previousPageY = e.pageY;
					startLeft = scroller[0].offsetLeft;

					coords = [0, 0, 0, startPageX];

					doc.bind(touchmove, move);
					doc.one(touchend + "." + namespace, end);

					switching.moveStart(e);
				},
				touchStart = function(e) {
					if (e.originalEvent.touches.length !== 1) {
						
						return;
					}

					startPageX = previousPageX = e.pageX = e.originalEvent.touches[0].pageX;
					startPageY = previousPageY = e.pageY = e.originalEvent.touches[0].pageY;
					absDistX = absDistY = 0;

					startLeft = new WebKitCSSMatrix(window.getComputedStyle(scroller[0]).webkitTransform).e;

					coords = [0, 0, 0, startPageX];

					doc.bind(touchmove, move);
					doc.one(touchend, end);

					switching.moveStart(e);
				},
				move = function(e) {
					var pageX, pageY;
					if (e.originalEvent.touches && isTouchWebkit) {
						if (e.originalEvent.touches.length !== 1) {
							return;
						}
						pageX = e.pageX = e.originalEvent.touches[0].pageX;
						pageY = e.pageY = e.originalEvent.touches[0].pageY;

						// iphone allow scrolling page
						absDistX += Math.abs(pageX - previousPageX);
						absDistY += Math.abs(pageY - previousPageY);

						// when long touching in one direction and then want to switch
						if (Math.abs(absDistX - absDistY) > 50) {
							var absDistXOld = absDistX;
							absDistX = Math.min(100, Math.max(0, absDistX - absDistY));
							absDistY = Math.min(100, Math.max(0, absDistY - absDistXOld));
						}

						if (pageX === previousPageX) {
							return;
						}

						// to scroll in a single direction
						if (!defaultPrevented) {
							if (absDistX > absDistY) {
								e.preventDefault();
								defaultPrevented = true;
							} else {
								end(e);
							}
						}
					} else {
						pageX = e.pageX;
						pageY = e.pageY;

						if (pageX === previousPageX) {
							return;
						}

						if ($.browser.msie) {
							e.preventDefault();
						}
					}

					distX += Math.abs(pageX - previousPageX);
					distY += Math.abs(pageY - previousPageY);
					times.shift();
					times.push(e.timeStamp);

					coords.shift();
					coords.push(pageX);

					switching.move(e, previousPageX);

					previousPageX = pageX;
					previousPageY = pageY;

				},
				end = function(e) {
					moving = false;
					// mobile webkit browser fix
					if (!e.originalEvent || e.originalEvent.touches) {
						e.pageX = previousPageX;
						e.pageY = previousPageY;
					}
					doc.unbind(touchmove, move);

					var i = times.length, pxInMs = 0, directionX = 0; // accelerate
					while (--i > 0) {
						if (times[i-1]) {
							var diffCoords = coords[i] - coords[i - 1];
							pxInMs += Math.abs(diffCoords)/(times[i] - times[i - 1]);
							if (diffCoords !== 0) {
								directionX = diffCoords > 0 ? -1 : 1;
							}
						}
					}
					pxInMs = pxInMs/times.length;

					switching.moveEnd(e, pxInMs, directionX, startTime, distX, distY);
					onFly = false;

					if (distX + distY > 4) {
						viewport.one("click", function(e) {
							e.preventDefault();
						});
					}
				};
			viewport.bind(touchstart, start);
		}
		if (options.mouseTouch) {
			initTouch();
		}

		if (options.autoplay) {
			start();
		}

		container.data(namespace, ret);
	};

	$.fn.touchSlider = function(options) {
		options = options || {};
		options.container = this;
		touchSlider(options);
		return this;
	};
}(jQuery));