Dragging and Dropping onto a scaled element
If I understand your goal correctly, there are a number of things you need to take care of.
1. The relative position
When the parent of an HTML element changes (i.e. the element is appended to some other element), its position on the screen changes, unless it position
property is fixed
(which is not the default).
So when you append your div
to $('.formBackground')
(I'm just gonna call it formBackground
), its position becomes relative to its previous sibling, or, if there is no previous sibling, to formBackground
itself.
To work around this, you have to subtract the offset of formBackground
from the offset of the draggable.
Additionally you need to set position
to absolute
, so the draggable is always rendered relative to formBackground
instead of the previous draggable.
The CSS position
property is explained here.
To do that, remove this passage (lines 19-22 in your fiddle):
$(objName).css({
"left": pos.left,
"top": pos.top
});
And instead add the following passage after element.addClass("tempclass");
(currently line 43):
element.css({
"position": "absolute",
"left": ui.offset.left - $(this).offset().left,
"top": ui.offset.top - $(this).offset().top
});
The next thing to take care of is:
2. The offset scaling
If now you would set var percent = 1.0;
in line 1, the draggable should stay exactly where is it.
With any other factor however, it will not, since its offset is multiplied too.
The CSS transform
property and its scale()
value are explained here, however the documentation does not mention that this applies to the offset of an object too, it just seems to be that way.
You can simply edit the snippet above to divide left
and top
by percent
:
element.css({
"position": "absolute",
"left": (ui.offset.left - $(this).offset().left) / percent,
"top": (ui.offset.top - $(this).offset().top) / percent
});
Now the upper left corner of the draggable should always stay where you drop it, regardless of what percent
is set to.
I forked and edited your fiddle to reflect these two changes. Since I do not have 10 reputation yet, I cannot post more than 2 links, but here it is anyway: http://jsfiddle.net/n7yns9eq/2/
3. (Optional) The top-left-anchored transformation
I find it a bit more user-friendly to make the "point of reference" for elements their center instead of their upper left corner. It seems more intuitive to me. If you find that too, here's how to do it:
From left
/top
you have to subtract half of the amount by width
/height
will increase. In code:
element.css({
"position": "absolute",
"left": (ui.offset.left - $(this).offset().left - $(ui.draggable).width() * (percent - 1) / 2) / percent,
"top": (ui.offset.top - $(this).offset().top - $(ui.draggable).height() * (percent - 1) / 2) / percent
});
Note that instead of $(ui.draggable)
you can not use element
, because element
has not been rendered at this point and since it has no explicit value set for height
, element.height()
will return 0
.
Fiddle: http://jsfiddle.net/9xbgqdeo/1/
4. Dead areas and non-proportional moving
Another problem I noticed was that now, if you drop a draggable in the lower of leftmost third of formBackground
, the drop doesn't happen. I don't know if this is caused by the browser engine (not resizing the functional area of an object) or by jquery (disregarding transformations).
The only way I can think of to work around this is to make body
droppable instead of formBackground
, check if it is within the borders of formBackground
and if yes, append it there, discard it otherwise.
Note that for this to work if your page does not fill the whole browser window, you'd have to set the following CSS:
html, body {
width: 100%;
height: 100%;
}
And don't forget to replace every this
in the droppable function with $('.formBackground')
.
In addition, when grabbing an existing draggable from formBackground
and moving it around, it drifts away from the cursor, which I consider unwanted. To prevent this I suggest moving the div back to its original parent and reverting the offset changes that were made when it was dropped on formBackground
.
I'm honestly too lazy to provide fiddles for those two changes now (edit: http://jsfiddle.net/gtc17z6b/1/
), but I hope this solves your question anyway.