UNPKG

e-lado

Version:

[![CircleCI](https://circleci.com/gh/sharetribe/sharetribe/tree/master.svg?style=svg)](https://circleci.com/gh/sharetribe/sharetribe/tree/master) [![Dependency Status](https://gemnasium.com/sharetribe/sharetribe.png)](https://gemnasium.com/sharetribe/shar

176 lines (141 loc) 4.99 kB
window.ST = window.ST || {}; ST.thumbnailStripe = function(images, opts) { var container = $("#thumbnail-stripe"); var thumbnailTmpl = _.template($("#image-thumbnail-template").html()); // Options opts = opts || {}; var selectedClass = opts.selectedClass || "selected"; var thumbnailWidth = opts.thumbnailWidth || 60; var paddingAdjustment = opts.paddingAdjustment || 0; var swipeDelay = 300; // Element initialization container.empty(); var thumbnailContainer = $("<div />"); thumbnailContainer.css("position", "absolute"); thumbnailContainer.css("left", ["-", paddingAdjustment, "px"].join("")); thumbnailContainer.css("right", ["-", paddingAdjustment, "px"].join("")); container.append(thumbnailContainer); var thumbnailContainerWidth; var thumbnailClickS = []; var elements = _.map(images, function(image, idx) { var thumbnailElement = $(thumbnailTmpl({url: image.images.thumb })); thumbnailClickS.push(thumbnailElement.asEventStream("click").map(function() { return idx; })); return thumbnailElement; }); var clickS = Bacon.mergeAll.apply(null, thumbnailClickS).debounceImmediate(swipeDelay); _.each(elements, function(el) { thumbnailContainer.append(el); }); if(elements.length < 2) { container.hide(); } thumbnailContainerWidth = elements.length * thumbnailWidth + 2 * paddingAdjustment; thumbnailContainer.width(thumbnailContainerWidth); // State var initialIdx = 0; var containerMoved = 0; var modAdded = 0; var nextId = _.partial(ST.utils.nextIndex, elements.length); var prevId = _.partial(ST.utils.prevIndex, elements.length); var nextBus = new Bacon.Bus(); var prevBus = new Bacon.Bus(); elements[initialIdx].addClass(selectedClass); function visibleWidth() { return container.width(); } function maxMovement() { return Math.max((elements.length - Math.floor(visibleWidth() / thumbnailWidth)) - 2, 0); } function modWidth() { return thumbnailWidth - ((visibleWidth() % thumbnailWidth) / 2) - paddingAdjustment; } function show(oldValue, newValue) { var oldIdx = oldValue.value; var newIdx = newValue.value; var goingLeft = oldIdx > newIdx; var goingRight = oldIdx < newIdx; var goingLeftAround = newValue.direction === "prev" && goingRight; var goingRightAround = newValue.direction === "next" && goingLeft; // Move if(!isPosVisible(newIdx)) { if(goingRight) { if(goingLeftAround) { moveBackRight(); } else { moveRight(newIdx); } } else { if(goingRightAround) { moveBackLeft(); } else { moveLeft(newIdx); } } } // Highlight elements[oldIdx].removeClass(selectedClass); elements[newIdx].addClass(selectedClass); } function isPosVisible(idx) { var thumbStart = idx * thumbnailWidth; var thumbEnd = thumbStart + thumbnailWidth; var start = (containerMoved * thumbnailWidth) + (modAdded * modWidth()); var end = start + visibleWidth(); return start <= thumbStart && thumbEnd <= end; } function moveRight(newIdx) { var firstMove = containerMoved === 0 && modAdded === 0; var lastMove = newIdx === elements.length - 1; if(lastMove) { modAdded = 2; } else if(firstMove) { modAdded = 1; } else { containerMoved++; } move(containerMoved, modAdded); } function moveLeft(newIdx) { var firstMove = containerMoved === maxMovement() && modAdded === 2; var lastMove = newIdx === 0; if(lastMove) { modAdded = 0; } else if(firstMove) { modAdded = 1; } else { containerMoved--; } move(containerMoved, modAdded); } function moveBackLeft() { modAdded = 0; containerMoved = 0; move(containerMoved, modAdded); } function moveBackRight() { modAdded = 2; containerMoved = maxMovement(); move(containerMoved, modAdded); } function move(wholeMoves, partialMoves) { thumbnailContainer.transition({ x: (-1 * ((wholeMoves * thumbnailWidth) + (partialMoves * modWidth())) ) }); } // Prev/Next events var prevIdxStream = prevBus.map(function() { return {value: null, fn: prevId, direction: "prev"}; }); var nextIdxStream = nextBus.map(function() { return {value: null, fn: nextId, direction: "next"}; }); var showIdxStream = clickS.map(function(newIdx) { return {value: newIdx }; }); var idxStream = prevIdxStream.merge(nextIdxStream).merge(showIdxStream).scan({value: initialIdx}, function(a, b) { var newIdx = b.value != null ? b.value : b.fn(a.value); return {direction: b.direction, value: newIdx}; }).skipDuplicates(_.isEqual).slidingWindow(2, 2); idxStream.onValues(show); return { next: function(nextStream) { nextBus.plug(nextStream.debounceImmediate(swipeDelay)); }, prev: function(prevStream) { prevBus.plug(prevStream.debounceImmediate(swipeDelay)); }, show: clickS }; };