I just spent a couple of hours smashing my head against the wall to try and do this work reliably, so I decided to post a solution :)
Question: Draggable cannot set cursorAt to drag "clone" during instance creation for dynamic values (ie Center of draggable proxy of variable size) because ui.helper has not been created yet! You can install it inside the launch handler, but it will not work for the first drag and drop.
Solution: Position the cursor inside the beginning, but ALSO manually override ui.position for the drag event that happens continuously. Using firstRun boolean, you can not run it unnecessarily. You must set the default cursorAt in the upper left corner to move.
Enjoy it!
$jobs.each( function( index, element ) { var $el = $(element), firstRun = true; /* * jQuery UI Draggable * See @link: http://api.jqueryui.com/draggable/ * * Note that for clone drags, the first drag cannot center the proxy because ui.helper hasn't been created yet * so need to set it manually for first drag. Subsequent drags can use the cursorAt property. * See my @link: */ $el.draggable({ cursorAt : [0, 0], // Set origin then update dynamically drag : function( evt, ui ) { // Fires after start event, and continuously during drag if ( firstRun ) { // Reset proxy position here since cursorAt cannot be set for ui.position.left -= Math.floor( ui.helper.width()/ 2 ); ui.position.top -= Math.floor( ui.helper.height()/ 2 ); }; }, helper : 'clone', start : function( evt, ui ) { // Fires once if ( firstRun ) { // Center proxy relative to cursor for future drags $(this).draggable( 'option', 'cursorAt', { left : Math.floor( ui.helper.width()/ 2 ), top : Math.floor( ui.helper.height()/ 2 ) }); }; // Set cursor ( 'cursor' option just applies style to <body> ) ui.helper.css( 'cursor', 'move' ); }, stop : function( evt, ui ) { // Fires once if ( firstRun ) { firstRun = false; }; } });
source share