Permalink
Browse files

Adding more options

  • Loading branch information...
1 parent 3b76f2a commit a5ad6b30d486c497bdcab235d82be738e91b64d6 @McPants committed Apr 10, 2013
Showing with 222 additions and 165 deletions.
  1. +44 −0 Shapeshift.jquery.json
  2. +96 −81 core/jquery.shapeshift.coffee
  3. +82 −78 core/jquery.shapeshift.js
  4. +0 −3 demo/assets/demo.coffee
  5. +0 −3 demo/assets/demo.js
View
44 Shapeshift.jquery.json
@@ -0,0 +1,44 @@
+{
+ "name": "Shapeshift",
+ "title": "jQuery Shapeshift",
+ "description": "jQuery plugin which can arrange a collection of elements into a grid while also providing drag and drop functionality.",
+ "keywords": [
+ "grid",
+ "drag",
+ "drop",
+ "arrange",
+ "organize",
+ "animation"
+ ],
+ "version": "2.0.0",
+ "author": {
+ "name": "Scott Elwood",
+ "url": "http://scottelwood.com"
+ },
+ "maintainers": [
+ {
+ "name": "We the Media, inc.",
+ "email": "dev@wtmworldwide.com",
+ "url": "http://wtmworldwide.com"
+ },
+ {
+ "name": "Scott Elwood",
+ "email": "scott@wtmworldwide.com",
+ "url": "http://scottelwood.com"
+ }
+ ],
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "https://github.com/McPants/jquery.shapeshift/blob/master/LICENSE"
+ }
+ ],
+ "bugs": "https://github.com/McPants/jquery.shapeshift/issues",
+ "homepage": "https://github.com/McPants/jquery.shapeshift",
+ "docs": "https://github.com/McPants/jquery.shapeshift",
+ "download": "https://github.com/McPants/jquery.shapeshift",
+ "dependencies": {
+ "jquery": ">=1.9.0",
+ "jquery-ui": ">=1.10.0"
+ }
+}
View
177 core/jquery.shapeshift.coffee
@@ -9,6 +9,7 @@
defaults =
# Features
enableDrag: true
+ enableCrossDrop: true
enableResize: true
# Grid Properties
@@ -21,20 +22,28 @@
minHeight: 100
gutterX: 10
gutterY: 10
- paddingX: 0
+ paddingX: 10
paddingY: 10
# Animation
animated: true
- animateOnInit: false
- animationSpeed: 150
- animationThreshold: 200
+ animateOnInit: true
+ animationSpeed: 225
+ animationThreshold: 100
# Drag/Drop Options
dragRate: 120
+ dragWhitelist: "*"
+ crossDropWhitelist: "*"
+ cutoffStart: null
+ cutoffEnd: null
+
+ # Customize CSS
activeClass: "ss-active-child"
draggedClass: "ss-dragged-child"
placeholderClass: "ss-placeholder-child"
+ currentContainerClass: "ss-current-container"
+ previousContainerClass: "ss-previous-container"
# Other Options
selector: ""
@@ -107,7 +116,7 @@
# ----------------------------
enableFeatures: ->
@enableResize() if @options.enableResize
- @enableDragNDrop() if @options.enableDrag
+ @enableDragNDrop() if @options.enableDrag or @options.enableCrossDrop
# ----------------------------
# setActiveChildren:
@@ -407,104 +416,109 @@
active_class = options.activeClass
dragged_class = options.draggedClass
placeholder_class = options.placeholderClass
+ current_container_class = options.currentContainerClass
+ previous_container_class = options.previousContainerClass
drag_rate = options.dragRate
$selected = $placeholder = selected_offset_y = selected_offset_x = null
dragging = false
- $container.children("." + active_class).draggable
- addClasses: false
- containment: 'document'
- zIndex: 9999
-
- start: (e, ui) -> start(e, ui)
- drag: (e, ui) -> drag(e, ui)
- stop: -> stop()
-
- start = (e, ui) ->
- # Set $selected globals
- $selected = $(e.target)
- $selected.addClass(dragged_class)
+ if options.enableDrag
+ $container.children("." + active_class).filter(options.dragWhitelist).draggable
+ addClasses: false
+ containment: 'document'
+ zIndex: 9999
+
+ start: (e, ui) ->
+ # Set $selected globals
+ $selected = $(e.target)
+ $selected.addClass(dragged_class)
+
+ # Create Placeholder
+ selected_tag = $selected.prop("tagName")
+ $placeholder = $("<#{selected_tag} class='#{placeholder_class}' style='height: #{$selected.height()}; width: #{$selected.width()}'></#{selected_tag}>")
+
+ # Set current container
+ $selected.parent().addClass(current_container_class)
+
+ # For manually centering the element with respect to mouse position
+ selected_offset_y = $selected.outerHeight() / 2
+ selected_offset_x = $selected.outerWidth() / 2
+
+ drag: (e, ui) =>
+ if !dragging
+ # Append placeholder to container
+ $placeholder.remove().appendTo("." + current_container_class)
+
+ # Set drag target and rearrange everything
+ $("." + current_container_class).trigger("ss-setTargetPosition")
+
+ # Disallow dragging from occurring too much
+ dragging = true
+ window.setTimeout ( ->
+ dragging = false
+ ), drag_rate
+
+ # Manually center the element with respect to mouse position
+ ui.position.left = e.pageX - $selected.parent().offset().left - selected_offset_x;
+ ui.position.top = e.pageY - $selected.parent().offset().top - selected_offset_y;
+
+ stop: ->
+ # Clear globals
+ $selected.removeClass(dragged_class)
+ $placeholder.remove()
+ $selected = $placeholder = null
+
+ # Arrange dragged item into place
+ $("." + current_container_class).trigger("ss-arrange").removeClass(current_container_class)
+ $("." + previous_container_class).trigger("ss-arrange").removeClass(previous_container_class)
- # Create Placeholder
- selected_tag = $selected.prop("tagName")
- $placeholder = $("<#{selected_tag} class='#{placeholder_class}' style='height: #{$selected.height()}; width: #{$selected.width()}'></#{selected_tag}>")
- # Set current container
- $selected.parent().addClass("ss-current-container")
-
- # For manually centering the element with respect to mouse position
- selected_offset_y = $selected.outerHeight() / 2
- selected_offset_x = $selected.outerWidth() / 2
-
- drag = (e, ui) =>
- if !dragging
- # Append placeholder to container
- $placeholder.remove().appendTo(".ss-current-container")
-
- # Set drag target and rearrange everything
- $(".ss-current-container").trigger("ss-setTargetPosition")
-
- # Disallow dragging from occurring too much
- dragging = true
- window.setTimeout ( ->
- dragging = false
- ), drag_rate
-
- # Manually center the element with respect to mouse position
- ui.position.left = e.pageX - $selected.parent().offset().left - selected_offset_x;
- ui.position.top = e.pageY - $selected.parent().offset().top - selected_offset_y;
-
- stop = ->
- # Clear globals
- $selected.removeClass(dragged_class)
- $placeholder.remove()
- $selected = $placeholder = null
-
- # Arrange dragged item into place
- $(".ss-current-container").trigger("ss-arrange").removeClass("ss-current-container")
- $(".ss-previous-container").trigger("ss-arrange").removeClass("ss-previous-container")
-
- $container.droppable
- tolerance: 'intersect'
- over: (e) -> over(e)
-
- over = (e) =>
- $(".ss-previous-container").removeClass("ss-previous-container")
- $(".ss-current-container").removeClass("ss-current-container").addClass("ss-previous-container")
- $(e.target).addClass("ss-current-container")
+ if options.enableCrossDrop
+ $container.droppable
+ accept: options.crossDropWhitelist
+ tolerance: 'intersect'
+ over: (e) =>
+ $("." + previous_container_class).removeClass(previous_container_class)
+ $("." + current_container_class).removeClass(current_container_class).addClass(previous_container_class)
+ $(e.target).addClass(current_container_class)
+
# ----------------------------
# getTargetPosition:
# Determine the target position for the selected
# element and arrange it into place
# ----------------------------
setTargetPosition: ->
- dragged_class = @options.draggedClass
- $selected = $("." + dragged_class)
- selected_x = $selected.position().left + $selected.width() / 2
- selected_y = $selected.position().top + $selected.height() / 2
- shortest_distance = 9999999
+ options = @options
+ dragged_class = options.draggedClass
+ $selected = $("." + dragged_class)
$start_container = $selected.parent()
parsed_children = @parsedChildren
child_positions = @getPositions()
total_positions = child_positions.length
+
+ selected_x = $selected.offset().left - $start_container.offset().left + ($selected.width() / 2)
+ selected_y = $selected.offset().top - $start_container.offset().top + ($selected.height() / 2)
+ shortest_distance = 9999999
target_position = 0
- for position_i in [0...total_positions]
+ cutoff_start = options.cutoffStart || 0
+ cutoff_end = options.cutoffEnd || total_positions
+
+ for position_i in [cutoff_start...cutoff_end]
attributes = child_positions[position_i]
- if selected_x > attributes.left and selected_y > attributes.top
- y_dist = selected_x - attributes.left
- x_dist = selected_y - attributes.top
+ y_dist = selected_x - attributes.left
+ x_dist = selected_y - attributes.top
- distance = Math.sqrt((x_dist * x_dist) + (y_dist * y_dist))
+ distance = Math.abs(Math.sqrt((x_dist * x_dist) + (y_dist * y_dist)))
- if distance < shortest_distance
- shortest_distance = distance
- target_position = position_i
+ if distance < shortest_distance
+ shortest_distance = distance
+ target_position = position_i
if target_position is parsed_children.length
$target = parsed_children[target_position - 1].el
@@ -516,7 +530,8 @@
@arrange(true)
if $start_container[0] isnt $selected.parent()[0]
- $(".ss-previous-container").trigger "ss-rearrange"
+ previous_container_class = options.previousContainerClass
+ $("." + previous_container_class).trigger "ss-rearrange"
# ----------------------------
# resize:
@@ -534,13 +549,13 @@
resizing = true
# Some funkyness to prevent too many renderings
- setTimeout (=> @render()), animation_speed / 2
- setTimeout (=> @render()), animation_speed
+ setTimeout (=> @render()), animation_speed / 3
+ setTimeout (=> @render()), animation_speed / 3
setTimeout =>
resizing = false
@render()
- , animation_speed * 1.5
+ , animation_speed / 3
# ----------------------------
View
160 core/jquery.shapeshift.js
@@ -6,6 +6,7 @@
pluginName = "shapeshift";
defaults = {
enableDrag: true,
+ enableCrossDrop: true,
enableResize: true,
align: "center",
autoHeight: true,
@@ -16,16 +17,22 @@
minHeight: 100,
gutterX: 10,
gutterY: 10,
- paddingX: 0,
+ paddingX: 10,
paddingY: 10,
animated: true,
- animateOnInit: false,
- animationSpeed: 150,
- animationThreshold: 200,
+ animateOnInit: true,
+ animationSpeed: 225,
+ animationThreshold: 100,
dragRate: 120,
+ dragWhitelist: "*",
+ crossDropWhitelist: "*",
+ cutoffStart: null,
+ cutoffEnd: null,
activeClass: "ss-active-child",
draggedClass: "ss-dragged-child",
placeholderClass: "ss-placeholder-child",
+ currentContainerClass: "ss-current-container",
+ previousContainerClass: "ss-previous-container",
selector: ""
};
Plugin = (function() {
@@ -82,7 +89,7 @@
if (this.options.enableResize) {
this.enableResize();
}
- if (this.options.enableDrag) {
+ if (this.options.enableDrag || this.options.enableCrossDrop) {
return this.enableDragNDrop();
}
};
@@ -324,94 +331,90 @@
};
Plugin.prototype.enableDragNDrop = function() {
- var $container, $placeholder, $selected, active_class, drag, drag_rate, dragged_class, dragging, options, over, placeholder_class, selected_offset_x, selected_offset_y, start, stop,
+ var $container, $placeholder, $selected, active_class, current_container_class, drag_rate, dragged_class, dragging, options, placeholder_class, previous_container_class, selected_offset_x, selected_offset_y,
_this = this;
options = this.options;
$container = this.$container;
active_class = options.activeClass;
dragged_class = options.draggedClass;
placeholder_class = options.placeholderClass;
+ current_container_class = options.currentContainerClass;
+ previous_container_class = options.previousContainerClass;
drag_rate = options.dragRate;
$selected = $placeholder = selected_offset_y = selected_offset_x = null;
dragging = false;
- $container.children("." + active_class).draggable({
- addClasses: false,
- containment: 'document',
- zIndex: 9999,
- start: function(e, ui) {
- return start(e, ui);
- },
- drag: function(e, ui) {
- return drag(e, ui);
- },
- stop: function() {
- return stop();
- }
- });
- start = function(e, ui) {
- var selected_tag;
- $selected = $(e.target);
- $selected.addClass(dragged_class);
- selected_tag = $selected.prop("tagName");
- $placeholder = $("<" + selected_tag + " class='" + placeholder_class + "' style='height: " + ($selected.height()) + "; width: " + ($selected.width()) + "'></" + selected_tag + ">");
- $selected.parent().addClass("ss-current-container");
- selected_offset_y = $selected.outerHeight() / 2;
- return selected_offset_x = $selected.outerWidth() / 2;
- };
- drag = function(e, ui) {
- if (!dragging) {
- $placeholder.remove().appendTo(".ss-current-container");
- $(".ss-current-container").trigger("ss-setTargetPosition");
- dragging = true;
- window.setTimeout((function() {
- return dragging = false;
- }), drag_rate);
- }
- ui.position.left = e.pageX - $selected.parent().offset().left - selected_offset_x;
- return ui.position.top = e.pageY - $selected.parent().offset().top - selected_offset_y;
- };
- stop = function() {
- $selected.removeClass(dragged_class);
- $placeholder.remove();
- $selected = $placeholder = null;
- $(".ss-current-container").trigger("ss-arrange").removeClass("ss-current-container");
- return $(".ss-previous-container").trigger("ss-arrange").removeClass("ss-previous-container");
- };
- $container.droppable({
- tolerance: 'intersect',
- over: function(e) {
- return over(e);
- }
- });
- return over = function(e) {
- $(".ss-previous-container").removeClass("ss-previous-container");
- $(".ss-current-container").removeClass("ss-current-container").addClass("ss-previous-container");
- return $(e.target).addClass("ss-current-container");
- };
+ if (options.enableDrag) {
+ $container.children("." + active_class).filter(options.dragWhitelist).draggable({
+ addClasses: false,
+ containment: 'document',
+ zIndex: 9999,
+ start: function(e, ui) {
+ var selected_tag;
+ $selected = $(e.target);
+ $selected.addClass(dragged_class);
+ selected_tag = $selected.prop("tagName");
+ $placeholder = $("<" + selected_tag + " class='" + placeholder_class + "' style='height: " + ($selected.height()) + "; width: " + ($selected.width()) + "'></" + selected_tag + ">");
+ $selected.parent().addClass(current_container_class);
+ selected_offset_y = $selected.outerHeight() / 2;
+ return selected_offset_x = $selected.outerWidth() / 2;
+ },
+ drag: function(e, ui) {
+ if (!dragging) {
+ $placeholder.remove().appendTo("." + current_container_class);
+ $("." + current_container_class).trigger("ss-setTargetPosition");
+ dragging = true;
+ window.setTimeout((function() {
+ return dragging = false;
+ }), drag_rate);
+ }
+ ui.position.left = e.pageX - $selected.parent().offset().left - selected_offset_x;
+ return ui.position.top = e.pageY - $selected.parent().offset().top - selected_offset_y;
+ },
+ stop: function() {
+ $selected.removeClass(dragged_class);
+ $placeholder.remove();
+ $selected = $placeholder = null;
+ $("." + current_container_class).trigger("ss-arrange").removeClass(current_container_class);
+ return $("." + previous_container_class).trigger("ss-arrange").removeClass(previous_container_class);
+ }
+ });
+ }
+ if (options.enableCrossDrop) {
+ return $container.droppable({
+ accept: options.crossDropWhitelist,
+ tolerance: 'intersect',
+ over: function(e) {
+ $("." + previous_container_class).removeClass(previous_container_class);
+ $("." + current_container_class).removeClass(current_container_class).addClass(previous_container_class);
+ return $(e.target).addClass(current_container_class);
+ }
+ });
+ }
};
Plugin.prototype.setTargetPosition = function() {
- var $selected, $start_container, $target, attributes, child_positions, distance, dragged_class, parsed_children, position_i, selected_x, selected_y, shortest_distance, target_position, total_positions, x_dist, y_dist, _i;
- dragged_class = this.options.draggedClass;
+ var $selected, $start_container, $target, attributes, child_positions, cutoff_end, cutoff_start, distance, dragged_class, options, parsed_children, position_i, previous_container_class, selected_x, selected_y, shortest_distance, target_position, total_positions, x_dist, y_dist, _i;
+ options = this.options;
+ dragged_class = options.draggedClass;
$selected = $("." + dragged_class);
- selected_x = $selected.position().left + $selected.width() / 2;
- selected_y = $selected.position().top + $selected.height() / 2;
- shortest_distance = 9999999;
$start_container = $selected.parent();
parsed_children = this.parsedChildren;
child_positions = this.getPositions();
total_positions = child_positions.length;
+ selected_x = $selected.offset().left - $start_container.offset().left + ($selected.width() / 2);
+ selected_y = $selected.offset().top - $start_container.offset().top + ($selected.height() / 2);
+ shortest_distance = 9999999;
target_position = 0;
- for (position_i = _i = 0; 0 <= total_positions ? _i < total_positions : _i > total_positions; position_i = 0 <= total_positions ? ++_i : --_i) {
+ cutoff_start = options.cutoffStart || 0;
+ cutoff_end = options.cutoffEnd || total_positions;
+ for (position_i = _i = cutoff_start; cutoff_start <= cutoff_end ? _i < cutoff_end : _i > cutoff_end; position_i = cutoff_start <= cutoff_end ? ++_i : --_i) {
attributes = child_positions[position_i];
- if (selected_x > attributes.left && selected_y > attributes.top) {
- y_dist = selected_x - attributes.left;
- x_dist = selected_y - attributes.top;
- distance = Math.sqrt((x_dist * x_dist) + (y_dist * y_dist));
- if (distance < shortest_distance) {
- shortest_distance = distance;
- target_position = position_i;
- }
+ y_dist = selected_x - attributes.left;
+ x_dist = selected_y - attributes.top;
+ distance = Math.abs(Math.sqrt((x_dist * x_dist) + (y_dist * y_dist)));
+ if (distance < shortest_distance) {
+ shortest_distance = distance;
+ target_position = position_i;
}
}
if (target_position === parsed_children.length) {
@@ -423,7 +426,8 @@
}
this.arrange(true);
if ($start_container[0] !== $selected.parent()[0]) {
- return $(".ss-previous-container").trigger("ss-rearrange");
+ previous_container_class = options.previousContainerClass;
+ return $("." + previous_container_class).trigger("ss-rearrange");
}
};
@@ -438,14 +442,14 @@
resizing = true;
setTimeout((function() {
return _this.render();
- }), animation_speed / 2);
+ }), animation_speed / 3);
setTimeout((function() {
return _this.render();
- }), animation_speed);
+ }), animation_speed / 3);
return setTimeout(function() {
resizing = false;
return _this.render();
- }, animation_speed * 1.5);
+ }, animation_speed / 3);
}
});
};
View
3 demo/assets/demo.coffee
@@ -32,9 +32,6 @@ $ ->
$children = $(this).children().not(".credits")
child_count = $children.length
- if child_count > 50
- type = "index"
-
if type is "index"
$(@).find(".position").show()
else
View
3 demo/assets/demo.js
@@ -33,9 +33,6 @@
var $child, $children, background, height, i, width, _i, _results;
$children = $(this).children().not(".credits");
child_count = $children.length;
- if (child_count > 50) {
- type = "index";
- }
if (type === "index") {
return $(this).find(".position").show();
} else {

0 comments on commit a5ad6b3

Please sign in to comment.