Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/public/js/ips.gallery_patchwork.js
Строк: 417
<?php
Element.addMethods({
patchwork: function( element, options ){
options = Object.extend({
minSize: 180,
optimumSize: 200,
gutterSize: 10,
minRowCount: 2,
maxRowCount: 5,
switchImages: true,
switchInterval: 8,
showRandomImage: true
}, options);
var boxDims = {},
curColumns = null,
curRows = null,
columnCount,
itemWidth,
grid = [],
maxBigImages,
images = [],
totalImages,
doneInit = false,
origImageData,
rowCount;
//------------------------------------
// Our kinda-constructor
//------------------------------------
var _init = function(){
// copy image data to a variable that we won't
// change
origImageData = options.imageData.clone();
totalImages = options.imageData.length;
getBoxDims();
calculateColumnsAndRows();
_createBlocks();
resizeWrapper();
doneInit = true;
},
//------------------------------------
// Creates the grid our images sit on
//------------------------------------
_createGrid = function(){
grid = [];
for( var i = 0; i < rowCount; i++ ){
grid[i] = new Array( columnCount );
}
},
//------------------------------------
// Randomly positions the larger images
//------------------------------------
_allocateLargeImages = function(){
// Position the large images
var checkGrid = function(p){
return grid[ p[0] ][ p[1] ] == null;
}
var startX = Math.floor( Math.random() * ( columnCount - 1 ) );
var startY = Math.floor( Math.random() * ( rowCount - 1 ) );
var curX = startX;
var curY = startY;
// First loop to build each large image
// Second loop for each row
// Third loop for each column
ImageLoop:
for( var i = 0; i < maxBigImages; i++ ){
for( var n = 0; n < ( rowCount - 1 ); n++ ){
for( var m = 0; m < ( grid[ n ].length - 1 ); m++ ){
// The coords this image would use if it fits
var possibleCoords = [
[ curY, curX ],
[ curY + 1, curX ],
[ curY + 1, curX + 1 ],
[ curY, curX + 1 ]
];
// Check the coords are available, insert is possible
if( possibleCoords.all( checkGrid ) ){
grid[ curY ][ curX ] = 3;
grid[ curY+1 ][ curX+1 ] = 2;
grid[ curY ][ curX+1 ] = 2;
grid[ curY+1 ][ curX ] = 2;
continue ImageLoop;
}
// subtract 2... 1 so it's zero index
// another because our image is 2 wide so we'll not bother
// checking the last column - image would never fit anyway.
if( curX++ == ( columnCount - 2 ) ){
curX = 0;
}
}
// Same as curX loop - subtract 2
if( curY++ == ( rowCount - 2 ) ){
curY = 0;
}
}
}
},
//------------------------------------
// Fills small images and inits all
//------------------------------------
_fillAndInitImages = function(){
images = [];
for( var n = 0; n < rowCount; n++ ){
for( var m = 0; m < grid[ n ].length; m++ ){
if( grid[ n ][ m ] == null ){
images.push(
new patchworkImage( {
pos: [ n, m ],
size: 'small',
image: getNextImage(),
fade: !doneInit,
variance: getRandomVariance()
} )
);
} else if( grid[ n ][ m ] == 3 ){
images.push(
new patchworkImage( {
pos: [ n, m ],
size: 'large',
image: getNextImage(),
fade: !doneInit,
variance: getRandomVariance()
} )
);
}
}
}
},
//------------------------------------
// Destroys existing images
//------------------------------------
destroyImages = function(){
images.each( function(item){
item.destroy();
delete item;
});
images = null;
},
//------------------------------------
// Calls methods in sequence that will
// build our grid and blocks
//------------------------------------
_createBlocks = function(){
maxBigImages = Math.round( Math.sqrt( rowCount * columnCount ) ) - 2;
if( maxBigImages < 1 ){ maxBigImages = 1; }
if( maxBigImages > 5 ){ maxBigImages = 5; }
Debug.write("Total images shown: " + ( rowCount * columnCount ) );
Debug.write("Max big images to show: " + maxBigImages );
_createGrid();
_allocateLargeImages();
_fillAndInitImages();
},
//------------------------------------
// Sets our wrapper dimensions variable
//------------------------------------
getBoxDims = function(){
boxDims = $( element ).getDimensions();
},
//------------------------------------
// Resizes the main wrapper to fit vertically
//------------------------------------
resizeWrapper = function(){
var height = calculateHeight( itemWidth );
$(element).setStyle({
'height': ( ( height * rowCount ) + ( options.gutterSize * ( rowCount - 1 ) ) ) + 'px'
});
},
//------------------------------------
// Calculate number and size of columns
//------------------------------------
calculateColumnsAndRows = function(){
var columns = parseInt( boxDims.width / options.optimumSize );
var leftover = boxDims.width % options.optimumSize;
// If what's left over is bigger than the minimum size,
// add an extra column. We'll resize the images.
if( leftover > options.minSize ){
columns++;
}
columnCount = columns;
// So our total item width is the box size divided by columns
itemWidth = Math.floor( ( boxDims.width - ( options.gutterSize * ( columnCount - 1 ) ) ) / columnCount );
// How many rows?
// Check whether rows * cols is more than
// the total number of images we have,
// and decrement as necessary.
var done = false;
var cur = options.maxRowCount;
do {
var c = ( cur * columnCount );
if( c < totalImages || cur == options.minRowCount ){
rowCount = cur;
done = true;
} else {
cur--;
}
} while( !done );
},
//------------------------------------
// Returns height value based on width value
//------------------------------------
calculateHeight = function( width ){
return ( width / 4 ) * 3;
},
//------------------------------------
// Returns a random image and then removes it from the array
// If we're out of elements, we repopulate and start again
//------------------------------------
getNextImage = function(){
if( options.imageData.length === 0 ){
_resetImageArray();
}
if( options.showRandomImage ){
var toreturn = options.imageData.splice( Math.floor( Math.random() * options.imageData.length ), 1 )[0];
while( typeof( toreturn ) == 'undefined' )
{
toreturn = options.imageData.splice( Math.floor( Math.random() * options.imageData.length ), 1 )[0];
}
} else {
var toreturn = options.imageData.splice( 0, 1 )[0];
}
return toreturn;
},
getRandomVariance = function(){
return ( Math.random() * options.switchInterval ).toFixed(3);
},
//------------------------------------
// resets options.imageData to its original value
//------------------------------------
_resetImageArray = function(){
options.imageData = origImageData.clone();
},
// Debug function
outputGrid = function( grid ){
for( var i = 0; i < grid.length; i++ ){
var rowOutput = '';
for( var j = 0; j < grid[i].length; j++ ){
if( grid[ i ][ j ] == 3 || grid[ i ][ j ] == 2 ){
rowOutput += "[x]";
} else if( grid[ i ][ j ] === 1 ) {
rowOutput += "[o]";
} else {
rowOutput += "[ ]";
}
}
Debug.write( rowOutput );
}
};
//------------------------------------
// Class for each block
//------------------------------------
var patchworkImage = Class.create({
// Constructor
initialize: function( data ){
var self = this;
this.data = data;
this.parentElement = element;
// Build inner element (which holds the image)
this.innerElement = new Element('div');
// Build outer element (which has a shadow)
this.outerElement = new Element('div')
.setStyle({
'position': 'absolute'
})
.addClassName('featured_image')
.addClassName('clickable')
.hide()
.insert( this.innerElement );
// Set the size and position of this block
this.sizeAndPosition();
// Set the background image on the inner element
this.setBackground( this.innerElement );
// Insert into our grid
$( this.parentElement ).insert( this.outerElement );
// Decide whether to fade in or not
if( this.data.fade ){
this.outerElement.appear({ delay: Math.random().toFixed(3), afterFinish: function(){
if( options.switchImages ){
self.switchImage.bind(self).delay( parseInt(options.switchInterval) + parseInt(self.data.variance) );
}
}});
} else {
this.outerElement.show();
}
this.outerElement.observe( 'click', function(e) {
window.location = this.data.image.image_url.replace( /&/, '&' );
}.bindAsEventListener(this) );
// Listen for resize event
$( this.parentElement ).on( 'patchwork:resize', this.resizeEvent.bindAsEventListener(this) );
},
switchImage: function(){
// Get new image
this.data.image = getNextImage();
var newDiv = this.setBackground( new Element('div').hide() );
this.outerElement.insert( newDiv );
new Effect.Parallel([
new Effect.Fade( this.innerElement, { sync: true } ),
new Effect.Appear( newDiv, { sync: true } )
], {
duration: 1.5,
afterFinish: function(){
this.innerElement.remove();
this.innerElement = newDiv;
}.bind(this)
});
if( options.switchImages ){
this.switchImage.bind(this).delay( parseInt(options.switchInterval) + parseInt(this.data.variance) );
}
},
// Sets the size and position of this block
sizeAndPosition: function(){
var itemHeight = calculateHeight( itemWidth );
this.outerElement.setStyle({
'left': ( this.data['pos'][1] * itemWidth ) + ( this.data['pos'][1] * options.gutterSize ) + 'px',
'top': ( this.data['pos'][0] * itemHeight ) + ( this.data['pos'][0] * options.gutterSize ) + 'px',
'width': ( ( this.data.size == 'large' ) ? ( itemWidth * 2 ) + options.gutterSize : itemWidth ) + 'px',
'height': ( ( this.data.size == 'large' ) ? ( itemHeight * 2 + options.gutterSize ) : itemHeight ) + 'px'
});
return this.outerElement;
},
// Sets the background image on an element
setBackground: function( elem ){
$( elem ).setStyle({
backgroundImage: 'url(' + this.data.image.med_img + ')',
backgroundPosition: 'center center',
backgroundRepeat: 'no-repeat'
});
if( this.data.image.thumb_size.w >= itemWidth ){
$( elem ).setStyle({
'background-size': 'cover'
});
}
return elem;
},
// Prepare to destroy ourselves
destroy: function(){
this.outerElement.remove();
},
// Catches the resize event fired by outer script
resizeEvent: function(e){
this.sizeAndPosition();
}
});
//------------------------------------
// Window resize event
//------------------------------------
Event.observe( window, 'resize', function(){
curColumns = columnCount;
curRows = rowCount;
getBoxDims();
calculateColumnsAndRows();
// Number of columns changed?
if( curColumns != columnCount || curRows != rowCount ){
destroyImages();
_resetImageArray();
_createBlocks();
}
resizeWrapper();
Event.fire( element, 'patchwork:resize' );
});
_init();
return element;
}
});
?>