Skip to content
This repository has been archived by the owner on Dec 17, 2022. It is now read-only.

Commit

Permalink
Got draggable sets working
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Ephraim committed Oct 30, 2009
1 parent ab5c259 commit 9822846
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 24 deletions.
16 changes: 13 additions & 3 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@ window.onload = function() {
var canvas = Raphael(0,0, 500, 500);
canvas.draggable.enable();

var rect = canvas.rect(0, 0, 100, 100).
attr({ 'fill': 'white' }).
draggable.enable();
canvas.rect(0, 0, 100, 100).
attr({ 'fill': 'white' }).
draggable.enable();

var rect = canvas.rect(100, 100, 100, 100).
attr({ 'fill': 'white' });

var circle = canvas.circle(150, 150, 60);

var set = canvas.set();
set.draggable.enable();
set.push(rect);
set.push(circle);
}
48 changes: 39 additions & 9 deletions lib/raphael.draggable.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Raphael draggable plugin
// Matt Ephraim - 2009

(function() {
/* Raphael paper extensions */
Raphael.fn.draggable = {};
Expand All @@ -26,6 +25,7 @@
}

overrideElements(paper);
overrideSet(paper);
return paper;
};

Expand All @@ -41,37 +41,67 @@
var oldFunc = paper[elementType];
paper[elementType] = function() {
var element = oldFunc.apply(paper, arguments);
element.draggable = new DraggableElementExtension(element);
element.draggable = new DraggableExtension(element);
return element;
}
};
}

/* Raphael set extensions */
function overrideSet(paper) {
var oldFunc = paper.set;
paper.set = function() {
var set = oldFunc.apply(paper, arguments);
set.paper = paper;
set.draggable = new DraggableExtension(set);

overrideSetFunctions(set);
return set;
};
}

function overrideSetFunctions(set) {
var oldPushFunc = set.push;
set.push = function(element) {
oldPushFunc.apply(set, arguments);
if (element.draggable) {
element.draggable.parent = set;

if (set.draggable.enabled) {
element.draggable.enable();
}
}
}
}

/* Extension for objects that adds draggable functionality */
var DraggableElementExtension = function (element) {
var DraggableExtension = function (element) {
var paper = element.paper,
lastX,
lastY;

this.element = element;
this.enabled = false;

element.mousedown(function(event) {
if (paper.draggable.current() || !element.draggable.enabled)
return;

element.draggable.isDragging = true;

paper.draggable.current(element);
lastX = event.clientX;
lastY = event.clientY;
});

element.mousemove(function(event) {
if (element.draggable.isDragging) {
console.log(element.draggable.parent);
var toMove = element.draggable.parent || element;

var transX = event.clientX - lastX;
var transY = event.clientY - lastY;

element.translate(transX, transY);
toMove.translate(transX, transY);
lastX = event.clientX;
lastY = event.clientY;
}
Expand All @@ -86,7 +116,7 @@
}
};

DraggableElementExtension.prototype = {
DraggableExtension.prototype = {
enable: function() {
this.enabled = true;
return this.element;
Expand Down
147 changes: 136 additions & 11 deletions spec/raphael.draggable_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,26 +89,20 @@ Screw.Unit(function() {
it("adds a draggable.enable function to raphael elements", function() {
expect(jQuery.isFunction(rect.draggable.enable)).to(equal, true);
});

describe("The draggable.enable function for elements", function() {
describe("the draggable.enable function for elements", function() {
it("returns the element after being called", function() {
expect(rect.draggable.enable()).to(equal, rect);
});
});

describe("the draggable.enable function", function() {
it("sets draggable.enabled to true when is called", function() {

it("sets draggable.enabled to true when it's called", function() {
rect.draggable.enabled = false;
rect.draggable.enable();
expect(rect.draggable.enabled).to(equal, true);
});

it("returns the element after being called", function() {
expect(rect.draggable.enable()).to(equal, rect);
});
});

describe("the draggable.disable function", function() {
describe("the draggable.disable function for elements", function() {
it("sets draggable.enabled to false when called", function() {
rect.draggable.enabled = true;
rect.draggable.disable();
Expand Down Expand Up @@ -181,5 +175,136 @@ Screw.Unit(function() {
});
});
});

describe("Draggable plugin for Raphael sets", function() {
var paper;
var set;
before(function() {
paper = Raphael(0, 0, 600, 600);

overrideEventHandlerForSet(paper, 'mousedown');
overrideEventHandlerForSet(paper, 'mousemove');
overrideEventHandlerForSet(paper, 'mouseup');
overrideEventHandlerForSet(paper, 'mouseout');

paper.draggable.enable();
set = paper.set();
set.draggable.enable();
});

it("adds a draggable namespace to raphael sets", function() {
expect(set.draggable).to_not(equal, null);
});

it("adds a draggable.enable function to raphael set", function() {
expect(jQuery.isFunction(set.draggable.enable)).to(equal, true);
});

describe("The draggable.enable function for sets", function() {
it("returns the set after being called", function() {
expect(set.draggable.enable()).to(equal, set);
});

it("sets draggable.enabled to true when it's called", function() {
set.draggable.enabled = false;
set.draggable.enable();
expect(set.draggable.enabled).to(equal, true);
});
});

describe("the draggable.disable function for set", function() {
it("sets draggable.enabled to false when called", function() {
set.draggable.enabled = true;
set.draggable.disable();
expect(set.draggable.enabled).to(equal, false);
});

it("returns the set after being called", function() {
expect(set.draggable.disable()).to(equal, set);
});
});

describe("event handlers", function() {
describe("mousedown", function() {
it("sets the draggable.current() for the paper to the element", function() {
set.mousedown([{}]);
expect(paper.draggable.current()).to(equal, set);
});

it("sets the isDragging property of the element to true", function() {
set.mousedown([{}]);
expect(set.draggable.isDragging).to(equal, true);
});
});

describe("mousemove", function() {
it("translates the object by the amount that the mouse moved", function() {
var translateX, translateY;
set.translate = function(x, y) {
translateX = x;
translateY = y;
};

var startX = startY = 0;
var moveX = moveY = 15;

set.mousedown([{ clientX: startX, clientY: startY}]);
set.mousemove([{clientX: moveX, clientY: moveY}]);

expect(translateX).to(equal, moveX - startX);
expect(translateY).to(equal, moveY - startY);
});
});

describe('mouseup', function() {
it("resets the current draggable", function() {
set.mousedown([{}]);
set.mouseup();
expect(paper.draggable.current()).to(equal, null);
});

it("sets the isDragging property to false", function() {
set.mousedown([{}]);
set.mouseup();
expect(set.draggable.isDragging).to(equal, false);
});
})

describe("mouseout", function() {
it("resets the current draggable", function() {
set.mousedown([{}]);
set.mouseout();
expect(paper.draggable.current()).to(equal, null);
});

it("sets the isDragging property to false", function() {
set.mousedown([{}]);
set.mouseout();
expect(set.draggable.isDragging).to(equal, false);
});
});
});

describe("set.push function", function() {
it("adds a draggable.parent property to the element that stores the parent set", function() {
var rect = paper.rect(1,1,1,1).draggable.enable();
set.push(rect);
expect(rect.draggable.parent).to(equal, set);
});

it("enables dragability for the element", function() {
var rect = paper.rect(1,1,1,1);
set.push(rect);
expect(rect.draggable.enabled).to(equal, true);
});

it("doesn't enable dragability for the element if the set's draggability isn't enabled", function() {
var rect = paper.rect(1,1,1,1);
set.draggable.disable();
set.push(rect);
expect(rect.draggable.enabled).to(equal, false);
});
});
});
});

24 changes: 23 additions & 1 deletion spec/spec_helper.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Overrides a built in Raphael event handler so that event handlers can
// Overrides a built in Raphael event handlers for elements so that event handlers can
// be triggered during testing
function overrideEventHandler(handlerName) {
var handlerCollectionName = handlerName + "handlers";
Expand All @@ -13,4 +13,26 @@ function overrideEventHandler(handlerName) {
}
}
};
}

// Overrides a built in Raphael event handler for sets so that event handlers can
// be triggered during testing
function overrideEventHandlerForSet(paper, handlerName) {
var handlerCollectionName = handlerName + "handlers";
var oldFunc = paper.set;
paper.set = function() {
var set = oldFunc.apply(paper, arguments);
set[handlerName] = function(arg) {
if (typeof arg == 'function') {
this[handlerCollectionName] = this[handlerCollectionName] || [];
this[handlerCollectionName].push(arg);
} else {
for(var i = 0; i < this[handlerCollectionName].length; i++) {
this[handlerCollectionName][i].apply(this, arg);
}
}
};

return set;
}
}

0 comments on commit 9822846

Please sign in to comment.