Я использовал решения Tuze и Yusuf Demirag и добавил кое-что для перетаскивания по сетке:
var gridSize = 20;
$('#dragme').draggable({
grid: [ gridSize , gridSize ],
snap: true,
snapTolerance: gridSize/2,
drag: function(event,ui){
var factor = (1 / zoom) -1;
ui.position.top += Math.round((ui.position.top - ui.originalPosition.top) * factor);
ui.position.top -= ui.position.top % gridSize;
ui.position.left += Math.round((ui.position.left- ui.originalPosition.left) * factor);
ui.position.left -= ui.position.left % gridSize;
if (ui.position.left < 0)
ui.position.left = 0;
if (ui.position.left + $(this).width() > canvasWidth)
ui.position.left = canvasWidth - $(this).width();
if (ui.position.top < 0)
ui.position.top = 0;
if (ui.position.top + $(this).height() > canvasHeight)
ui.position.top = canvasHeight - $(this).height();
}
});
В нем есть небольшая ошибка (иногда он не может получить точное значение, например: 160px), но он работал для того, что мне было нужно.
Надеюсь, это поможет.