Jump to content


[partially solved] Draggable: Drag a copy of an image into a div, move back if dropped elsewhere

Recommended Posts

Hey there,


I'm sorry if this question (or something similar) has been answered before, but I didn't find a way to search through the forum.


I need to be able to drag an image (or the link it is in) out of a list of images, but leave the original image visually there. On dropping, I want to see where it is dropped, and if it is an a special area, just use an individual property (data-img-path) to create an img tag there. And if it is dropped outside this special area, I need exactly nothing to happen, the original image always stays at it's original location.



I have done this with jQuery without problems, but that doesn't work on mobile (touch) devices, and that's why I came to using GSAP with Draggable, but I can't find out how to do this.

Thanks a lot in advance!


Kind regards


Edited by XM624
Link to comment
Share on other sites

Welcome to the GreenSock community, @XM624


14 minutes ago, XM624 said:

I'm sorry if this question (or something similar) has been answered before, but I didn't find a way to search through the forum.

There's a search icon in the upper right corner (magnifying glass) - just click that, type in your terms, and hit submit :)


What you're asking is totally doable. Have you read the docs yet? https://greensock.com/docs/v3/Plugins/Draggable


There are links in the docs to "how to" demos and showcase ones too. Maybe this one can get you going in the right direction: 

See the Pen JvjLyg by GreenSock (@GreenSock) on CodePen


Good luck!

  • Like 4
Link to comment
Share on other sites

this demo by @OSUblake may help with some of it.


See the Pen XJQKVX by osublake (@osublake) on CodePen


it looks like you would have to add code that leaves the original in place.


this pen by @Rodrigo shows how to make copies of the thing you are dragging, maybe it will help as well. Drag the numbered blue divs around.


See the Pen mJqwZq by rhernando (@rhernando) on CodePen

  • Like 6
Link to comment
Share on other sites

Thanks a lot for the hints, I came a decent way with them.

But there still are some problems to overcome:

  • I can NOT use display:block; on my draggable elements, because they need to line up on different screen resolutions (desktop, mobile),
  • on initiating with Draggable(), it moves the images into the viewport, destroying my design if their parent element is partially off screen,
  • I cannot get an element's copy to be dragged, so I did without it, but now I need to move back the element on drag end, which I currently can only get done by reloading the images (removing or resetting the filter:translate3d only works partially as it picks up the new position on a new dragstart),

Following is the part of the code in question:

function reloadImages() {
    $('#UploadForm').attr('action', '{UPLOADFORM_ACTION}' + $('#Directory').val().replace(/\//g, '%2F') + '%2F');
        url: $('#ReviewForm').attr('action'),
        type: 'get',
        data: 'images-only=' + $('#Directory').val(),
        success: function(data) {
            $('#OwnFiles a').remove();
            Draggable.create('#OwnFiles a', {
                type: 'x,y',
                bounds: window,
                onClick: function(e) {
                    if (e.button == 0) {
                        var textarea = $('#Content')[0];
                        var url = e.target.attributes['data-img-path']['nodeValue'];
                        var scrollTop = textarea.scrollTop;
                        var scrollLeft = textarea.scrollLeft;
                        if ((url != '') && (url != null)) {
                            if (document.selection) {
                                var sel = document.selection.createRange();
                                sel.text = '[img]' + url + '[/img]';
                            } else {
                                var len = textarea.value.length;
                                var start = textarea.selectionStart;
                                var end = textarea.selectionEnd;
                                var sel = textarea.value.substring(start, end);
                                var rep = '[img]' + url + '[/img]';
                                textarea.value =  textarea.value.substring(0, start) + rep + textarea.value.substring(end, len);
                                textarea.scrollTop = scrollTop;
                                textarea.scrollLeft = scrollLeft;
                                textarea.selectionStart = (start + rep.length);
                                textarea.selectionEnd = (start + rep.length);
                onDragStart: function() {
                    imgUrl = this.target.attributes['data-img-path']['nodeValue'];
                onDragEnd: function(e) {
                    if (this.hitTest('#GalleryImagePreview')) {
                        $('#GalleryImagePreview').html('<img src="' + imgUrl + '" alt="" />');
                    $('#OwnFiles a').css('transform', 'translate3d(0px, 0px, 0px)');

(yes, I do need the click event too).

Does anyone have a solution for these problems?

Thanks in advance!

Link to comment
Share on other sites

Can you create a minimal demo showing just the issues you're having? With the snippet you posted there isn't much we can do.



Finally it seems that you're having a few issues with CSS, which is definitely not a GSAP-related issue, perhaps you could try using flexbox or css grids to see how it works in that setup.


Happy Tweening!!!

  • Like 1
Link to comment
Share on other sites

Unfortunately, I can't provide a demo through CodePen, as the website in question uses Ajax to load the images after the page is ready (this is because of the possibility to switch directories).

I now created a temporary user account on my new website and already uploaded some images for testing purposes.

The page for testing: (removed)

.htaccess access data: (removed)

On (re)loading the page, the images get repositioned by GSAP Draggable to fit inside the browser window, which is NOT what I want.

This is even worse on mobile devices (or the mobile testing mode of the desktop browser, I use Brave and Firefox).


About the page:
This is the editor page of a reviews website.

Klicking an image inserts it in the editor textarea including BBCode code.

Dragging an image to the "Gallery image" drop area shows it there, this image is used for list views of available reviews.


Dragging an image should just copy it's address, which already works, as the image get's shown.

After dragging, the image must return to it's original position while making it draggable again without offset.


I hope this helps a little on understanding the problems.

Edited by XM624
Removed access to non-ready website
Link to comment
Share on other sites

Sorry, but there isn't much I can do with the sample you provide since there isn't a way to tinker with the code.


You can create a sample in codepen using jQuery ajax and get some dumy images from unsplash:

  url: "https://images.unsplash.com/photo-1548366086-7f1b76106622?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=624&q=80",
  crossDomain: true

I just tested that code in codepen and I don't get any errors.

  • Like 5
Link to comment
Share on other sites

Finally got it running:

See the Pen XWpaKMw by XM624 (@XM624) on CodePen

As you can see, just after loading the images, they move up a bit to enter the viewport:


Thanks for your patience!

Link to comment
Share on other sites



Thanks for the live sample, it was quite helpful.


The issue is being cause by the bounds you're setting for the Draggable instances, when you remove that it actually works as expected. What I'm seeing is that if a specific percentage of the Draggable instance target, in this case the <a> tag wrapping the image, is not in the viewport, GSAP enforces that at least that portion of the element is within the established bounds by adding a translate3d style to the element. I don't know if this is by design or not, perhaps @GreenSock or @OSUblake could clarify that for us. Considering the fact that you set the bounds to be the window object, is completely logical that the elements are out of position.


In the mean time, remove those bounds and create a new set of bounds. Perhaps wrap your form elements or do something like the codepen created by Blake that @Carl linked above in this thread.


Happy Tweening!!!

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

Thanks a lot, that was the problem!

As for my understanding, one can restrict the movement with the bounds setting.

To me "window" would mean the whole page, but as I'm writing this, it comes to me that that would be something like "page" (or nothing at all).

I removed that setting from my website's code and it works as expected.

Thanks again, now this is perfectly usable :wub:

Link to comment
Share on other sites

  • XM624 changed the title to [partially solved] Draggable: Drag a copy of an image into a div, move back if dropped elsewhere
15 minutes ago, XM624 said:

To me "window" would mean the whole page, but as I'm writing this, it comes to me that that would be something like "page" (or nothing at all).

Yeah the window object can be a tricky thing to grasp, but in order to simplify it if you check the properties innerHeight and innerWidth of the window, you'll see that those are basically the dimensions of the browser where the content is actually rendered (including the scroll bars), so those are basically the bounds being applied.




Perhaps you could try the body tag in the document object. Although I wouldn't recommend it is finally up to you to make that decision:




Happy Tweening!!!

  • Like 4
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.