define(['jquery', 'internal/sitebuilder/common/ModuleClassLoader', 'underscore', 'backbone', 'site/deckInspectah/DeckInspectahView', 'site/modules/photo_gallery/PhotoGalleryDeckInspectahImageView', 'site/modules/photo_gallery/PhotoGalleryDeckInspectahSidebarView'], function($, ModuleClassLoader, _, Backbone, DeckInspectahView, PhotoGalleryDeckInspectahImageView, PhotoGalleryDeckInspectahSidebarView) { var module = {}, extend = {}; // SubModules // Module Styles extend.styles = {"base":{"global":{"css":"view.less"},"slug":"base"}}; if (!extend.styles['base']['global']) { extend.styles['base']['global'] = {}; } extend.styles['base']['global']['js'] = null; extend.defaultStyle = extend.styles['base']; // View JS $.extend(module, { VIEW_TYPE: { 'GRID': 'grid', 'SLIDESHOW': 'slideshow' }, /** * Init function */ oneLoaded: function () { var self = this; if(self.data.viewType == self.VIEW_TYPE.SLIDESHOW) { self._oneLoadedSlideShow(); } else { self._oneLoadedGrid(); } }, _oneLoadedGrid: function () { var self = this; // if we haven't already included the deckInspectah css, do so now, and set a global variable so we don't try to include it again if (!webs.deckInspectah) { try { $("head").append(''); webs.deckInspectah = true; } catch (ex) { webs.log.error("Unable to setup Deck Inspectah", this.data, ex); } } this.el.on('click', '.ellip-anchor, .deck-inspectah-link', function (evt) { evt.preventDefault(); var gridSettings = self.data.settings.grid; var isEllipAnchor = $(evt.target).hasClass('ellip-anchor'); var closestCell = $(this).closest('.cell'); var isMobile = closestCell.hasClass('mobile-image'); var image = closestCell.data('_i_'); var titleEnabled = (!isMobile) && (isEllipAnchor || gridSettings.showTitle === 'lightbox' || gridSettings.showTitle == 'both'); var captionEnabled = (!isMobile) && (isEllipAnchor || gridSettings.showCaption === 'lightbox' || gridSettings.showCaption == 'both'); var deckInspectahView = new DeckInspectahView({ model: new Backbone.Collection(self.data.images), selectedImage: image, imageViewClass: PhotoGalleryDeckInspectahImageView, sidebarViewClass: PhotoGalleryDeckInspectahSidebarView, titleEnabled: titleEnabled, captionEnabled: captionEnabled }); $('body').append(deckInspectahView.el); deckInspectahView.show(); }); var overlayEllipsis = _.bind(this._overlayEllipsis, this); try { if (top && top.dsnr) { top.require(['internal/sitebuilder/designerChrome/dsnrLoader'], function (dsnrLoader) { dsnrLoader.sitePreview.bind('iframeRestyled', overlayEllipsis) }); } } catch (e) { // No designer - we can safely ignore } // always call the deferred, in case we are not on a designer frame _.defer(overlayEllipsis); }, _oneLoadedSlideShow: function () { var self = this; var duration = self.data.settings.slideshow.duration; var autoplay = parseInt(duration, 10) != 0; if (autoplay && self.data.images.length > 1) { this.autoplay(duration); } this.el.on('click', '.ellip-anchor, .deck-inspectah-link', function (evt) { evt.preventDefault(); var gridSettings = self.data.settings.grid; var isEllipAnchor = $(evt.target).hasClass('ellip-anchor'); var closestCell = $(this).closest('.slide'); var isMobile = closestCell.hasClass('mobile-image'); var image = closestCell.data('_i_'); var titleEnabled = (!isMobile); var captionEnabled = (!isMobile); var deckInspectahView = new DeckInspectahView({ model: new Backbone.Collection(self.data.images), selectedImage: image, imageViewClass: PhotoGalleryDeckInspectahImageView, sidebarViewClass: PhotoGalleryDeckInspectahSidebarView, titleEnabled: titleEnabled, captionEnabled: captionEnabled }); $('body').append(deckInspectahView.el); deckInspectahView.show(); }); var overlayEllipsis = _.bind(this._overlayEllipsis, this); try { if (top && top.dsnr) { top.require(['internal/sitebuilder/designerChrome/dsnrLoader'], function (dsnrLoader) { dsnrLoader.sitePreview.bind('iframeRestyled', overlayEllipsis) }); } } catch (e) { // No designer - we can safely ignore } // always call the deferred, in case we are not on a designer frame _.defer(overlayEllipsis); this.el.on('click', '.thumbnail', _.bind(self.thumbnailClick, self)); this.el.on('mouseenter', '.w-slideshow-thumbnail-button', _.bind(self.thumbnailScroll, self)); this.el.on('mouseleave', '.w-slideshow-thumbnail-button', _.bind(self.stopThumbnailScroll, self)); //set the selected slide to the first one for (var i = 0; i < self.data.images.length; i++) { self.el.find(".webs-gallery-grid-title-caption-social-box[data-_i_=" + i + "]").removeClass("slide-selected"); self.el.find(".slide-wrapper[data-_i_=" + i + "]").removeClass("slide-selected"); self.el.find(".thumbnail[data-_i_=" + i + "]").removeClass("slide-selected"); self.data.images[i].selected = false; } self.el.find(".webs-gallery-grid-title-caption-social-box[data-_i_=0]").addClass("slide-selected"); self.el.find(".slide-wrapper[data-_i_=0]").addClass("slide-selected"); self.el.find(".thumbnail[data-_i_=0]").addClass("slide-selected"); self.data.images[0].selected = true; this.setupSlideshow(); }, _overlayEllipsis: function () { var self = this; // ignore elements that aren't showing title & caption if (this.$('.ellip-content')[0]) { var parents = self.$('.ellip-content').eq(0).parents(); var bgColor = _.reduce(parents.toArray().reverse(), function (left, el) { var rgba = $(el).css('background-color').match(/[\d\.]+/g); // handle no background - webkit returns 0,0,0,0, gecko returns null if (rgba && rgba.length < 4) { //if there are only 1 (IE) or 3 (webkit/gecko) colors, then it's fully opaque return rgba; } else if (rgba && rgba[3] != 0) { // ignore transparent backgrounds, otherwise do alpha blending return _.map(rgba, function (val, key, rgba) { return key === 3 ? 1 : Math.round(rgba[3] * val + (1 - rgba[3]) * left[key]); }); } else { // transparent, return the previous background return left; } }, [255, 255, 255, 0]); // start with a white background bgColor[3] = bgColor[3] || 1; var rgbaStr = 'rgba(' + bgColor.toString() + ')'; var rgb = bgColor.slice(0, 3).toString(); // not creating rgbString as we need both rgba(x,x,x,0) and rgb(x,x,x) this.$('.ellipsis').css('background-image', 'linear-gradient(to right, rgba(' + rgb + ',0), ' + rgbaStr + ' 50%, ' + rgbaStr + ')'); this.$('.ellip-anchor').css('background-color', 'rgb(' + rgb + ')'); } }, autoplay: function (duration) { var self = this; setInterval(function () { self.nextSlide(); }, duration); }, setupSlideshow: function () { this.isMobile = this.el.find(".w-photo_gallery_slideshow-mobile").length; this.isEditMode = this.el.find(".moveable").length; this.data.currentSlide = 0; for (var i = 0; i < this.data.images.length; i++) { if (this.data.images[i].selected) { this.data.currentSlide = i; } } var self = this; this.el.on('mousedown', '.right-button', function (e) { self.nextSlide(e); }); this.el.on('mousedown', '.left-button', function (e) { self.prevSlide(e); }); if (this.isMobile) { this.mobileSetup(this); } this.duration = parseInt(this.data.settings.slideshow.duration, 10); if (this.duration && this.data.images.length > 1 && !this.isEditMode) { this.isAutoplaying = true; if (this.isMobile) { this.$progress = this.el.find(".progress-timer"); } this.playSlide(); } }, mobileSetup: function (context) { var self = this; this.setMobileSlideHeight(context); this.data.settings.slideshow.duration = 3000; //var $container = this.el.find(".slide-container"); this.el.on("touchmove mousemove", function (e) { e.stopPropagation(); }); this.el.on("dragstart", function (e) { e.preventDefault(); }); this.el.on("mousedown", function (e) { var ref = arguments.callee, handle = $(this), start = e.pageX; handle.off("mousedown", ref); handle.on("mouseup", function(e){ handle.off("mouseup", arguments.callee); handle.on("mousedown", ref); var end = e.pageX; if(Math.abs(end - start) > 30){ handle.trigger((end > start) ? "swiperight" : "swipeleft"); }; }); }); this.el.on("swiperight", function() { self.prevSlide(); }); this.el.on("swipeleft", function() { self.nextSlide(); }); }, setMobileSlideHeight: function (context) { var $container = this.el.find(".w-photo_gallery_slideshow-mobile").find(".slide-container"), $imgs = $container.find('img'); _.each($imgs, function (img) { var loading = new Image(); loading.onload = function() { setTimeout(function() { $container.css("height", loading.height); }, 0); }; loading.src = img.src; }); }, playSlide: function () { var self = this; if (this.isMobile) { setTimeout(function () { self.$progress.addClass("move"); }, 0); } this.timeout = setTimeout(function () { if (self.isMobile) { self.$progress.removeClass("move"); } self.nextSlide(); }, self.duration); }, nextSlide: function () { if (this.data.images && this.data.images.length > 1) { var prev = this.data.currentSlide; var next = this.data.currentSlide + 1; if (next == this.data.images.length) { next = 0; } this.selectSlide(prev, next); } }, prevSlide: function () { if (this.data.images && this.data.images.length > 1) { var prev = this.data.currentSlide; var next = this.data.currentSlide - 1; if (next == -1) { next = this.data.images.length - 1; } this.selectSlide(prev, next); } }, selectSlide: function (prev, next) { if (!this.thumbnailScrollIntervalRef) { if (this.isAutoplaying) { clearTimeout(this.timeout); if (this.isMobile) { this.$progress.removeClass("move"); } this.playSlide(); } var prevSlide = this.el.find(".slide-wrapper[data-_i_=" + prev + "]"); var nextSlide = this.el.find(".slide-wrapper[data-_i_=" + next + "]"); var transitionStyle = this.data.settings.slideshow.transition; this.el.find(".slide-wrapper").removeClass("scalein scaleout incomingright outgoingleft incomingleft outgoingright"); if (transitionStyle == "carouselHorizontal" || transitionStyle == "vertical"){ if (next == 0 && prev == (this.data.images.length - 1)){ nextSlide.addClass("incomingright"); prevSlide.addClass("outgoingleft"); } else if (prev == 0 && next == (this.data.images.length - 1)){ nextSlide.addClass("incomingleft"); prevSlide.addClass("outgoingright"); } else if (prev < next){ nextSlide.addClass("incomingright"); prevSlide.addClass("outgoingleft"); } else { nextSlide.addClass("incomingleft"); prevSlide.addClass("outgoingright"); } } else if (transitionStyle == "scale"){ nextSlide.addClass("scalein"); prevSlide.addClass("scaleout"); } this.data.images[prev].selected = false; prevSlide.removeClass("slide-selected"); nextSlide.addClass("slide-selected"); this.el.find(".webs-gallery-grid-title-caption-social-box[data-_i_=" + prev + "]").removeClass("slide-selected"); this.el.find(".webs-gallery-grid-title-caption-social-box[data-_i_=" + next + "]").addClass("slide-selected"); this.data.currentSlide = next; this.data.images[next].selected = true; if (!this.isMobile) { this.adjustThumbnail(prev, next); } } }, adjustThumbnail: function (prev, next) { var self = this; var horizontalScroll = self.el.find('.w-slideshow-thumbnail-area').hasClass("thumbnail-horizontal"); var thumbnailsContainer = self.el.find('.w-slideshow-thumbnails-ul'); var thumbnailContainerWidth = thumbnailsContainer.height(); var thumbnailsAreaWidth = self.el.find('.w-slideshow-thumbnails').height(); if (horizontalScroll) { thumbnailsAreaWidth = self.el.find('.w-slideshow-thumbnails').width(); thumbnailContainerWidth = thumbnailsContainer.width(); } var oldThumbnail = self.el.find(".thumbnail[data-_i_=" + prev + "]"); var newThumbnail = self.el.find(".thumbnail[data-_i_=" + next + "]"); oldThumbnail.removeClass("slide-selected"); newThumbnail.addClass("slide-selected"); if (thumbnailContainerWidth > thumbnailsAreaWidth) { var thumbnailWidth = parseInt(newThumbnail.height(), 10); var left = parseInt(newThumbnail.position().top, 10); if (horizontalScroll) { left = parseInt(newThumbnail.position().left, 10); thumbnailWidth = parseInt(newThumbnail.width(), 10); } var right = left + thumbnailWidth; var jump = (((prev === 0) && (this.data.images.length - 1 === next)) || ((prev === this.data.images.length - 1) && (0 === next))); if (!self.windowLeft) { self.windowLeft = self.data.currentPosition; self.windowRight = self.windowLeft + thumbnailsAreaWidth; } } if ((right > self.windowRight) || (left < self.windowLeft)) { if (right > self.windowRight) { scrolling(true, 10, thumbnailContainerWidth - thumbnailsAreaWidth, thumbnailContainerWidth); } else if (left < self.windowLeft) { scrolling(false, -10, 0, thumbnailsAreaWidth); } } function scrolling(goRight, scrollingSpeed, winLef, winRig) { self.thumbnailScrollIntervalRef = setInterval(function () { thumbnailsContainer = self.el.find('.w-slideshow-thumbnails-ul'); var checkCondition = (right > self.windowRight); if (!goRight) { checkCondition = (left < self.windowLeft); } if (checkCondition) { if (jump) { // disable scroll for long jump self.windowRight = winRig; self.windowLeft = winLef; self.data.currentPosition = -self.windowLeft; } else { self.windowLeft += scrollingSpeed; self.windowRight += scrollingSpeed; self.data.currentPosition -= scrollingSpeed; } if (horizontalScroll) { thumbnailsContainer.css('left', self.data.currentPosition); } else { thumbnailsContainer.css('top', self.data.currentPosition); } } else { clearInterval(self.thumbnailScrollIntervalRef); self.thumbnailScrollIntervalRef = false; } }, 16); } }, thumbnailClick: function (evt) { var targetDiv = $(evt.target); var prev = targetDiv.parents().siblings('.thumbnail.slide-selected').data('_i_'); var next = targetDiv.parents('.thumbnail').data('_i_'); if (typeof prev !== 'undefined' && prev != next){ this.selectSlide(prev, next); } }, thumbnailScroll: function (evt) { if (!this.thumbnailScrollIntervalRef) { var self = this; var targetDiv = $(evt.target); var horizontalScroll = targetDiv.hasClass("thumbnail-horizontal"); var thumbnailsContainer = targetDiv.parents('.w-slideshow-thumbnails').find('.w-slideshow-thumbnails-ul'); var thumbnailsAreaWidth = targetDiv.parents('.w-slideshow-thumbnails').height(); var thumbnailContainerWidth = thumbnailsContainer.height(); if (horizontalScroll) { thumbnailsAreaWidth = targetDiv.parents('.w-slideshow-thumbnails').width(); thumbnailContainerWidth = thumbnailsContainer.width(); } if (thumbnailContainerWidth > thumbnailsAreaWidth) { if (!self.windowLeft) { self.windowLeft = self.data.currentPosition; self.windowRight = self.windowLeft + thumbnailsAreaWidth; } if (targetDiv.hasClass('w-slideshow-thumbnail-button-next')) { scrolling(true, 5); } else if ((targetDiv.hasClass('w-slideshow-thumbnail-button-prev'))) { scrolling(false, -5); } } } function scrolling(next, scrollingSpeed) { self.thumbnailScrollIntervalRef = setInterval(function () { var checkCondition = (self.data.currentPosition < 0); if (next) { checkCondition = ((thumbnailContainerWidth - thumbnailsAreaWidth + self.data.currentPosition) > 0); } if (checkCondition) { self.windowLeft += scrollingSpeed; self.windowRight += scrollingSpeed; self.data.currentPosition -= scrollingSpeed; if (self.data.currentPosition > 0) { self.data.currentPosition = 0; } else if (self.data.currentPosition < -thumbnailContainerWidth) { self.data.currentPosition = -thumbnailContainerWidth; } if (horizontalScroll) { thumbnailsContainer.css('left', self.data.currentPosition); } else { thumbnailsContainer.css('top', self.data.currentPosition); } } else { clearInterval(self.thumbnailScrollIntervalRef); self.thumbnailScrollIntervalRef = false; } }, 16); } }, stopThumbnailScroll: function (evt) { if (this.thumbnailScrollIntervalRef) { clearInterval(this.thumbnailScrollIntervalRef); this.thumbnailScrollIntervalRef = false; } } }); return ModuleClassLoader.register('photo_gallery', module, extend); });