views:

51

answers:

1

I want to enable drag-and-drop behaviour on my Web application. I have an image I want to drag. The image is behind another one that has transparent sections so that you can see the image beneath it. I do not want to change the order of the images. My thinking is I should use another layer on top of both images that is transparent and use it as a proxy to transfer events to the image I want to drag. jQuery UI's draggable function will not allow me to transfer the events in real-time i.e. I cannot hook into what it is doing while the drag is taking place, only when it is completed.

Is there a JavaScript library or jQuery plugin that will allow me to enable drag-and-drop on an element and have it transfer those events to another element in real-time?

+1  A: 

Maybe I don't understand what you are trying to accomplish, but you should be able to drag and drop overlapping images without any trouble (demo).

Just wrap both images in a div and then make the div draggable:

CSS (no need to make .dragme position relative, because it is done in the draggable script)

.dragme img {
 position: absolute;
 top: 0;
 left: 0;
}

HTML

<div class="dragme">
 <img src="image1.gif">
 <img src="image2.gif">
</div>

Script

$(".dragme").draggable();

I updated the demo, this isn't pretty and there might be a better way, but basically this puts an invisible overlay over the frame, then positions the image while the overlay is being dragged.

CSS

#draggable, #droppable {
 width: 450px;
 height: 250px;
 padding: 0.5em;
 margin: 10px;
 background: #ddd;
 color:#000;
}
.dragme {
 position: relative;
 width: 100px;
 padding: 5px;
}
.dragme img {
 position: absolute;
 top: 55px;
 left: 30px;
}
.demo {
 width: 500px;
}
.border {
 position: absolute;
 top: 75px;
 left: 30px;
 z-index: 1;
}

HTML

<div class="demo">
 <div class="border">
  <img src="http://www.imageuploading.net/image/thumbs/large/border-564.png"&gt;
 </div>
 <div id="draggable" class="ui-widget-content">
  <p>Drag from here</p>   
  <div class="dragme">
   <img src="http://i142.photobucket.com/albums/r117/SaltyDonut/Icons/evilpuppy.gif"&gt;
  </div>
 </div>
 <div id="droppable">
  <p>Drop here</p>
 </div>
</div>

Script (The demo uses $(document).ready because jsFiddle doesn't like $(window).load)

$(window).load(function(){
 // cycle through draggable divs (in case there are more than one)
 $(".dragme").each(function(){
  var img = $(this).find('img');
  var pos = img.position();
  // create div overlay on image
  $('<div/>', {
   class : 'overlay',
   css: {
    position: 'relative',
    top: pos.top,
    left: pos.left,
    width: img.outerWidth(),
    height: img.outerHeight(),
    zIndex: 100
   }
  })
   // save original image position
   .data('pos', [pos.left, pos.top])
   .appendTo($(this));

  // make overlay draggable
  $(this).find('.overlay').draggable({
   containment : '.demo',
   revert: true,
   revertDuration: 0,
   handle: 'div',
   // drag overlay and image
   drag: function(e,ui){
    img = $(this).parent().find('img');
    img.css({
     top: ui.position.top,
     left: ui.position.left
    });
   },
   // make image revert
   stop: function(e,ui){
    pos = $(this).data('pos');
    $(this).parent().find('img').animate({left: pos[0], top: pos[1] },500);
   }
  });
 });

 $("#droppable").droppable({
  drop : function(e,ui) {
   // append entire div wrapper (.dragme)
   ui.helper.parent().appendTo($(this));
  }
 });
});
fudgey
Here is an example of what I want to do:http://jsfiddle.net/wVref/2/ The puppy image is under the PNG with transparent parts. I want to put another layer on top of both images. This layer will be transparent and catch and transmit the drag events to the puppy so that it can be moved. How do you drag an image that is beneath a non-draggable image?
hekevintran
I've updated my answer. Like I mentioned above, there might be a better way, but this is what I came up with.
fudgey
I see. This is perfect except that it doesn't work in Safari where the overlay div doesn't exist. Any ideas?
hekevintran
I edited the HTML so that the overlay div is in the markup. Then it works fine. This is a little weird to me. http://jsfiddle.net/wVref/19/
hekevintran
What is wierd? I've updated the demo (http://jsfiddle.net/wVref/20/) to move it inside the drop box by setting the top and left position to zero. I also added a yellow border around the overlay div so you can see where it is at all times (for the demo)
fudgey
Yes the one you just linked to (http://jsfiddle.net/wVref/20/) works in Safari 5 but this one doesn't (http://jsfiddle.net/wVref/27/). The only difference between the two is that the second one creates the div in the JavaScript code and yours has the div in the HTML. They both work in Firefox and Chrome. Could this be a Safari bug?
hekevintran
The way I have it in the original demo was using jQuery 1.4 ability to create a div which caused me trouble in IE (I don't have Safari to test it) in another project... try making the div like this: `$('<div class="overlay" style="..."></div>');`
fudgey
Yes you are right: http://jsfiddle.net/wVref/28/
hekevintran