Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    0
    Thanked 1 Time in 1 Post

    Draggable clone of image, jQuery

    I am trying to do some draggable coding with jQuery. What I want to do is this. I have an image, I want the user to be able to drag the image, but I also want the original image to stay in place. So there would now be 2 images, the original (static) and the draggable clone.

    I have tried using the clone method (fired on mouseover, which seems wrong on hacky) to clone the image and then append the clone using css, the problem is that the appended clone is being flowed into the div every time (thus creating many copies, for subsequent mouseovers), I have tried using absolute positioning and z-index, but it's not working.

    Hope this makes sense, any thoughts appreciated.

  • #2
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    mouseover is not a good choice because, as you have discovered, you can end up with lots of clones. mousedown is probably more sensible, but you need to check that you only have one clone at any time:

    Code:
    var theImage = document.getElementById("imageID"); // jQuery: $('#imageID')
    var theClone = theClone || theImage.cloneNode(true); // jQuery: theImage.clone()
    Then use mouseup to either insert the clone (or not) and set theClone = null (jQuery: .remove() ..? if you must . No, I think this removes an existing element from the DOM: just set it to null.)

    BTW
    Code:
    var theClone = theClone || theImage.cloneNode(true);
    is my favourite JS statement; we cannot do this in most any other language - or, at least, not as simply as this.
    Last edited by AndrewGSW; 12-15-2012 at 05:33 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #3
    New to the CF scene
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    0
    Thanked 1 Time in 1 Post
    If I create the clone on mousedown, append it to the dom on mouseup, the user is going to need to click again to drag it. And I'm still not sure how to place the clone directly on top of the static image, z-index isn't doing to the trick. the clone(s) is always placed next to the static original. Thanks.

  • #4
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Quote Originally Posted by javageek View Post
    If I create the clone on mousedown, append it to the dom on mouseup, the user is going to need to click again to drag it. And I'm still not sure how to place the clone directly on top of the static image, z-index isn't doing to the trick. the clone(s) is always placed next to the static original. Thanks.
    In general terms.. mousedown can be used to initiate the clone, mousemove to make it visible and move it, then mouseup to append it permanently.

    z-index on its own won't help. You should use a container element (maybe a DIV) with position:relative, and make the clone position: absolute (within this DIV or other container) so that it can be moved at the same time as the mouse.

    But (I keep forgetting) you are using jQuery, so why don't you investigate the jQuery draggable UI?

    The following code is vanilla JS but it indicates the principles involved in dragging elements:
    Code:
    	function Draggable() { 				// Class : allow draggable elements
            if (!(this instanceof Draggable)) return new Draggable();  // did they use "new"?
            var _startX, _startY, _offsetX, _offsetY,
                _dragElement,		// needs to be passed from OnMouseDown to OnMouseMove 
                _oldZIndex;		// we temporarily increase the z-index during drag 
            
            var InitDragDrop = function () {
                _startX = _startY = _offsetX = _offsetY = 0;
    			document.onmousedown = OnMouseDown; 
    			document.onmouseup = OnMouseUp; 
    		};
            var OnMouseDown = function (e) { 
                if (e == null) e = window.event;    // IE doesn't pass the event object 
                var target = e.target != null ? e.target : e.srcElement;
                // ..IE uses srcElement, others use target
                // for IE, left click == 1; for Firefox, left click == 0 
                if ((e.button == 1 && window.event != null || e.button == 0) && 
                        target.className == 'dragIt') {   // grab the mouse position
                    // grab the clicked element's position 
                    _startX = e.clientX; _startY = e.clientY;       
                    _offsetX = ExtractNumber(target.style.left); 
                    _offsetY = ExtractNumber(target.style.top);
                    // bring the clicked element to the front while it is being dragged 
                    _oldZIndex = target.style.zIndex;
                    target.style.zIndex = 100;
                    // we need to access the element in OnMouseMove 
                    _dragElement = target;
                    // tell our code to start moving the element with the mouse 
                    document.onmousemove = OnMouseMove;
                    // cancel out any text selections 
                    document.body.focus();
                    // prevent text selection in IE 
                    document.onselectstart = function () { return false; }; 
                    // prevent IE from trying to drag an image 
                    target.ondragstart = function() { return false; };
                    // prevent text selection (except IE) 
                    return false; 
                }
                return true;    // not used
            };
            var OnMouseMove = function (e) { 
                if (e == null) e = window.event;
                // this is the actual "drag code" 
                _dragElement.style.left = (_offsetX + e.clientX - _startX) + 'px'; 
                _dragElement.style.top = (_offsetY + e.clientY - _startY) + 'px'; 
            };
            var OnMouseUp = function (e) {
                // When the mouse is released, we remove the event handlers 
                // and reset dragElement:
                if (_dragElement != null) { 
                    _dragElement.style.zIndex = _oldZIndex;
                    // we're done with these events until the next OnMouseDown 
                    document.onmousemove = null; 
                    document.onselectstart = null; 
                    _dragElement.ondragstart = null;
                    // this is how we know we're not dragging 
                    _dragElement = null; 
                } 
            };
            var ExtractNumber = function (value) { 
                var n = parseInt(value,10); 
                return n == null || isNaN(n) ? 0 : n; 
            };
    		this.InitDragDrop = InitDragDrop;	// only need to expose this method
            return this;
    	}
    Last edited by AndrewGSW; 12-15-2012 at 06:29 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #5
    New to the CF scene
    Join Date
    Dec 2012
    Posts
    7
    Thanks
    0
    Thanked 1 Time in 1 Post
    Hmmm, I'm going to look further at the regular js code you posted, and I am using jQuery's ui draggable.

    Let me hack on it some, and I'll come back with more questions. Thanks.

    Update: Got it working (mostly) I wound up needing to position the class absolutely, where as before it was just flowing in it's container. Now I have a new problem which is how to do it with n images, without creating separate css entries for each one.
    Last edited by javageek; 12-15-2012 at 07:02 PM. Reason: appending

  • #6
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Quote Originally Posted by javageek View Post
    Hmmm, I'm going to look further at the regular js code you posted, and I am using jQuery's ui draggable.

    Let me hack on it some, and I'll come back with more questions. Thanks.
    Here's a complete page if it helps. It is not mine - believe it's Vic's work
    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title>Some Title</title>
    
    <style type="text/css">
    /* */
    </style>
    
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
    </script>
    <script type="text/javascript">
    
    $(document).ready(function() {
    
    });
    
    var dragobjekt = null;
    
    var dragx = 0;
    var dragy = 0;
    
    var posx = 0;
    var posy = 0;
    
    function draginit() {
        document.onmousemove = drag;
        document.onmouseup = dragstop;
    }
    
    function dragstart(element,coords) {
        dragstart.coords=coords;
        dragobjekt = element;
        dragx = posx - dragobjekt.offsetLeft;
        dragy = posy - dragobjekt.offsetTop;
    }
    
    function dragstop() {
        var lft=dragobjekt.offsetLeft,top=dragobjekt.offsetTop,c=dragstart.coords;
        if (c&&lft>c[0]&&lft+dragobjekt.offsetWidth<c[1]&&top>c[2]&&top+dragobjekt.offsetHeight<c[3]){
            alert(c)
        }
        dragobjekt=null;
    }
    
    function drag(ereignis) {
        posx = document.all ? window.event.clientX : ereignis.pageX;
        posy = document.all ? window.event.clientY : ereignis.pageY;
        if(dragobjekt != null) {
            dragobjekt.style.left = (posx - dragx) + "px";
            dragobjekt.style.top = (posy - dragy) + "px";
        }
    }
    </script>
    
    </head>
    
    <body onload="draginit()">
    <div  style="position:absolute;top:200px;left:500px;height:120px;width:120px;border:solid red 1px;"> </div>
    <div onmousedown="dragstart(this,[500,620,200,320])"
         style="position:absolute;top:0px;left:0px;height:100px;width:100px;background:#ff0000"> </div>
    <div onmousedown="dragstart(this,[500,620,200,320])"
         style="position:absolute;top:200px;left:0px;height:100px;width:100px;background:#00ff00"> </div>
    </body>
    </html>
    Vic

    God Loves You and will never love you less.

    http://www.vicsjavascripts.org.uk/

    If my post has been useful please donate to http://www.operationsmile.org.uk/
    Last edited by AndrewGSW; 12-15-2012 at 07:07 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •