how to enforce draggable() object to fixed position
I'm using the jquery library these days. It is quite good designed, I believe. But sometimes you would feel it lacks what you'd like to do, especially it is in the very localized problem.
I recommend you to read the original code in such case. The jquery code feeds you very good code reading experience.
So, I was stucked in jquery.ui.draggable. The problem was draggable options "grid" doesn't behave as I expected. My element object was located (x, y) = (52, 110) for example, and told $("#obj").draggable({grid: [2, 2]}) but it moves around like (53, 108), (51, 109)... and so on. Doesn't it mean snap to the grid I told?? I expected the element will be (x, y) = (even, even). The ui.draggable.js 5194 says
drag: function(e) { //Compute the helpers position this.position = { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left }; this.positionAbs = { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top }; //Call plugins and callbacks this.checkConstrains(); this.position = this.propagate("drag", e) || this.position; this.checkConstrains(); $(this.helper).css({ left: this.position.left+'px', top: this.position.top+'px' }); // Stick the helper to the cursor if($.ui.ddmanager) $.ui.ddmanager.drag(this, e); return false;
around lines 224-238. The essence is
this.position = this.propagate("drag", e) || this.position; this.checkConstrains(); $(this.helper).css({ left: this.position.left+'px', top: this.position.top+'px' }); // Stick the helper to the cursor
which tells you that jquery calls your option-drag function and sets the returned value to its position property if any, then check constraints like bounding box and updates actual css position of the element.
I wrote like:
var scale = 2; $("#obj").draggable({ // grid: [scale, scale], drag: function(e, ui){ self.config.x = parseInt(ui.position.left / scale); self.config.y = parseInt(ui.position.top / scale); /* this is actually used for the element positions */ return { top: self.config.y * scale, left: self.config.x * scale}; } });
so that the updated position (x, y) must be (even, even).
Hack jquery!