/** * @fileOverview * @author: wehr * @date: 15.09.11 * * */ neo.namespace("neo.jsComponents.Homepage"); /** * Homepage components class * @class Homepage components class * @constructs * @param {Object} element Dom element representing the component container * @param {index} index the index, normally a uid referencing this component */ neo.jsComponents.Homepage = function (element, index) { //the components constructor, do magic in here! /** * @type {jQuery} */ this._$container = $(element); this._$currentItem = $([]); this._id = index; this._current = null; this._slideshowTimer = 0; this._weights = []; }; neo.jsComponents.Homepage.prototype = { _bindNavigation:function () { this._$nav.children('ul').children('li').hover(function () { $(this).children('div').fadeIn(300, "easeOutQuart"); }, function () { $(this).children('div').fadeOut(300, "easeInQuart"); }); }, _binHovering:function () { var _this = this; this._$stages.delegate('.description', 'mouseenter', function () { clearTimeout(_this._slideshowTimer); }).delegate('.description', 'mouseleave', function () { _this._slideshow(); }); }, /** * Get the next item randomly (http://stackoverflow.com/questions/1761626/weighted-random-numbers) * See this jsfiddle http://jsfiddle.net/GhLDu/1/, it works ;) * @return {*} * @private */ _getNext:function () { var weights = this._weights, i = 0, sum = 0, l, rand, resultIndex; //remove the current index, we don't want it to be choosen if (this._current !== null) { weights = this._weights.slice(0, this._current).concat(this._weights.slice(this._current+1)); } //now, get the sum of all weights for (i, l = weights.length; i < l; i += 1) { sum += weights[i].weight; } //get a random number in the sum's range rand = Math.floor(Math.random() * sum); //iterate over all elements, one by one, the sorting doesn't matter for (i = 0; i < l; i += 1) { //and look, if the random number from above is smaller than the current element's weight if (rand < weights[i].weight && weights[i].index !== this._current) { //if so, here we have our randomly selected element resultIndex = weights[i].index; //so let's get out of this loop break; } else { //if not, subtract the current element's weight from the random number and continue rand -= weights[i].weight; } } return resultIndex; }, _preload:function (index) { var _this = this; this._blocker.block(); this._$stages.eq(index).imagesLoaded(function () { _this._blocker.unblock(0); _this._showStage(index); }); }, _slideshow:function () { var _this = this; if (isNumber(this._interval)) { this._slideshowTimer = window.setTimeout(function () { _this._preload(_this._getNext()); }, this._interval + 1600); } }, _showStage:function (index) { var _this = this, $newDesc; if (index >= 0 && index < this._$stages.length) { this._current = index; this._$currentItem.children('.description').animate({ top:0 }, 450, "easeInQuart", function () { this.style.top = neo.jsComponents.Homepage.STAGE_HEIGHT + "px"; }); this._$currentItem.delay(300).fadeOut(1200); this._$currentItem = this._$stages.eq(index); $newDesc = this._$currentItem.children('.description'); $newDesc.delay(800).animate({ top:$newDesc.data("topDistance") }, 800, "easeOutQuart"); this._$currentItem.fadeIn(1600, "easeOutSine"); this._$nav.find('ul li.current').removeClass("current"); this._$stage.css({ backgroundColor:this._$currentItem.data("bgColor") }); $(this._$currentItem.data('nav')).addClass("current"); this._slideshow(); } else if (index >= this._$stages.length) { this._showStage(0); } }, /** * Loads the Homepage class */ load:function () { var _this = this, blocker, $desc; this._$nav = this._$container.children('.home-navigation'); this._$stage = this._$container.children('.home-stage'); this._$stages = this._$stage.find('.stage-item'); this._$stages.each(function (index) { var weight = parseInt(this.getAttribute("data-random-weight"), 10); if (typeof(weight)=="number" && weight+""=="NaN") { weight = 10; } _this._weights.push({ index:index, weight:weight }); }); /* Inline unit test :-p var t = ""; for (var i = 0;i<10000;i++){ var n = this._getNext(); if (n === this._current){ throw "arghh " } this._current = n; t+=","+this._current; } console.log(t);*/ this._interval = this._$stage.data("slideshowInterval") * 1000; this._blocker = new neo.ui.UiBlocker(this._$stage); this._$stages.children('.description').each(function () { $desc = $(this); $desc.data("topDistance", this.style.top).css({top:neo.jsComponents.Homepage.STAGE_HEIGHT}); }); this._preload(this._getNext()); this._bindNavigation(); this._binHovering(); }, /** * unloads the Homepage class */ unload:function () { //do something }, /** * Suspend/pause the component */ suspend:function () { }, /** * Resume the component */ resume:function () { } }; neo.jsComponents.Homepage.INITIAL_STAGE = 0; neo.jsComponents.Homepage.STAGE_HEIGHT = 544;