Release v0.3.0

This commit is contained in:
vieron
2014-02-07 14:48:53 +01:00
parent b65a802964
commit 04cb32f6f3
8 changed files with 424 additions and 203 deletions
+11
View File
@@ -1,3 +1,14 @@
<a name="v0.3.0"></a>
## v0.3.0 (2013-11-18)
#### Features
* **draggable:**
* method to set drag limits dynamically ([d4482ec1](http://github.com/ducksboard/gridster.js/commit/d4482ec1476f8a0b6fb6cdeb25b7774ef678d81c))
* support horizontal scrolling while dragging ([ae4921b7](http://github.com/ducksboard/gridster.js/commit/ae4921b70798944211267cacf8a89e62d0818369))
* **gridster:** increase grid width when dragging or resizing ([b61df653](http://github.com/ducksboard/gridster.js/commit/b61df6535f728970fb8c6f25a208275dbde66550))
<a name="v0.2.1"></a>
### v0.2.1 (2013-10-28)
+6 -6
View File
@@ -1,4 +1,4 @@
/*! gridster.js - v0.2.1 - 2013-10-28
/*! gridster.js - v0.3.0 - 2013-11-19
* http://gridster.net/
* Copyright (c) 2013 ducksboard; Licensed MIT */
@@ -8,11 +8,11 @@
.gridster > * {
margin: 0 auto;
-webkit-transition: height .4s;
-moz-transition: height .4s;
-o-transition: height .4s;
-ms-transition: height .4s;
transition: height .4s;
-webkit-transition: height .4s, width .4s;
-moz-transition: height .4s, width .4s;
-o-transition: height .4s, width .4s;
-ms-transition: height .4s, width .4s;
transition: height .4s, width .4s;
}
.gridster .gs-w {
+200 -95
View File
@@ -1,4 +1,4 @@
/*! gridster.js - v0.2.1 - 2013-10-28
/*! gridster.js - v0.3.0 - 2013-11-19
* http://gridster.net/
* Copyright (c) 2013 ducksboard; Licensed MIT */
@@ -138,7 +138,7 @@
this.$element = el;
this.last_colliders = [];
this.last_colliders_coords = [];
if (typeof colliders === 'string' || colliders instanceof jQuery) {
if (typeof colliders === 'string' || colliders instanceof $) {
this.$colliders = $(colliders,
this.options.colliders_context).not(this.$element);
}else{
@@ -385,6 +385,7 @@
};
var $window = $(window);
var dir_map = { x : 'left', y : 'top' };
var isTouch = !!('ontouchstart' in window);
var pointer_events = {
start: isTouch ? 'touchstart.gridster-draggable' : 'mousedown.gridster-draggable',
@@ -392,6 +393,10 @@
end: isTouch ? 'touchend.gridster-draggable' : 'mouseup.gridster-draggable'
};
var capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
/**
* Basic drag implementation for DOM elements inside a container.
* Provide start/stop/drag callbacks.
@@ -431,13 +436,13 @@
var fn = Draggable.prototype;
fn.init = function() {
this.calculate_positions();
this.calculate_dimensions();
this.$container.css('position', 'relative');
this.disabled = false;
this.events();
$(window).bind('resize.gridster-draggable',
throttle($.proxy(this.calculate_positions, this), 200));
throttle($.proxy(this.calculate_dimensions, this), 200));
};
fn.events = function() {
@@ -483,9 +488,10 @@
mouse_actual_pos.left - this.mouse_init_pos.left);
var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top);
var left = Math.round(this.el_init_offset.left + diff_x - this.baseX);
var top = Math.round(
this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset);
var left = Math.round(this.el_init_offset.left +
diff_x - this.baseX + this.scroll_offset_x);
var top = Math.round(this.el_init_offset.top +
diff_y - this.baseY + this.scroll_offset_y);
if (this.options.limit) {
if (left > this.player_max_left) {
@@ -503,8 +509,8 @@
pointer: {
left: mouse_actual_pos.left,
top: mouse_actual_pos.top,
diff_left: diff_x,
diff_top: diff_y + this.scrollOffset
diff_left: diff_x + this.scroll_offset_x,
diff_top: diff_y + this.scroll_offset_y
}
};
};
@@ -519,42 +525,69 @@
};
fn.manage_scroll = function(data) {
/* scroll document */
var nextScrollTop;
var scrollTop = $window.scrollTop();
var min_window_y = scrollTop;
var max_window_y = min_window_y + this.window_height;
fn.set_limits = function(container_width) {
container_width || (container_width = this.$container.width());
this.player_max_left = (container_width - this.player_width +
- this.options.offset_left);
var mouse_down_zone = max_window_y - 50;
var mouse_up_zone = min_window_y + 50;
this.options.container_width = container_width;
var abs_mouse_left = data.pointer.left;
var abs_mouse_top = min_window_y + data.pointer.top;
var max_player_y = (this.doc_height - this.window_height +
this.player_height);
if (abs_mouse_top >= mouse_down_zone) {
nextScrollTop = scrollTop + 30;
if (nextScrollTop < max_player_y) {
$window.scrollTop(nextScrollTop);
this.scrollOffset = this.scrollOffset + 30;
}
}
if (abs_mouse_top <= mouse_up_zone) {
nextScrollTop = scrollTop - 30;
if (nextScrollTop > 0) {
$window.scrollTop(nextScrollTop);
this.scrollOffset = this.scrollOffset - 30;
}
}
return this;
};
fn.calculate_positions = function(e) {
fn.scroll_in = function(axis, data) {
var dir_prop = dir_map[axis];
var area_size = 50;
var scroll_inc = 30;
var is_x = axis === 'x';
var window_size = is_x ? this.window_width : this.window_height;
var doc_size = is_x ? $(document).width() : $(document).height();
var player_size = is_x ? this.$player.width() : this.$player.height();
var next_scroll;
var scroll_offset = $window['scroll' + capitalize(dir_prop)]();
var min_window_pos = scroll_offset;
var max_window_pos = min_window_pos + window_size;
var mouse_next_zone = max_window_pos - area_size; // down/right
var mouse_prev_zone = min_window_pos + area_size; // up/left
var abs_mouse_pos = min_window_pos + data.pointer[dir_prop];
var max_player_pos = (doc_size - window_size + player_size);
if (abs_mouse_pos >= mouse_next_zone) {
next_scroll = scroll_offset + scroll_inc;
if (next_scroll < max_player_pos) {
$window['scroll' + capitalize(dir_prop)](next_scroll);
this['scroll_offset_' + axis] += scroll_inc;
}
}
if (abs_mouse_pos <= mouse_prev_zone) {
next_scroll = scroll_offset - scroll_inc;
if (next_scroll > 0) {
$window['scroll' + capitalize(dir_prop)](next_scroll);
this['scroll_offset_' + axis] -= scroll_inc;
}
}
return this;
};
fn.manage_scroll = function(data) {
this.scroll_in('x', data);
this.scroll_in('y', data);
};
fn.calculate_dimensions = function(e) {
this.window_height = $window.height();
this.window_width = $window.width();
};
@@ -614,7 +647,7 @@
var offset = this.$container.offset();
this.baseX = Math.round(offset.left);
this.baseY = Math.round(offset.top);
this.doc_height = $(document).height();
this.initial_container_width = this.options.container_width || this.$container.width();
if (this.options.helper === 'clone') {
this.$helper = this.$player.clone()
@@ -624,14 +657,13 @@
this.helper = false;
}
this.scrollOffset = 0;
this.scroll_offset_y = 0;
this.scroll_offset_x = 0;
this.el_init_offset = this.$player.offset();
this.player_width = this.$player.width();
this.player_height = this.$player.height();
var container_width = this.options.container_width || this.$container.width();
this.player_max_left = (container_width - this.player_width +
this.options.offset_left);
this.set_limits(this.options.container_width);
if (this.options.start) {
this.options.start.call(this.$player, e, this.get_drag_data(e));
@@ -734,9 +766,10 @@
extra_rows: 0,
extra_cols: 0,
min_cols: 1,
max_cols: null,
max_cols: Infinity,
min_rows: 15,
max_size_x: false,
autogrow_cols: false,
autogenerate_stylesheet: true,
avoid_overlapped_widgets: true,
serialize_params: function($w, wgd) {
@@ -856,6 +889,7 @@
this.generate_grid_and_stylesheet();
this.get_widgets_from_DOM();
this.set_dom_grid_height();
this.set_dom_grid_width();
this.$wrapper.addClass('ready');
this.draggable();
this.options.resize.enabled && this.resizable();
@@ -1017,38 +1051,36 @@
* @param {HTMLElement} $widget The jQuery wrapped HTMLElement
* representing the widget.
* @param {Number} size_x The number of columns that will occupy the widget.
* @param {Number} size_y The number of rows that will occupy the widget.
* @param {Boolean} [reposition] Set to false to not move the widget to
* the left if there is insufficient space on the right.
* By default <code>size_x</code> is limited to the space available from
* the column where the widget begins, until the last column to the right.
* @param {Number} size_y The number of rows that will occupy the widget.
* @param {Function} [callback] Function executed when the widget is removed.
* @return {HTMLElement} Returns $widget.
*/
fn.resize_widget = function($widget, size_x, size_y, reposition, callback) {
fn.resize_widget = function($widget, size_x, size_y, callback) {
var wgd = $widget.coords().grid;
reposition !== false && (reposition = true);
size_x || (size_x = wgd.size_x);
size_y || (size_y = wgd.size_y);
if (size_x > this.cols) {
size_x = this.cols;
}
var col = wgd.col;
var max_cols = this.options.max_cols;
var old_size_y = wgd.size_y;
var old_col = wgd.col;
var new_col = old_col;
if (reposition && old_col + size_x - 1 > this.cols) {
var diff = old_col + (size_x - 1) - this.cols;
var c = old_col - diff;
new_col = Math.max(1, c);
size_x || (size_x = wgd.size_x);
size_y || (size_y = wgd.size_y);
if (max_cols !== Infinity) {
size_x = Math.min(size_x, max_cols - col + 1);
}
if (size_y > old_size_y) {
this.add_faux_rows(Math.max(size_y - old_size_y, 0));
}
var player_rcol = (col + size_x - 1);
if (player_rcol > this.cols) {
this.add_faux_cols(player_rcol - this.cols);
}
var new_grid_data = {
col: new_col,
row: wgd.row,
@@ -1059,6 +1091,7 @@
this.mutate_widget_in_gridmap($widget, wgd, new_grid_data);
this.set_dom_grid_height();
this.set_dom_grid_width();
if (callback) {
callback.call(this, new_grid_data.size_x, new_grid_data.size_y);
@@ -1297,7 +1330,7 @@
* @return {Class} Returns the instance of the Gridster Class.
*/
fn.remove_widget = function(el, silent, callback) {
var $el = el instanceof jQuery ? el : $(el);
var $el = el instanceof $ ? el : $(el);
var wgd = $el.coords().grid;
// if silent is a function assume it's a callback
@@ -1495,7 +1528,9 @@
var self = this;
var draggable_options = $.extend(true, {}, this.options.draggable, {
offset_left: this.options.widget_margins[0],
offset_top: this.options.widget_margins[1],
container_width: this.container_width,
limit: true,
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON',
'.' + this.options.resize.handle_class],
start: function(event, ui) {
@@ -1537,6 +1572,8 @@
offset_left: this.options.widget_margins[0],
container_width: this.container_width,
move_element: false,
resize: true,
limit: this.options.autogrow_cols ? false : true,
start: $.proxy(this.on_start_resize, this),
stop: $.proxy(function(event, ui) {
delay($.proxy(function() {
@@ -1579,13 +1616,22 @@
fn.on_start_drag = function(event, ui) {
this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging');
this.highest_col = this.get_highest_occupied_cell().col;
this.$player.addClass('player');
this.player_grid_data = this.$player.coords().grid;
this.placeholder_grid_data = $.extend({}, this.player_grid_data);
//set new grid height along the dragging period
this.$el.css('height', this.$el.height() +
(this.player_grid_data.size_y * this.min_widget_height));
this.set_dom_grid_height(this.$el.height() +
(this.player_grid_data.size_y * this.min_widget_height));
this.set_dom_grid_width(this.highest_col + 1);
// auto grow cols
var cols_diff = this.cols - this.highest_col;
if (cols_diff < this.player_grid_data.size_x) {
this.add_faux_cols(this.player_grid_data.size_x - cols_diff);
}
var colliders = this.faux_grid;
var coords = this.$player.data('coords').coords;
@@ -1649,6 +1695,19 @@
this.on_stop_overlapping_row
);
//auto grow cols
if (this.options.autogrow_cols) {
var prcol = this.placeholder_grid_data.col +
this.placeholder_grid_data.size_x - 1;
if (prcol === this.highest_col) {
if (prcol < this.cols) {
this.set_dom_grid_width(prcol + 1);
}
this.highest_col = prcol + 1;
this.drag_api.set_limits(this.container_width);
}
}
if (this.helper && this.$player) {
this.$player.css({
'left': ui.position.left,
@@ -1720,6 +1779,11 @@
this.cells_occupied_by_player = {};
this.set_dom_grid_height();
this.set_dom_grid_width();
if (this.options.autogrow_cols) {
this.drag_api.set_limits(this.container_width);
}
};
@@ -1739,12 +1803,16 @@
this.resize_initial_height = this.resize_coords.coords.height;
this.resize_initial_sizex = this.resize_coords.grid.size_x;
this.resize_initial_sizey = this.resize_coords.grid.size_y;
this.resize_initial_col = this.resize_coords.grid.col;
this.resize_last_sizex = this.resize_initial_sizex;
this.resize_last_sizey = this.resize_initial_sizey;
this.resize_max_size_x = Math.min(this.resize_wgd.max_size_x ||
this.options.resize.max_size[0], this.cols - this.resize_wgd.col + 1);
this.options.resize.max_size[0],
this.options.max_cols - this.resize_initial_col + 1);
this.resize_max_size_y = this.resize_wgd.max_size_y ||
this.options.resize.max_size[1];
this.resize_initial_last_col = this.get_highest_occupied_cell().col;
this.resize_dir = {
right: ui.$player.is('.' + this.resize_handle_class + '-x'),
@@ -1799,6 +1867,12 @@
});
}, this), 300);
this.set_dom_grid_width();
if (this.options.autogrow_cols) {
this.drag_api.set_limits(this.container_width);
}
if (this.options.resize.stop) {
this.options.resize.stop.call(this, event, ui, this.$resized_widget);
}
@@ -1845,6 +1919,20 @@
size_x = this.resize_initial_sizex;
}
if (this.options.autogrow_cols) {
// auto grow cols
var last_widget_col = this.resize_initial_col + size_x - 1;
if (this.options.autogrow_cols && this.resize_initial_last_col <= last_widget_col) {
this.set_dom_grid_width(last_widget_col + 1);
if (this.cols < last_widget_col) {
this.add_faux_cols(last_widget_col - this.cols);
}
}
}
var css_props = {};
!this.resize_dir.bottom && (css_props.width = Math.min(
this.resize_initial_width + rel_x, max_width));
@@ -1856,7 +1944,7 @@
if (size_x !== this.resize_last_sizex ||
size_y !== this.resize_last_sizey) {
this.resize_widget(this.$resized_widget, size_x, size_y, false);
this.resize_widget(this.$resized_widget, size_x, size_y);
this.$resize_preview_holder.css({
'width': '',
@@ -3082,7 +3170,7 @@
fn.get_cells_occupied = function(el_grid_data) {
var cells = { cols: [], rows: []};
var i;
if (arguments[1] instanceof jQuery) {
if (arguments[1] instanceof $) {
el_grid_data = arguments[1].coords().grid;
}
@@ -3166,7 +3254,7 @@
var cr, max;
var action = type + '/' + direction;
if (arguments[2] instanceof jQuery) {
if (arguments[2] instanceof $) {
var el_grid_data = arguments[2].coords().grid;
col = el_grid_data.col;
row = el_grid_data.row;
@@ -3250,26 +3338,23 @@
fn.get_highest_occupied_cell = function() {
var r;
var gm = this.gridmap;
var rows = [];
var rl = gm[1].length;
var rows = [], cols = [];
var row_in_col = [];
for (var c = gm.length - 1; c >= 1; c--) {
for (r = gm[c].length - 1; r >= 1; r--) {
for (r = rl - 1; r >= 1; r--) {
if (this.is_widget(c, r)) {
rows.push(r);
row_in_col[r] = c;
cols.push(c);
break;
}
}
}
var highest_row = Math.max.apply(Math, rows);
this.highest_occupied_cell = {
col: row_in_col[highest_row],
row: highest_row
return {
col: Math.max.apply(Math, cols),
row: Math.max.apply(Math, rows)
};
return this.highest_occupied_cell;
};
@@ -3305,9 +3390,34 @@
* @method set_dom_grid_height
* @return {Object} Returns the instance of the Gridster class.
*/
fn.set_dom_grid_height = function() {
var r = this.get_highest_occupied_cell().row;
this.$el.css('height', r * this.min_widget_height);
fn.set_dom_grid_height = function(height) {
if (typeof height === 'undefined') {
var r = this.get_highest_occupied_cell().row;
height = r * this.min_widget_height;
}
this.container_height = height;
this.$el.css('height', this.container_height);
return this;
};
/**
* Set the current width of the parent grid.
*
* @method set_dom_grid_width
* @return {Object} Returns the instance of the Gridster class.
*/
fn.set_dom_grid_width = function(cols) {
var width;
if (typeof cols === 'undefined') {
cols = this.get_highest_occupied_cell().col;
}
cols = Math.min(this.options.max_cols,
Math.max(cols, this.options.min_cols));
this.container_width = cols * this.min_widget_width;
this.$el.css('width', this.container_width);
return this;
};
@@ -3509,8 +3619,9 @@
fn.add_faux_cols = function(cols) {
var actual_cols = this.cols;
var max_cols = actual_cols + (cols || 1);
max_cols = Math.min(max_cols, this.options.max_cols);
for (var c = actual_cols; c < max_cols; c++) {
for (var c = actual_cols + 1; c <= max_cols; c++) {
for (var r = this.rows; r >= 1; r--) {
this.add_faux_cell(r, c);
}
@@ -3573,7 +3684,6 @@
*/
fn.generate_grid_and_stylesheet = function() {
var aw = this.$wrapper.width();
var ah = this.$wrapper.height();
var max_cols = this.options.max_cols;
var cols = Math.floor(aw / this.min_widget_width) +
@@ -3588,28 +3698,23 @@
var min_cols = Math.max.apply(Math, actual_cols);
this.cols = Math.max(min_cols, cols, this.options.min_cols);
if (max_cols !== Infinity && max_cols >= min_cols && max_cols < this.cols) {
this.cols = max_cols;
}
// get all rows that could be occupied by the current widgets
var max_rows = this.options.extra_rows;
this.$widgets.each(function(i, w) {
max_rows += (+$(w).attr('data-sizey'));
});
this.cols = Math.max(min_cols, cols, this.options.min_cols);
if (max_cols && max_cols >= min_cols && max_cols < this.cols) {
this.cols = max_cols;
}
this.rows = Math.max(max_rows, this.options.min_rows);
this.baseX = ($(window).width() - aw) / 2;
this.baseY = this.$wrapper.offset().top;
// left and right gutters not included
this.container_width = (this.cols *
this.options.widget_base_dimensions[0]) + ((this.cols - 1) * 2 *
this.options.widget_margins[0]);
if (this.options.autogenerate_stylesheet) {
this.generate_stylesheet();
}
+2 -2
View File
@@ -1,2 +1,2 @@
/*! gridster.js - v0.2.1 - 2013-10-28 - * http://gridster.net/ - Copyright (c) 2013 ducksboard; Licensed MIT */
.gridster{position:relative}.gridster>*{margin:0 auto;-webkit-transition:height .4s;-moz-transition:height .4s;-o-transition:height .4s;-ms-transition:height .4s;transition:height .4s}.gridster .gs-w{z-index:2;position:absolute}.ready .gs-w:not(.preview-holder){-webkit-transition:opacity .3s,left .3s,top .3s;-moz-transition:opacity .3s,left .3s,top .3s;-o-transition:opacity .3s,left .3s,top .3s;transition:opacity .3s,left .3s,top .3s}.ready .gs-w:not(.preview-holder),.ready .resize-preview-holder{-webkit-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-moz-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-o-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;transition:opacity .3s,left .3s,top .3s,width .3s,height .3s}.gridster .preview-holder{z-index:1;position:absolute;background-color:#fff;border-color:#fff;opacity:.3}.gridster .player-revert{z-index:10!important;-webkit-transition:left .3s,top .3s!important;-moz-transition:left .3s,top .3s!important;-o-transition:left .3s,top .3s!important;transition:left .3s,top .3s!important}.gridster .dragging,.gridster .resizing{z-index:10!important;-webkit-transition:all 0s!important;-moz-transition:all 0s!important;-o-transition:all 0s!important;transition:all 0s!important}.gs-resize-handle{position:absolute;z-index:1}.gs-resize-handle-both{width:20px;height:20px;bottom:-8px;right:-8px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=);background-position:top left;background-repeat:no-repeat;cursor:se-resize;z-index:20}.gs-resize-handle-x{top:0;bottom:13px;right:-5px;width:10px;cursor:e-resize}.gs-resize-handle-y{left:0;right:13px;bottom:-5px;height:10px;cursor:s-resize}.gs-w:hover .gs-resize-handle,.resizing .gs-resize-handle{opacity:1}.gs-resize-handle,.gs-w.dragging .gs-resize-handle{opacity:0}.gs-resize-disabled .gs-resize-handle{display:none!important}[data-max-sizex="1"] .gs-resize-handle-x,[data-max-sizey="1"] .gs-resize-handle-y,[data-max-sizey="1"][data-max-sizex="1"] .gs-resize-handle{display:none!important}
/*! gridster.js - v0.3.0 - 2013-11-19 - * http://gridster.net/ - Copyright (c) 2013 ducksboard; Licensed MIT */
.gridster{position:relative}.gridster>*{margin:0 auto;-webkit-transition:height .4s,width .4s;-moz-transition:height .4s,width .4s;-o-transition:height .4s,width .4s;-ms-transition:height .4s,width .4s;transition:height .4s,width .4s}.gridster .gs-w{z-index:2;position:absolute}.ready .gs-w:not(.preview-holder){-webkit-transition:opacity .3s,left .3s,top .3s;-moz-transition:opacity .3s,left .3s,top .3s;-o-transition:opacity .3s,left .3s,top .3s;transition:opacity .3s,left .3s,top .3s}.ready .gs-w:not(.preview-holder),.ready .resize-preview-holder{-webkit-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-moz-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-o-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;transition:opacity .3s,left .3s,top .3s,width .3s,height .3s}.gridster .preview-holder{z-index:1;position:absolute;background-color:#fff;border-color:#fff;opacity:.3}.gridster .player-revert{z-index:10!important;-webkit-transition:left .3s,top .3s!important;-moz-transition:left .3s,top .3s!important;-o-transition:left .3s,top .3s!important;transition:left .3s,top .3s!important}.gridster .dragging,.gridster .resizing{z-index:10!important;-webkit-transition:all 0s!important;-moz-transition:all 0s!important;-o-transition:all 0s!important;transition:all 0s!important}.gs-resize-handle{position:absolute;z-index:1}.gs-resize-handle-both{width:20px;height:20px;bottom:-8px;right:-8px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=);background-position:top left;background-repeat:no-repeat;cursor:se-resize;z-index:20}.gs-resize-handle-x{top:0;bottom:13px;right:-5px;width:10px;cursor:e-resize}.gs-resize-handle-y{left:0;right:13px;bottom:-5px;height:10px;cursor:s-resize}.gs-w:hover .gs-resize-handle,.resizing .gs-resize-handle{opacity:1}.gs-resize-handle,.gs-w.dragging .gs-resize-handle{opacity:0}.gs-resize-disabled .gs-resize-handle{display:none!important}[data-max-sizex="1"] .gs-resize-handle-x,[data-max-sizey="1"] .gs-resize-handle-y,[data-max-sizey="1"][data-max-sizex="1"] .gs-resize-handle{display:none!important}
+2 -2
View File
File diff suppressed because one or more lines are too long
+200 -95
View File
@@ -1,4 +1,4 @@
/*! gridster.js - v0.2.1 - 2013-10-28
/*! gridster.js - v0.3.0 - 2013-11-19
* http://gridster.net/
* Copyright (c) 2013 ducksboard; Licensed MIT */
@@ -138,7 +138,7 @@
this.$element = el;
this.last_colliders = [];
this.last_colliders_coords = [];
if (typeof colliders === 'string' || colliders instanceof jQuery) {
if (typeof colliders === 'string' || colliders instanceof $) {
this.$colliders = $(colliders,
this.options.colliders_context).not(this.$element);
}else{
@@ -385,6 +385,7 @@
};
var $window = $(window);
var dir_map = { x : 'left', y : 'top' };
var isTouch = !!('ontouchstart' in window);
var pointer_events = {
start: isTouch ? 'touchstart.gridster-draggable' : 'mousedown.gridster-draggable',
@@ -392,6 +393,10 @@
end: isTouch ? 'touchend.gridster-draggable' : 'mouseup.gridster-draggable'
};
var capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
/**
* Basic drag implementation for DOM elements inside a container.
* Provide start/stop/drag callbacks.
@@ -431,13 +436,13 @@
var fn = Draggable.prototype;
fn.init = function() {
this.calculate_positions();
this.calculate_dimensions();
this.$container.css('position', 'relative');
this.disabled = false;
this.events();
$(window).bind('resize.gridster-draggable',
throttle($.proxy(this.calculate_positions, this), 200));
throttle($.proxy(this.calculate_dimensions, this), 200));
};
fn.events = function() {
@@ -483,9 +488,10 @@
mouse_actual_pos.left - this.mouse_init_pos.left);
var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top);
var left = Math.round(this.el_init_offset.left + diff_x - this.baseX);
var top = Math.round(
this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset);
var left = Math.round(this.el_init_offset.left +
diff_x - this.baseX + this.scroll_offset_x);
var top = Math.round(this.el_init_offset.top +
diff_y - this.baseY + this.scroll_offset_y);
if (this.options.limit) {
if (left > this.player_max_left) {
@@ -503,8 +509,8 @@
pointer: {
left: mouse_actual_pos.left,
top: mouse_actual_pos.top,
diff_left: diff_x,
diff_top: diff_y + this.scrollOffset
diff_left: diff_x + this.scroll_offset_x,
diff_top: diff_y + this.scroll_offset_y
}
};
};
@@ -519,42 +525,69 @@
};
fn.manage_scroll = function(data) {
/* scroll document */
var nextScrollTop;
var scrollTop = $window.scrollTop();
var min_window_y = scrollTop;
var max_window_y = min_window_y + this.window_height;
fn.set_limits = function(container_width) {
container_width || (container_width = this.$container.width());
this.player_max_left = (container_width - this.player_width +
- this.options.offset_left);
var mouse_down_zone = max_window_y - 50;
var mouse_up_zone = min_window_y + 50;
this.options.container_width = container_width;
var abs_mouse_left = data.pointer.left;
var abs_mouse_top = min_window_y + data.pointer.top;
var max_player_y = (this.doc_height - this.window_height +
this.player_height);
if (abs_mouse_top >= mouse_down_zone) {
nextScrollTop = scrollTop + 30;
if (nextScrollTop < max_player_y) {
$window.scrollTop(nextScrollTop);
this.scrollOffset = this.scrollOffset + 30;
}
}
if (abs_mouse_top <= mouse_up_zone) {
nextScrollTop = scrollTop - 30;
if (nextScrollTop > 0) {
$window.scrollTop(nextScrollTop);
this.scrollOffset = this.scrollOffset - 30;
}
}
return this;
};
fn.calculate_positions = function(e) {
fn.scroll_in = function(axis, data) {
var dir_prop = dir_map[axis];
var area_size = 50;
var scroll_inc = 30;
var is_x = axis === 'x';
var window_size = is_x ? this.window_width : this.window_height;
var doc_size = is_x ? $(document).width() : $(document).height();
var player_size = is_x ? this.$player.width() : this.$player.height();
var next_scroll;
var scroll_offset = $window['scroll' + capitalize(dir_prop)]();
var min_window_pos = scroll_offset;
var max_window_pos = min_window_pos + window_size;
var mouse_next_zone = max_window_pos - area_size; // down/right
var mouse_prev_zone = min_window_pos + area_size; // up/left
var abs_mouse_pos = min_window_pos + data.pointer[dir_prop];
var max_player_pos = (doc_size - window_size + player_size);
if (abs_mouse_pos >= mouse_next_zone) {
next_scroll = scroll_offset + scroll_inc;
if (next_scroll < max_player_pos) {
$window['scroll' + capitalize(dir_prop)](next_scroll);
this['scroll_offset_' + axis] += scroll_inc;
}
}
if (abs_mouse_pos <= mouse_prev_zone) {
next_scroll = scroll_offset - scroll_inc;
if (next_scroll > 0) {
$window['scroll' + capitalize(dir_prop)](next_scroll);
this['scroll_offset_' + axis] -= scroll_inc;
}
}
return this;
};
fn.manage_scroll = function(data) {
this.scroll_in('x', data);
this.scroll_in('y', data);
};
fn.calculate_dimensions = function(e) {
this.window_height = $window.height();
this.window_width = $window.width();
};
@@ -614,7 +647,7 @@
var offset = this.$container.offset();
this.baseX = Math.round(offset.left);
this.baseY = Math.round(offset.top);
this.doc_height = $(document).height();
this.initial_container_width = this.options.container_width || this.$container.width();
if (this.options.helper === 'clone') {
this.$helper = this.$player.clone()
@@ -624,14 +657,13 @@
this.helper = false;
}
this.scrollOffset = 0;
this.scroll_offset_y = 0;
this.scroll_offset_x = 0;
this.el_init_offset = this.$player.offset();
this.player_width = this.$player.width();
this.player_height = this.$player.height();
var container_width = this.options.container_width || this.$container.width();
this.player_max_left = (container_width - this.player_width +
this.options.offset_left);
this.set_limits(this.options.container_width);
if (this.options.start) {
this.options.start.call(this.$player, e, this.get_drag_data(e));
@@ -734,9 +766,10 @@
extra_rows: 0,
extra_cols: 0,
min_cols: 1,
max_cols: null,
max_cols: Infinity,
min_rows: 15,
max_size_x: false,
autogrow_cols: false,
autogenerate_stylesheet: true,
avoid_overlapped_widgets: true,
serialize_params: function($w, wgd) {
@@ -856,6 +889,7 @@
this.generate_grid_and_stylesheet();
this.get_widgets_from_DOM();
this.set_dom_grid_height();
this.set_dom_grid_width();
this.$wrapper.addClass('ready');
this.draggable();
this.options.resize.enabled && this.resizable();
@@ -1017,38 +1051,36 @@
* @param {HTMLElement} $widget The jQuery wrapped HTMLElement
* representing the widget.
* @param {Number} size_x The number of columns that will occupy the widget.
* @param {Number} size_y The number of rows that will occupy the widget.
* @param {Boolean} [reposition] Set to false to not move the widget to
* the left if there is insufficient space on the right.
* By default <code>size_x</code> is limited to the space available from
* the column where the widget begins, until the last column to the right.
* @param {Number} size_y The number of rows that will occupy the widget.
* @param {Function} [callback] Function executed when the widget is removed.
* @return {HTMLElement} Returns $widget.
*/
fn.resize_widget = function($widget, size_x, size_y, reposition, callback) {
fn.resize_widget = function($widget, size_x, size_y, callback) {
var wgd = $widget.coords().grid;
reposition !== false && (reposition = true);
size_x || (size_x = wgd.size_x);
size_y || (size_y = wgd.size_y);
if (size_x > this.cols) {
size_x = this.cols;
}
var col = wgd.col;
var max_cols = this.options.max_cols;
var old_size_y = wgd.size_y;
var old_col = wgd.col;
var new_col = old_col;
if (reposition && old_col + size_x - 1 > this.cols) {
var diff = old_col + (size_x - 1) - this.cols;
var c = old_col - diff;
new_col = Math.max(1, c);
size_x || (size_x = wgd.size_x);
size_y || (size_y = wgd.size_y);
if (max_cols !== Infinity) {
size_x = Math.min(size_x, max_cols - col + 1);
}
if (size_y > old_size_y) {
this.add_faux_rows(Math.max(size_y - old_size_y, 0));
}
var player_rcol = (col + size_x - 1);
if (player_rcol > this.cols) {
this.add_faux_cols(player_rcol - this.cols);
}
var new_grid_data = {
col: new_col,
row: wgd.row,
@@ -1059,6 +1091,7 @@
this.mutate_widget_in_gridmap($widget, wgd, new_grid_data);
this.set_dom_grid_height();
this.set_dom_grid_width();
if (callback) {
callback.call(this, new_grid_data.size_x, new_grid_data.size_y);
@@ -1297,7 +1330,7 @@
* @return {Class} Returns the instance of the Gridster Class.
*/
fn.remove_widget = function(el, silent, callback) {
var $el = el instanceof jQuery ? el : $(el);
var $el = el instanceof $ ? el : $(el);
var wgd = $el.coords().grid;
// if silent is a function assume it's a callback
@@ -1495,7 +1528,9 @@
var self = this;
var draggable_options = $.extend(true, {}, this.options.draggable, {
offset_left: this.options.widget_margins[0],
offset_top: this.options.widget_margins[1],
container_width: this.container_width,
limit: true,
ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON',
'.' + this.options.resize.handle_class],
start: function(event, ui) {
@@ -1537,6 +1572,8 @@
offset_left: this.options.widget_margins[0],
container_width: this.container_width,
move_element: false,
resize: true,
limit: this.options.autogrow_cols ? false : true,
start: $.proxy(this.on_start_resize, this),
stop: $.proxy(function(event, ui) {
delay($.proxy(function() {
@@ -1579,13 +1616,22 @@
fn.on_start_drag = function(event, ui) {
this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging');
this.highest_col = this.get_highest_occupied_cell().col;
this.$player.addClass('player');
this.player_grid_data = this.$player.coords().grid;
this.placeholder_grid_data = $.extend({}, this.player_grid_data);
//set new grid height along the dragging period
this.$el.css('height', this.$el.height() +
(this.player_grid_data.size_y * this.min_widget_height));
this.set_dom_grid_height(this.$el.height() +
(this.player_grid_data.size_y * this.min_widget_height));
this.set_dom_grid_width(this.highest_col + 1);
// auto grow cols
var cols_diff = this.cols - this.highest_col;
if (cols_diff < this.player_grid_data.size_x) {
this.add_faux_cols(this.player_grid_data.size_x - cols_diff);
}
var colliders = this.faux_grid;
var coords = this.$player.data('coords').coords;
@@ -1649,6 +1695,19 @@
this.on_stop_overlapping_row
);
//auto grow cols
if (this.options.autogrow_cols) {
var prcol = this.placeholder_grid_data.col +
this.placeholder_grid_data.size_x - 1;
if (prcol === this.highest_col) {
if (prcol < this.cols) {
this.set_dom_grid_width(prcol + 1);
}
this.highest_col = prcol + 1;
this.drag_api.set_limits(this.container_width);
}
}
if (this.helper && this.$player) {
this.$player.css({
'left': ui.position.left,
@@ -1720,6 +1779,11 @@
this.cells_occupied_by_player = {};
this.set_dom_grid_height();
this.set_dom_grid_width();
if (this.options.autogrow_cols) {
this.drag_api.set_limits(this.container_width);
}
};
@@ -1739,12 +1803,16 @@
this.resize_initial_height = this.resize_coords.coords.height;
this.resize_initial_sizex = this.resize_coords.grid.size_x;
this.resize_initial_sizey = this.resize_coords.grid.size_y;
this.resize_initial_col = this.resize_coords.grid.col;
this.resize_last_sizex = this.resize_initial_sizex;
this.resize_last_sizey = this.resize_initial_sizey;
this.resize_max_size_x = Math.min(this.resize_wgd.max_size_x ||
this.options.resize.max_size[0], this.cols - this.resize_wgd.col + 1);
this.options.resize.max_size[0],
this.options.max_cols - this.resize_initial_col + 1);
this.resize_max_size_y = this.resize_wgd.max_size_y ||
this.options.resize.max_size[1];
this.resize_initial_last_col = this.get_highest_occupied_cell().col;
this.resize_dir = {
right: ui.$player.is('.' + this.resize_handle_class + '-x'),
@@ -1799,6 +1867,12 @@
});
}, this), 300);
this.set_dom_grid_width();
if (this.options.autogrow_cols) {
this.drag_api.set_limits(this.container_width);
}
if (this.options.resize.stop) {
this.options.resize.stop.call(this, event, ui, this.$resized_widget);
}
@@ -1845,6 +1919,20 @@
size_x = this.resize_initial_sizex;
}
if (this.options.autogrow_cols) {
// auto grow cols
var last_widget_col = this.resize_initial_col + size_x - 1;
if (this.options.autogrow_cols && this.resize_initial_last_col <= last_widget_col) {
this.set_dom_grid_width(last_widget_col + 1);
if (this.cols < last_widget_col) {
this.add_faux_cols(last_widget_col - this.cols);
}
}
}
var css_props = {};
!this.resize_dir.bottom && (css_props.width = Math.min(
this.resize_initial_width + rel_x, max_width));
@@ -1856,7 +1944,7 @@
if (size_x !== this.resize_last_sizex ||
size_y !== this.resize_last_sizey) {
this.resize_widget(this.$resized_widget, size_x, size_y, false);
this.resize_widget(this.$resized_widget, size_x, size_y);
this.$resize_preview_holder.css({
'width': '',
@@ -3082,7 +3170,7 @@
fn.get_cells_occupied = function(el_grid_data) {
var cells = { cols: [], rows: []};
var i;
if (arguments[1] instanceof jQuery) {
if (arguments[1] instanceof $) {
el_grid_data = arguments[1].coords().grid;
}
@@ -3166,7 +3254,7 @@
var cr, max;
var action = type + '/' + direction;
if (arguments[2] instanceof jQuery) {
if (arguments[2] instanceof $) {
var el_grid_data = arguments[2].coords().grid;
col = el_grid_data.col;
row = el_grid_data.row;
@@ -3250,26 +3338,23 @@
fn.get_highest_occupied_cell = function() {
var r;
var gm = this.gridmap;
var rows = [];
var rl = gm[1].length;
var rows = [], cols = [];
var row_in_col = [];
for (var c = gm.length - 1; c >= 1; c--) {
for (r = gm[c].length - 1; r >= 1; r--) {
for (r = rl - 1; r >= 1; r--) {
if (this.is_widget(c, r)) {
rows.push(r);
row_in_col[r] = c;
cols.push(c);
break;
}
}
}
var highest_row = Math.max.apply(Math, rows);
this.highest_occupied_cell = {
col: row_in_col[highest_row],
row: highest_row
return {
col: Math.max.apply(Math, cols),
row: Math.max.apply(Math, rows)
};
return this.highest_occupied_cell;
};
@@ -3305,9 +3390,34 @@
* @method set_dom_grid_height
* @return {Object} Returns the instance of the Gridster class.
*/
fn.set_dom_grid_height = function() {
var r = this.get_highest_occupied_cell().row;
this.$el.css('height', r * this.min_widget_height);
fn.set_dom_grid_height = function(height) {
if (typeof height === 'undefined') {
var r = this.get_highest_occupied_cell().row;
height = r * this.min_widget_height;
}
this.container_height = height;
this.$el.css('height', this.container_height);
return this;
};
/**
* Set the current width of the parent grid.
*
* @method set_dom_grid_width
* @return {Object} Returns the instance of the Gridster class.
*/
fn.set_dom_grid_width = function(cols) {
var width;
if (typeof cols === 'undefined') {
cols = this.get_highest_occupied_cell().col;
}
cols = Math.min(this.options.max_cols,
Math.max(cols, this.options.min_cols));
this.container_width = cols * this.min_widget_width;
this.$el.css('width', this.container_width);
return this;
};
@@ -3509,8 +3619,9 @@
fn.add_faux_cols = function(cols) {
var actual_cols = this.cols;
var max_cols = actual_cols + (cols || 1);
max_cols = Math.min(max_cols, this.options.max_cols);
for (var c = actual_cols; c < max_cols; c++) {
for (var c = actual_cols + 1; c <= max_cols; c++) {
for (var r = this.rows; r >= 1; r--) {
this.add_faux_cell(r, c);
}
@@ -3573,7 +3684,6 @@
*/
fn.generate_grid_and_stylesheet = function() {
var aw = this.$wrapper.width();
var ah = this.$wrapper.height();
var max_cols = this.options.max_cols;
var cols = Math.floor(aw / this.min_widget_width) +
@@ -3588,28 +3698,23 @@
var min_cols = Math.max.apply(Math, actual_cols);
this.cols = Math.max(min_cols, cols, this.options.min_cols);
if (max_cols !== Infinity && max_cols >= min_cols && max_cols < this.cols) {
this.cols = max_cols;
}
// get all rows that could be occupied by the current widgets
var max_rows = this.options.extra_rows;
this.$widgets.each(function(i, w) {
max_rows += (+$(w).attr('data-sizey'));
});
this.cols = Math.max(min_cols, cols, this.options.min_cols);
if (max_cols && max_cols >= min_cols && max_cols < this.cols) {
this.cols = max_cols;
}
this.rows = Math.max(max_rows, this.options.min_rows);
this.baseX = ($(window).width() - aw) / 2;
this.baseY = this.$wrapper.offset().top;
// left and right gutters not included
this.container_width = (this.cols *
this.options.widget_base_dimensions[0]) + ((this.cols - 1) * 2 *
this.options.widget_margins[0]);
if (this.options.autogenerate_stylesheet) {
this.generate_stylesheet();
}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "gridster",
"title": "gridster.js",
"description": "a drag-and-drop multi-column jQuery grid plugin",
"version": "0.2.1",
"version": "0.3.0",
"homepage": "http://gridster.net/",
"author": {
"name": "ducksboard",