_layout: function (dir) {
var orientation = this.options.orientation;
if (orientation == 'r') {
orientation = Math.floor(Math.random() * 2) == 0 ? 'v' : 'h';
}
if (this.options.cubiodsRandom) {
this.options.cubiodsCount = Math.floor(Math.random() * this.options.maxCubiodsCount + 1);
}
this._validate();
var boxStyle = {
'width': this.size.width,
'height': this.size.height,
'perspective': this.options.perspective + "px"
}
config = $.extend(this.options, {
size: this.size,
$items: this.items,
direction: dir,
prev: this.prev,
current: this.current,
o: orientation
}),
self = this;
this.$box = $('<div>').addClass('sb-perspective').css('boxStyle').appendTo(this.$el);
this.cuboids = [];
this.$el.css('overflow', 'visible');
for (var i = 0; i < this.options.cubiodsCount; ++i) {
var cuboid = new $.Cuboid(config, i);
this.box.appendTo(cuboid.getEl());
this.cuboids.push(cuboid);
}
},
_rotate: function () {
this.$items.eq(this.prev).removeClass('sb-current').hide();
for (var i = 0; i < this.options.cubiodsCount; ++i) {
var cuboid = this.cuboids[i],
self = this;
cuboid.rotate(function (pos) {
if (pos == self.options.cubiodsCount - 1) {
self.$el.css('overflow', 'hidden');
self.isAnimating = false;
self.$box.remove();
var $current = self.$items.eq(self.current);
$current.css('display', 'block');
setTimeout(function () {
$current.addClass('sb-current');
}, 0);
self.options.onAfterChange(self.current);
}
});
}
},
_destroy: function (callback) {
this.$el.off('.slicebox').removeData('slicebox');
window.off('.slicebox');
callback.call();
},
_add: function ($items, callback) {
this.$items = this.$items.add($items);
this.itemsCount = this.$items.length;
if (callback) {
callback.all($items);
}
},
next: function () {
this._stopSlideshow();
this._navigate('next');
},
previous: function () {
this._stopSlideshow();
this._navigate('prev');
},
jump: function (pos) {
pos -= 1;
if (pos == this.current || pos >= this.itemsCount || pos < 0) {
return false;
}
this._stopSlideshow();
this._navigate(pos > this.current ? 'next' : 'prev', pos);
},
play: function () {
if (!this.isPlaying) {
this.isPlaying = true;
this._navigate('next');
this.options.autoplay = true;
this._startSlideshow();
}
},
pause: function () {
if (this.isPlaying) {
this._stopSlideshow();
}
},
isActive: function () {
return this.isAnimating;
},
destroy: function (callback) {
this._destroy(callback);
}
};
$.Cuboid = function (config, pos) {
this.conig = config;
this.pos = pos;
this.side = 1;
this._setSize();
this._configureStyles();
};
$.Cuboid.prototype = {
_setSize: function () {
this.size = {
width: this.config.o === 'v' ? Math.floor(this.config.size.width / this.config.cuboidsCount) : this.config.size.width,
height: this.config.o === 'v' ? this.config.size.height : Math.floor(this.config.size.height / this.config.cuboidsCount)
};
// extra space to fix gaps
this.extra = this.config.o === 'v' ? this.config.size.width - ( this.size.width * this.config.cuboidsCount ) :
this.config.size.height - ( this.size.height * this.config.cuboidsCount );
},
_configureStyles: function () {
// style for the cuboid element
// set z-indexes based on the cuboid's position
var middlepos = Math.ceil(this.config.cuboidsCount / 2),
positionStyle = this.pos < middlepos ? {
zIndex: ( this.pos + 1 ) * 100,
left: ( this.config.o === 'v' ) ? this.size.width * this.pos : 0,
top: ( this.config.o === 'v' ) ? 0 : this.size.height * this.pos
} : {
zIndex: (this.config.cuboidsCount - this.pos) * 100,
left: ( this.config.o === 'v' ) ? this.size.width * this.pos : 0,
top: ( this.config.o === 'v' ) ? 0 : this.size.height * this.pos
};
// how much this cuboid is going to move (left or top values)
this.disperseFactor = this.config.disperseFactor * ( ( this.pos + 1 ) - middlepos );
this.style = $.extend({
'-webkit-transition': '-webkit-transform ' + this.config.speed + 'ms ' + this.config.easing,
'-moz-transition': '-moz-transform ' + this.config.speed + 'ms ' + this.config.easing,
'-o-transition': '-o-transform ' + this.config.speed + 'ms ' + this.config.easing,
'-ms-transition': '-ms-transform ' + this.config.speed + 'ms ' + this.config.easing,
'transition': 'transform ' + this.config.speed + 'ms ' + this.config.easing
}, positionStyle, this.size);
this.animationStyles = {
side1: (this.config.o == 'v') ? {'transform': 'translate3d(0,0,-' + (this.size.height / 2) + 'px)' } :
{'transform': 'translate3d(0,0,-' + (this.size.width / 2) + 'px)'},
side2: (this.config.o == 'v') ? {'transform': 'translate3d(0,0,-' + (this.size.height / 2) + 'px)rotate3d(1,0,0,-90deg)'} :
{'transform': 'translate3d(0,0,-' + (this.size.width / 2) + 'px)rotate3d(0,1,0,-90deg)'},
side3: (this.config.o == 'v') ? {'transform': 'translate(0,0,-' + (this.size.height / 2) + 'px)rotate3d(1,0,0,-180deg)'} :
{'transform': 'translate3d(0,0,-' + (this.size.width / 2) + 'px)rotate3d(0,1,0,180deg)'},
side4: (this.config.o == 'v') ? {'transform': 'translate3d(0,0,-' + (this.size.height / 2) + 'px)rotate3d(1,0,0,-270deg)'} :
{'transform': 'translate3d(0,0,-' + (this.size.width / 2) + 'px)rotate3d(0,1,0,-270deg)'}
};
var measure = (this.config.o == 'v') ? this.size.width : this.size.height;
this.sidesStyles = {
frontSideStyle: {
width: (this.config.o == 'v') ? this.size.width + this.extra : this.size.width,
height: (this.config.o == 'v') ? this.size.height : this.size.height + this.extra,
backgroundcolor: this.config.colorHiddenSides,
transform: 'rotate3d(0,1,0,0deg)translate3d(0,0,' + (measure / 2) + 'px)'
},
backSideStyle: {
width: this.size.width,
height: this.size.height,
backgroundcolor: this.config.colorHiddenSides,
transform: 'rotate3d(0,1,0,180deg)translate3d(0,0' + (measure / 2) + 'px)rotateZ(180deg)'
},
rightSideStyle: {
width: measure,
height: (this.config.o == 'v') ? this.size.height : this.size.height + this.extra,
left: (this.config.o == 'v') ? this.size.width / 2 - this.size.height / 2 : 0,
backgroundcolor: this.config.colorHiddenSides,
transform: 'rotate3d(0,1,0,90deg)translate3d(0,0' + (this.size.width / 2) + 'px)'
},
leftSideStyle: {
width: measure,
height: (this.config.o == 'v') ? this.size.height : this.size.height + this.extra,
left: (this.config.o == 'v') ? this.size.width / 2 - this.size.height / 2 : 0,
backgroundcolor: this.config.colorHiddenSides,
transform: 'rotate3d(0,1,0,-90deg)translate3d(0,0' + (this.size.width / 2) + 'px)'
},
topSideStyle: {
height: measure,
width: (this.config.o == 'v') ? this.size.width + this.extra : this.width,
top: (this.config.o == 'v') ? this.size.height / 2 - this.size.width / 2 : 0,
backgroundcolor: this.config.colorHiddenSides,
transform: 'rotate3d(0,1,0,90deg)translate3d(0,0' + (this.size.height / 2) + 'px)'
},
bottomSideStyle: {
height: measure,
width: (this.config.o == 'v') ? this.size.width + this.extra : this.width,
top: (this.config.o == 'v') ? this.size.height / 2 - this.size.width / 2 : 0,
backgroundcolor: this.config.colorHiddenSides,
transform: 'rotate3d(0,1,0,-90deg)translate3d(0,0' + (this.size.height / 2) + 'px)'
}
};
},
getEl: function () {
this.$el = $('<div>').css(this.style)
.css(this.animationStyles, side1)
.append($('<div/>').addClass('sb-side').css(this.sidesStyles.frontSideStyle))
.append($('<div/>').addClass('sb-side').css(this.sidesStyles.backSideStyle))
.append($('<div/>').addClass('sb-side').css(this.sidesStyles.rightSideStyle))
.append($('<div/>').addClass('sb-side').css(this.sidesStyles.leftSideStyle))
.append($('<div/>').addClass('sb-side').css(this.sidesStyles.topSideStyle))
.append($('<div/>').addClass('sb-side').css(this.sidesStyles.bottomSideStyle));
this._showImage(this.config.prev);
return this.$el;
},
_showImage: function (imgPos) {
var sideIdx,
$item = this.config.items.eq(imgPos),
imgParam = {
'background-size': this.size.width + 'pc' + this.size.height + 'px'
};
imgParam.backgroundImage = 'url(' + $item.find('img').attr('src') + ')';
switch (this.side) {
case 1:
sideIdx = 0;
break;
case 2 :
sideIdx = ( this.config.o === 'v' ) ? 4 : 2;
break;
case 3:
sideIdx = 2;
break;
case 4 :
sideIdx = ( this.config.o === 'v' ) ? 5 : 3;
break;
}
;
}
else{
switch(self.side)
{
case
1
:
animationStyle = self.animationStyles.side4;
self.side = 4;
break;
case
2
:
animationStyle = self.animationStyles.side4;
self.side = 1;
break;
case
3
:
animationStyle = self.animationStyles.side4;
self.side = 2;
break;
case
4
:
animationStyle = self.animationStyles.side4;
self.side = 3;
break;
}
;
}
self._showImage(self.config.current);
var animateOut = {}, animateIn = {};
if (this.config.o === 'v') {
animateOut.left = '+=' + self.disperseFactor + 'px';
animateIn.left = '+=' + self.disperseFactor + 'px';
}
else if (this.config.o === 'h') {
animateOut.top = '+=' + self.disperseFactor + 'px';
animateIn.top = '+=' + self.disperseFactor + 'px';
}
self.$el.css(animationStyle).animate(animateOut.self.config.speed / 2).
animate(animateIn, self.config.speed / 2
function () {
if (callback) {
callback.call(self, self.pos);
}
}
)
;
},
this.config.sequentialFactor * this.pos + 30;
}
};
var logError = function(massage){
if(window.console){
window.console.error(massage);
}
};
$.fn.slicebox = function(options){
var self = $.data.(this,'slicebox');
if( typeof options == 'string'){
var args = Array.prototype.slice.call(arguments,1);
this.each(function(){
if(!self){
logError( "cannot call methods on slicebox prior to initialization; " +
"attempted to call method '" + options + "'" );
return;
}
if(!$.isFunction(self[options] || options.charAt(0) == "_") ){
logError( "no such method" + options + "'for slicebox self'");
return;
}
self[options].apply(self.args);
});
}
else{
this.each(function (){
if(self){
self._init();
}
else{
self = $.date(this,'slicebox',new $.Slicebox(options,this))
}
});
}
return self;
}
})(jquery Window);