tupali_fork/librerias/notas/jquery.infinitedrag.js.test
2017-11-10 22:56:06 -05:00

380 lines
9.3 KiB
Plaintext

/*
* jQuery Infinite Drag
* Copyright (c) 2010 Ian Li (http://ianli.com)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*
* Requires jQuery with either jQuery UI Draggable or jQuery Pep
*
* Reference:
* http://ianli.com/infinitedrag/ for usage and examples
* http://github.com/Sleavely/jquery-infinite-drag/ for additional documentation
*/
(function($) {
/**
* Function to create InfiniteDrag object.
*/
$.infinitedrag = function(draggable, draggable_options, tile_options) {
return new InfiniteDrag(draggable, draggable_options, tile_options);
};
$.infinitedrag.serializeTiles = function(tiles) {
var pairs = [];
$.each(tiles, function(key, tile) {
pairs.push(tile.x + ';' + tile.y);
});
return pairs.join();
};
/**
* The InfiniteDrag object.
*/
var InfiniteDrag = function(draggable, draggable_options, tile_options) {
// Use self to reduce confusion about this.
var self = this;
var $draggable = $(draggable);
var $viewport = $draggable.parent();
$draggable.css({
position: "relative"
});
// Draggable options
var _do = {
shouldEase: false,
cursor: true
};
$.extend(_do, draggable_options);
if (_do.cursor) {
$draggable.css({
cursor: "move"
});
}
// Tile options (DEFAULT)
var _to = {
class_name: "_tile",
width: 100,
height: 100,
start_col: 0,
start_row: 0,
range_col: [-1000000, 1000000],
range_row: [-1000000, 1000000],
margin: 0,
cleaning_enabled: true,
remove_buffer: 10,
draggable_lib: $.fn.pep ? "pep" : "draggable",
oncreate: function($element, i, j) {
$element.text(i + "," + j);
},
on_aggregate: false,
aggregate_time: 10
};
// Override tile options.
$.extend(_to, tile_options);
// Override tile options based on draggable options.
if (_do.axis == "x") {
_to.range_row = [_to.start_row, _to.start_row];
} else if (_do.axis == "y") {
_to.range_col = [_to.start_col, _to.start_col];
}
var aggregator_data = [],
aggregator_timer = 0;
// Creates the tile at (i, j).
function create_tile(i, j) {
if (i < _to.range_col[0] || _to.range_col[1] < i) {
return;
} else if (j < _to.range_row[0] || _to.range_row[1] < j) {
return;
}
var x = i * _to.width;
var y = j * _to.height;
var $e = $draggable.append('<div></div>');
var $new_tile = $e.children(":last");
_storeTile($new_tile, i, j);
$new_tile.attr({
"class": _to.class_name,
col: i,
row: j
});
_setTileStyle($new_tile, i, j);
if (_to.on_aggregate) {
aggregator_data.push({
tile: $new_tile,
x: i,
y: j
});
if (aggregator_timer === 0) {
aggregator_timer = setTimeout(_fireAgregate, _to.aggregate_time);
}
}
_to.oncreate.call(self, $new_tile, i, j);
};
// Tries to register a tile
function register_tile(elem) {
var i = $(elem).attr('col');
var j = $(elem).attr('row');
if (typeof i === 'undefined' || typeof j === 'undefined') {
return;
}
if (typeof grid[i] == "undefined") {
grid[i] = {};
}
_storeTile(elem, i, j);
_setTileStyle(elem, i, j);
}
function _setTileStyle(tile, i, j) {
var x = i * _to.width;
var y = j * _to.height;
$(tile).css({
position: "absolute",
left: x,
top: y,
width: _to.width,
height: _to.height
});
}
function _storeTile(tile, i, j) {
grid[i][j] = $(tile).get(0);
if (typeof grid[i].cnt == "undefined") grid[i].cnt = 0;
grid[i].cnt++;
}
function _fireAgregate() {
_to.on_aggregate.call(self, aggregator_data);
aggregator_timer = 0;
aggregator_data = [];
}
// Updates the containment box wherein the draggable can be dragged.
self.update_containment = function() {
// Update viewport info.
viewport_zoom = $viewport.css('zoom');
viewport_width = $viewport.width() + _to.margin * 2;
viewport_height = $viewport.height() + _to.margin * 2;
viewport_cols = Math.ceil(viewport_width / _to.width);
viewport_rows = Math.ceil(viewport_height / _to.height);
// Create containment box.
var half_width = _to.width / 2,
half_height = _to.height / 2,
viewport_offset = $viewport.offset(),
viewport_draggable_width = (viewport_width / viewport_zoom) - _to.width,
viewport_draggable_height = (viewport_height / viewport_zoom) - _to.height;
var containment = [
(-_to.range_col[1] * _to.width) + viewport_offset.left + viewport_draggable_width,
(-_to.range_row[1] * _to.height) + viewport_offset.top + viewport_draggable_height,
(-_to.range_col[0] * _to.width) + viewport_offset.left,
(-_to.range_row[0] * _to.height) + viewport_offset.top,
];
if (_to.draggable_lib == "draggable") {
$draggable.draggable("option", "containment", containment);
}
// Force check for new tiles in visible area,
// in case the containment was triggered by a zoom change.
update_tiles();
};
var last_cleaned_tiles = {
left: 0,
top: 0
};
var update_tiles = function(dragged_pos) {
if (typeof dragged_pos == "undefined") {
dragged_pos = {
left: 0,
top: 0
}
}
var $this = $draggable;
var $parent = $this.parent();
// Problem with .position() in Chrome/WebKit:
// var pos = $(this).position();
// So, we compute it ourselves.
var pos = {
left: $this.offset().left - $parent.offset().left + _to.margin,
top: $this.offset().top - $parent.offset().top + _to.margin
}
// - 1 because the previous tile is partially visible
var visible_left_col = Math.ceil(-pos.left / _to.width) - 1,
visible_top_row = Math.ceil(-pos.top / _to.height) - 1;
for (var i = visible_left_col; i <= visible_left_col + viewport_cols; i++) {
if (typeof grid[i] == "undefined") {
grid[i] = {};
}
for (var j = visible_top_row; j <= visible_top_row + viewport_rows; j++) {
if (typeof grid[i][j] == "undefined") {
create_tile(i, j);
}
}
}
if (
Math.abs(dragged_pos.left - last_cleaned_tiles.left) > (_to.remove_buffer * _to.width) ||
Math.abs(dragged_pos.top - last_cleaned_tiles.top) > (_to.remove_buffer * _to.height)) {
remove_tiles(visible_left_col, visible_top_row);
last_cleaned_tiles = dragged_pos;
}
};
// Removes unseen tiles
//-----------------------
var remove_tiles = function(left, top) {
// Is cleaning disabled?
if (_to.cleaning_enabled) {
return;
}
// Finds tiles which can be seen based on window width & height
var maxLeft = (left + viewport_cols) + 1,
maxTop = (top + viewport_rows);
$.each(grid, function(i, rows) {
$.each(rows, function(j, elem) {
if (j !== 'cnt') {
if ((i < left) || (i > maxLeft) || (j < top) || (j > maxTop)) {
delete grid[i][j];
grid[i].cnt--;
if (grid[i].cnt == 0) delete grid[i];
$(elem).remove();
}
}
});
});
}
// Public Methods
//-----------------
self.draggable = function() {
return $draggable;
};
self.disabled = function(value) {
if (value === undefined) {
return $draggable;
}
if ($.fn.pep) {
$.pep.toggleAll(!value)
} else {
$draggable.draggable("option", "disabled", value);
}
if (_do.cursor) {
$draggable.css({
cursor: (value) ? "default" : "move"
});
}
};
self.center = function(col, row) {
var x = _to.width * col,
y = _to.height * row,
half_width = _to.width / 2,
half_height = _to.height / 2,
half_vw_width = $viewport.width() / 2,
half_vw_height = $viewport.height() / 2,
offset = $draggable.offset();
var new_offset = {
left: -x - (half_width - half_vw_width),
top: -y - (half_height - half_vw_height)
};
if (_do.axis == "x") {
new_offset.top = offset.top;
} else if (_do.axis == "y") {
new_offset.left = offset.left;
}
$draggable.offset(new_offset);
update_tiles(new_offset);
};
self.get_tile_dimensions = function() {
var tileDims = {
width: _to.width,
height: _to.height
};
return tileDims;
};
self.get_tile = function(x, y) {
if (typeof grid[x] !== 'undefined' && typeof grid[x][y] !== 'undefined') {
return $(grid[x][y]);
}
return null;
}
// Setup
//--------
//To make sure minimal setup will show something
if ($viewport.height() == 0) {
$viewport.css({
'min-height': '300px'
});
}
var viewport_zoom = $viewport.css('zoom'),
viewport_width = $viewport.width() + _to.margin * 2,
viewport_height = $viewport.height() + _to.margin * 2,
viewport_cols = Math.ceil(viewport_width / _to.width),
viewport_rows = Math.ceil(viewport_height / _to.height);
$draggable.offset({
left: $viewport.offset().left - (_to.start_col * _to.width),
top: $viewport.offset().top - (_to.start_row * _to.height)
});
var grid = {};
// Tries to register any existing tiles
$draggable.children("." + _to.class_name).each(function() {
register_tile(this);
});
// Create initial tiles
update_tiles();
// Handle resize of window.
$(window).resize(function() {
// HACK:
// Update the containment when the window is resized
// because the containment boundaries depend on the offset of the viewport.
self.update_containment();
});
// The drag event handler.
_do.drag = function(e, ui) {
update_tiles(ui.position);
};
$draggable[_to.draggable_lib](_do);
self.update_containment();
};
})(jQuery);