Skip to content

Instantly share code, notes, and snippets.

@maolion
Created December 8, 2014 12:49
Show Gist options
  • Select an option

  • Save maolion/bdbe237c5e7ee85b4ab5 to your computer and use it in GitHub Desktop.

Select an option

Save maolion/bdbe237c5e7ee85b4ab5 to your computer and use it in GitHub Desktop.
/***
* AKD.EC
* ----------------------------------------------------------------------------
* <Slider.js> - 2014/5/9
* @version 0.1
* @author Joye, maolion.j@gmail.com
* @website http://maolion.com
*/
var
SLICE = Array.prototype.slice,
Utils = require("Utils.js"),
Event = require("Event.js"),
EMPTY = {},
DEF_CONFIG = {
duration : 400,
direction : 1,
ease : "easeInOutCubic",
interval : 0,
pageSize : 1,
pageButton : function(page) {
return '<li>'+page+'</li>';
},
buttonEvent : "click"
},
FADE_ANIMATE = {
opacity : 1
}
;
function Slider(slider, config)
{
var _this = this;
if (!(this instanceof Slider) || this.constructor === Slider) {
return new Slider[config && config.effect || "ScrollX"](slider, config);
}
slider.show();
this._items = slider.children();
this._config = config = jQuery.extend(
{
width : this._items.outerWidth(),
height : this._items.outerHeight()
},
DEF_CONFIG,
config || EMPTY
);
Event.call(this);
Utils.Animate.call(this, slider, config.duration, config.ease);
var count = this._items.length;
this._slider = slider;
this._active = 1;
this._pageCount = ~~(count / config.pageSize) + (count % config.pageSize ? 1 : 0);
this._pageButton = config.pageButton;
this._itemWidth = config.width;
this._itemHeight = config.height;
this._auto_timer = null;
this._auto_play = false;
this._count = this._pageCount * this._config.pageSize;
this._offset = 0;
//this._direction = ~~config.direction > 0 ? 1 : -1;
if (config.pageButton instanceof Function) {
var html = '';
for (var i = 0, l = this._pageCount; i < l; i++) {
html += config.pageButton(i+1);
}
var wrap = jQuery('<ul class="slider-navigate">'+html+'</ul>');
slider.after(wrap);
this._pageButton = wrap.children();
}
if (this._pageButton instanceof jQuery) {
this._pageButton.on(this._config.buttonEvent, function()
{
_this.switchTo(jQuery(this).index() + 1);
});
}
if (~~config.direction < 0) {
var swap = this.prev;
this.prev = this.next;
this.next = swap;
}
config.interval && autoPlay.call(this);
};
var sliderApi = Slider.prototype = Utils.create(Event.prototype, Slider);
sliderApi.switchTo = function(page)
{
page = Math.min(Math.max(~~page, 1), this._pageCount);
var prev = this._active;
this._active = page;
this._items.removeClass("active");
this.getActive().addClass("active");
if (this._pageButton) {
this._pageButton.removeClass("active");
this._pageButton.eq(page-1).addClass("active");
}
this.fireEvent("switch", [page, prev]);
if (!this._from_auto_paly && this._auto_play && this._auto_timer) {
this.play();
}
};
sliderApi.next = function()
{
this.switchTo(this._active+1 > this._pageCount ? 1 : this._active + 1);
};
sliderApi.prev = function()
{
this.switchTo(this._active-1 < 1 ? this._pageCount : this._active - 1);
};
sliderApi.getActive = function(page) {
page = Math.min(Math.max(~~page||this._active, 1), this._pageCount);
var start = (page-1) * this._config.pageSize;
return this._items.slice(start, start + this._config.pageSize);
};
sliderApi.getPage = function()
{
return this._active;
};
sliderApi.getItems = function()
{
return this._items;
};
sliderApi.pageButton = function()
{
return this._pageButton;
};
sliderApi.getSlider = function()
{
return this._slider;
};
sliderApi.play = function()
{
var _this = this;
if (!this._auto_play) return;
this.fireEvent("play");
clearInterval(this._auto_timer);
this._auto_timer = setInterval(function()
{
_this._from_auto_paly = true;
_this.next();
_this._from_auto_paly = false;
}, this._config.interval);
};
sliderApi.stop = function()
{
if (!this._auto_timer) return;
this.fireEvent("stop");
clearInterval(this._auto_timer);
this._auto_timer = null;
};
function autoPlay()
{
var _this = this;
this._auto_play = true;
this._slider.hover(
function()
{
_this._auto_play = false;
_this.stop();
},
function()
{
_this._auto_play = true;
_this.play();
}
);
this.play();
}
/*SliderScroll*/
function SliderScroll(slider, prop, config)
{
Slider.call(this, slider, config);
this._scrollProp= prop;
this._step = this[prop==="marginLeft" ? "_itemWidth":"_itemHeight"] * this._config.pageSize;
this._startPos = 0;
this._endPos = -(this._pageCount - 1) * this._step;
if (this._items.length < this._count) {
var clone = this._items.slice(0, this._count - this._items.length).clone(true);
slider.append(clone);
this._items.push.apply(this._items, SLICE.call(clone));
}
}
var sliderScrollApi = SliderScroll.prototype = Utils.create(Slider.prototype, SliderScroll);
sliderScrollApi.switchTo = function(page, done)
{
sliderApi.switchTo.call(this, page);
page = this._active;
var animate = {};
animate[this._scrollProp] = -((page-1 + this._offset) * this._step);
this.nextAnimate(this._slider, animate, done);
};
sliderScrollApi.prev = function()
{
if (this._active === 1) {
var
_this = this,
slider = this._slider,
firstItems = this.getActive()
;
slider.css(this._scrollProp, this._endPos );
slider.append(firstItems);
this._offset = -1;
this.switchTo(this._pageCount, function()
{
_this._offset = 0;
slider.css(_this._scrollProp, _this._endPos);
firstItems.insertBefore(slider.children()[0]);
});
} else {
this.switchTo(this._active-1);
}
};
sliderScrollApi.next = function()
{
if (this._active === this._pageCount) {
var
_this = this,
slider = this._slider,
lastItems = this.getActive()
;
slider.css(this._scrollProp, this._startPos);
lastItems.insertBefore(this._items[0]);
this._offset = 1;
this.switchTo(1, function()
{
_this._offset = 0;
slider.css(_this._scrollProp, _this._startPos);
slider.append(lastItems);
});
} else {
this.switchTo(this._active+1);
}
};
/*Slider.ScrollX [Effect]*/
Slider.ScrollX = function SliderScrollX(slider, config)
{
SliderScroll.call(this,slider, "marginLeft", config);
this._items.css("float", "left");
slider.css({
width : this._itemWidth * this._count,
height : this._itemHeight,
marginLeft : 0
});
if (~~this._config.direction < 0) {
slider.css("marginLeft", this._endPos);
this._active = this._pageCount;
this.switchTo(this._pageCount);
} else {
this.switchTo(1);
}
};
var sliderXApi = Slider.ScrollX.prototype = Utils.create(SliderScroll.prototype, Slider.ScrollX);
/*Slider.ScrollY [Effect]*/
Slider.ScrollY = function SliderScrollY(slider, config)
{
SliderScroll.call(this,slider, "marginTop", config);
slider.css({
width : this._itemWidth,
height : this._itemHeight * this._count,
marginTop : 0
});
if (~~this._config.direction < 0) {
slider.css("marginTop", this._endPos);
this._active = this._pageCount;
this.switchTo(this._pageCount);
} else {
this.switchTo(1);
}
};
var sliderYApi = Slider.ScrollY.prototype = Utils.create(SliderScroll.prototype, Slider.ScrollY);
/*Slider.Fade [Effect]*/
Slider.Fade = function SliderFade(slider, config)
{
if (config) {
config.pageSize = 1;
}
Slider.call(this, slider, config);
//Utils.Animate.call(this, this._items.eq(0), config.duration, config.ease);
slider.css({
position : "relative",
width : this._itemWidth,
height : this._itemHeight
});
this._items.css({
position : "absolute",
zIndex : "1"
});
this._z = 1;
if (~~this._config.direction < 0) {
this._items.eq(-1).css("zIndex", ++this._z);
this._active = this._pageCount;
this.switchTo(this._pageCount);
} else {
this._items.eq(0).css("zIndex", ++this._z);
this.switchTo(1);
}
};
var sliderFadeApi = Slider.Fade.prototype = Utils.create(Slider.prototype, Slider.Fade);
sliderFadeApi.switchTo = function(page, done)
{
var prev = this._active;
sliderApi.switchTo.call(this, page);
page = this._active;
if (prev === page) return;
var item = this._items.eq(page-1);
item.css({
zIndex : ++this._z,
opacity : 0
});
this.nextAnimate(item, FADE_ANIMATE, done);
}
module.exports = Slider;
//DEFAULT EASE
jQuery.easing.easeInOutCubic = function (x, t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t*t + b;
return c/2*((t-=2)*t*t + 2) + b;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment