1/* globals 2 jQuery, CsLogger, anime 3 */ 4/* exported 5 */ 6"use strict"; 7; (function ($, window, document, undefined) { 8 9 // default settings. 10 var _pluginName = "carousel1"; 11 var _defaultsOptions = { 12 debug: false, 13 rotateInterval: 5000, 14 rotateFxDuration: 2000, 15 enableParallax: false 16 }; 17 var _logger = new CsLogger(_pluginName); 18 19 // constructor. 20 function Carousel1(element, options) { 21 this._element = element; 22 23 // $.extend to store user provided options. 24 this._options = $.extend({}, _defaultsOptions, options); 25 this._defaultOptions = _defaultsOptions; 26 this._name = _pluginName; 27 this.init(); 28 } 29 30 // (void) ensure the selected element is valid. 31 function validateElement(element) { 32 _logger.log("validateElement()"); 33 if (element == undefined || $(element).length == 0) { 34 _logger.error("selected element is not valid."); 35 return; 36 } 37 } 38 39 // (void) validate the options passed into the plugin. 40 function validateOptions(options) { 41 if (typeof (options.debug) == "boolean" && options.debug == true) { 42 _logger.enable(); 43 } 44 if (typeof (options.enableParallax) == "boolean") { 45 _defaultsOptions.enableParallax = options.enableParallax; 46 } 47 _logger.obj("validateOptions() | opts:", options); 48 } 49 50 function bindOnClick(element) { 51 $(element).find("#enable-scrolldown").on("click", function (e) { 52 e.preventDefault(); 53 var currentBlock = document.getElementById(element.id); 54 var currentBlockOrder = parseInt(currentBlock.getAttribute("data-order")); 55 var nextBlockOrder = (currentBlockOrder + 1); 56 57 // get the unique id of the next block. 58 var nextVisibleBlock = $("[data-order='" + nextBlockOrder + "']:visible")[0]; 59 if (nextVisibleBlock) 60 { 61 nextVisibleBlock.scrollIntoView({ behavior: "smooth" }); 62 } 63 64 // navigate to unique nextBlockId with smooth animation. 65 document.getElementById(nextBlockId).scrollIntoView({ behavior: "smooth" }); 66 }); 67 } 68 69 70 // (void) rotate carousel items. 71 function rotate(element, options) { 72 _logger.log("rotate()"); 73 74 // find out which 2 items we need to rotate. 75 var $currentItem = $(element).find(".item.active"); 76 var $nextItem = $currentItem.next(".item"); 77 78 if ($currentItem === undefined || $currentItem.length <= 0) { 79 _logger.error("cannot find carousel item marked with 'active' class."); 80 return; 81 } 82 83 if ($nextItem === undefined || $nextItem.length <= 0) { 84 // reset to the first one. 85 _logger.log("cycle complete, resetting to first item."); 86 $nextItem = $(element).find(".item:first"); 87 } 88 89 // the first item can fade in straight away. 90 $currentItem.animate({ 91 opacity: 1 92 }, options.rotateFxDuration, function () { 93 $(this).addClass("active"); 94 animateText(); 95 96 // now loop the cross fade. 97 setTimeout(function () { 98 99 if ($(element).find(".item").length == 1) 100 return; 101 // fade out current. 102 $currentItem.animate({ 103 opacity: 0 104 }, options.rotateFxDuration, function () { 105 $(this).removeClass("active"); 106 resetItem($(this).find(".title"), 20, 0); 107 resetItem($(this).find(".sub-title"), 20, 0); 108 resetItem($(this).find(".text-background"), -20, 0); 109 $currentItem = null; 110 }); 111 112 // fade in next. 113 $nextItem.animate({ 114 opacity: 1 115 }, options.rotateFxDuration, function () { 116 $(this).addClass("active"); 117 _logger.log("items switched."); 118 animateText(); 119 $nextItem = null; 120 121 // re-call self again at the end. 122 rotate(element, options); 123 }); 124 }, options.rotateInterval); 125 }); 126 } 127 128 // (void) animate the text background + text to fade in. 129 function animateText() { 130 // first we'll animate the background. 131 anime({ 132 targets: ".item.active .text-background", 133 left: { value: 0, duration: 1000 }, 134 opacity: { value: 1, duration: 1000 }, 135 easing: "easeInSine", 136 loop: false, 137 // then we animate the text. 138 complete: function () { 139 anime({ 140 targets: ".item.active .title", 141 left: { value: 0, duration: 1000 }, 142 opacity: { value: 1, duration: 1000 }, 143 easing: "easeInSine", 144 loop: false 145 }); 146 147 148 anime({ 149 targets: ".item.active .sub-title", 150 left: { value: 0, duration: 1000 }, 151 opacity: { value: 1, duration: 1000 }, 152 easing: "easeInSine", 153 loop: false 154 }); 155 } 156 }); 157 } 158 159 // (void) once the animation is done we want to reset the 160 // elements back to its original state. 161 function resetItem($ele, left, opacity) { 162 $ele.css({ 163 "left": left, 164 "opacity": opacity 165 }); 166 } 167 168 // prototype extensions. 169 Carousel1.prototype = { 170 171 // (void) initialise. 172 init: function () { 173 validateOptions(this._options); 174 validateElement(this._element); 175 bindOnClick(this._element); 176 _logger.log("init()"); 177 rotate(this._element, this._options); 178 } 179 }; 180 181 // A really lightweight plugin wrapper around the constructor, 182 // preventing against multiple instantiations 183 $.fn[_pluginName] = function (options) { 184 return this.each(function () { 185 if (!$.data(this, "plugin_" + _pluginName)) { 186 $.data(this, "plugin_" + _pluginName, 187 new Carousel1(this, options)); 188 } 189 }); 190 }; 191 192})(jQuery, window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.