Wednesday, May 3, 2017

How to tilt/rotate the item being dragged in javascript drag and drop?

Leave a Comment

I want to tilt an item being dragged to show distinction. I have basic drag and drop fiddle here https://jsfiddle.net/igaurav/bqprc9p8/3/

My javascript looks like:

"use strict";  var source = null;  function listItemDragStartHandler(event){     // What is true there for?     source = event.currentTarget;     event.dataTransfer.setData("text/plain", event.currentTarget.innerHTML);     event.currentTarget.style.transform = 'rotate(15deg)';     event.dataTransfer.effectAllowed = "move"; }  function dragoverHandler(event) {     event.preventDefault();     event.dataTransfer.dropEffect = "move"; }  function dropHandler(event) {     event.preventDefault();     event.stopPropagation();     var currentElement = event.currentTarget;     var listContainer = currentElement.parentNode;     listContainer.insertBefore(source, currentElement);     source.style.transform = 'rotate(0deg)'; }  function delete_item(event) {     var currentTarget = event.currentTarget;     var grandParentOfDelete = currentTarget.parentNode.parentNode;     grandParentOfDelete.remove(); }  function add_item() {     var item_text_node = document.getElementsByName("add-item-text")[0]     var item_text = item_text_node.value;     if (item_text.length > 0) {         var item_template = document.getElementById("item-template");         var item_clone = item_template.cloneNode(true);         item_clone.removeAttribute("id");         var clone_text = item_clone.getElementsByClassName("item-text")[0];         clone_text.textContent = item_text;         // reset the value         item_text_node.value = "";         var item_list = document.getElementById("item-list");         item_list.appendChild(item_clone);     } else {         alert("No text?? Add some text!");     } }  function add_item_listener() {     var add_item_button = document.getElementById("add-item");     add_item_button.addEventListener("click", add_item); }  function sample_data() {     for(var i=0;i<10;i++){         var item_text_node = document.getElementsByName('add-item-text')[0]         item_text_node.value = i;         add_item();     } }  function init_app() {     add_item_listener();     sample_data(); }  window.onload = function () {     init_app() } 

Relevant HTML is:

<body>     <div id="container">         <div id="add-item-div">             <input type="text" name="add-item-text">             <button id="add-item">Add Item</button>         </div>         <div id="item-list">         </div>         <div id="item-template" class="item-list-element" draggable="true" ondragstart="listItemDragStartHandler(event);" ondrop="dropHandler(event);" ondragover="dragoverHandler(event);">             <div class="item-text"></div>             <div class="delete-item-div">                 <button class="delete-item" onclick="delete_item(event);">Delete Item</button>             </div>         </div>     </div> </body> 

I am applying the transform on line 9 but the drag operation stops and drag doesn't start.

What am I doing wrong?

P.S: I don't want to use libraries.

Thanks

2 Answers

Answers 1

Basically, we can use setDragImage for replacing the browser implementation of the ghost image it is rendering for the dragging operation, with one of our own.

We use a cloned node as you do in the fiddle, and we add it to the dom.

Then, you can do the transformation on an inner container in the cloned element.

document.getElementById("drag-with-create-add").addEventListener("dragstart", function(e) {      var crt = this.cloneNode(true);        crt.style.position = "absolute";       crt.style.top = "0px";       crt.style.left = "-100px";            var inner = crt.getElementsByClassName("inner")[0];      inner.style.backgroundColor = "orange";      inner.style.transform = "rotate(20deg)";            document.body.appendChild(crt);      e.dataTransfer.setDragImage(crt, 20, 20);  }, false);
<div id="drag-with-create-add" class="dragdemo" draggable="true">    <div class="inner">      drag me    </div>  </div>

This is partly based on an helpfull article by Stuart Langridge.

Note: Trick here is to apply transformation on inner element and not on the one which has drag events. Transformation would appear only if applied to inner elements.

Answers 2

I just created a sample fiddle. Which uses the setDragImage method, Please have a look and comment your needs so that we can upate the answer.

I have added a ghost image and added 'shake' feel while drag start. You can similarly rotate the dragging ghost image via css.

Also note, we are cloning the image while dragging to show ghost image. So we need to manually remove that from dom.

document.addEventListener("dragstart", function(e) {    var img = document.createElement("img");    img.src = "http://i.imgur.com/BDcvqmf.jpg";    e.dataTransfer.setDragImage(img, 5000, 5000); //5000 will be out of the window    drag(e)  }, false);    var crt, dragX, dragY;  //document.addEventListener('drag',drag)  function drag(ev) {    crt = ev.target.cloneNode(true);    crt.className = "face";    crt.style.position = "absolute";    crt.style.opacity = "0.9";    document.body.appendChild(crt);    ev.dataTransfer.setData("text", ev.target.id);  }    document.addEventListener("dragover", function(ev) {    ev = ev || window.event;    dragX = ev.pageX;    dragY = ev.pageY;    crt.style.left = dragX + "px";    crt.style.top = dragY + "px";  }, false);    document.addEventListener("dragend", function(event) {    crt.style.display = 'none';    crt.remove()  });
body {    padding: 10px  }    #draggable-element {    width: 100px;    height: 100px;    background-color: #666;    color: white;    padding: 10px 12px;    cursor: move;    position: relative;    /* important (all position that's not `static`) */  }    .face {    animation: shake 1s cubic-bezier(.36, .07, .19, .97) both;    transform: translate3d(0, 0, 0);    backface-visibility: hidden;    perspective: 1000px;  }    @keyframes shake {    10%,    90% {      transform: translate3d(-1px, 0, 0);    }    20%,    80% {      transform: translate3d(4px, 0, 0);    }    30%,    50%,    70% {      transform: translate3d(-5px, 0, 0);    }    40%,    60% {      transform: translate3d(5px, 0, 0);    }  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>    See the tilt in action on drag start. <br>    <img draggable id="draggable-element" src="http://i.imgur.com/BDcvqmf.jpg">

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment