Welcome to the forums,
Thanks for the demo, and congrats on getting it pretty close to what you needed.
The tricky thing here is that when you are dragging you are using "x,y" but you are using offset() to determine the natural position of the elements on the page which returns left and top. Of course, only after finishing the demo did I consider switching the draggable type to "left,top". That may save some trouble, but I'm not sure.
Anyway one component of this challenge is that in order to animate the elements back to their "normal" or start position you need to remember what that is.
I store a startPos object on each element with
draggables.each(function(index, element){
element.startPos = $(element).offset();
console.log(element.startPos)
})
When I detect that the dragged element is in the "dropzone" I use this calculation to tween it to the dropzone. Its important to figure out the action targets offset minus the draggable's offset. We also need to zero out the x and y as they have changed while dragging
TweenLite.to(this.target, 0.3, {
left: (actionTarget.offset().left - this.target.startPos.left),
top: (actionTarget.offset().top - this.target.startPos.top),
x:0,
y:0,
scale:0.8,
});
I'm changing the scale as it allows us to still see the active yellow border of the dropzone.
When you detect that the dragged item is NOT in the dropzone, we send it back home using:
TweenLite.to(this.target, 1, {x: 0, left:0, y: 0, top:0, scale:1});
I don't know if dragging using "x,y" performs so much better than "left,top" that its worth the hassle tweening and resetting both x, y, left and top in each tween. As I suspected (too late) if you just switch the Draggable type to "left, top", it will work fine and you don't have to worry about x and y.
IMPORTANT
The functionality for both demos works fine at any screen size and the boxes can be in one row or multiple rows.
However, if you resize the window and change the flow AFTER the page loads it will get entirely messed up as you are changing the relative offsets of the draggables start positions and drop zone.
If resizing is important to you, you may want to look into another approach, like FLIP (first, last, invert, play).
This technique, although not using those terms, is described by @OSUblake here:
You can also Google Flip Animations and probably find a lot about how the technique is used with other animation engines, but the core principles of how it works remain the same regardless of animation engine.
https://aerotwist.com/blog/flip-your-animations/
The basic idea is that since you are changing the flow of the document, you need to figure out where elements should go based on that new flow. You can only determine that if you place your elements where they should be before you animate them to there.
Hopefully the demos above get you closer to what you need as the main calculations and hooks are in place.