Я придумал что-то, что не соответствует вашим потребностям, насколько я могу судить, но это может быть началом: http://jsfiddle.net/eGjak/2/.
var ctx = $('#cv').get(0).getContext('2d');
$('body').bind('selectstart', function() {return false});
var Circle = function() {
this.x = Math.random() * 400;
this.y = Math.random() * 400;
this.c = 'rgb(' + Math.floor(Math.random() * 256) + ',' +
Math.floor(Math.random() * 256) + ',' +
Math.floor(Math.random() * 256) + ')';
};
var circles = [];
function d(xp, yp, x, y) {
return Math.sqrt((x-xp)*(x-xp) + (y-yp)*(y-yp));
}
$('button').click(function() {
circles.push(new Circle);
render();
});
var currindex = -1;
$('#cv').mousedown(function(e) {
bx = e.offsetX, by = e.offsetY;
for(var i = 0; i < circles.length; i++) {
if(d(circles[i].x, circles[i].y, e.offsetX, e.offsetY) < 50) {
currindex = i;
tx = circles[i].x;
ty = circles[i].y;
}
}
});
var bx = 0, by = 0, tx = 0, ty = 0;
$('#cv').mouseup(function(e) {
currindex = -1;
});
$('#cv').mousemove(function(e) {
if(currindex > -1) {
circles[currindex].x = tx + (e.offsetX - bx);
circles[currindex].y = ty + (e.offsetY - by);
}
render();
});
function render() {
ctx.clearRect(0, 0, 400, 400);
for(var i = 0; i < circles.length; i++) {
ctx.beginPath();
ctx.arc(circles[i].x, circles[i].y, 50, 0, Math.PI*2);
ctx.fillStyle = circles[i].c;
ctx.fill();
}
}