JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
<script src="http://rawgithub.com/kangax/fabric.js/master/dist/all.js"></script>
<!-- Based on the tutorial at http://www.html5rocks.com/en/tutorials/dnd/basics/ -->
<div id="images">
<img draggable="true" src="http://i.imgur.com/8rmMZI3.jpg" width="250" height="250"></img>
<img draggable="true" src="http://i.imgur.com/q9aLMza.png" width="252" height="295"></img>
<img draggable="true" src="http://i.imgur.com/wMU4SFn.jpg" width="238" height="319"></img>
</div>
<!-- NOTE: Fabric.js sets both the <canvas> element and the wrapper element which it
creates to be user-unselectable using CSS properties (e.g. for Webkit, this is
-webkit-user-select: none;). We could remove that property during the dragging, but
I'm just going to wrap the canvas in a container and bind events to that, which is
less intrusive.
-->
<div id="canvas-container">
<canvas id="canvas" width="800" height="600"></canvas>
</div>
CSS
#canvas-container {
position: relative;
width: 800px;
height: 600px;
box-shadow: 0 0 5px 1px black;
margin: 10px auto;
border: 5px solid transparent;
}
#canvas-container.over {
border: 5px dashed cyan;
}
#images img.img_dragging {
opacity: 0.4;
}
/*
Styles below based on http://www.html5rocks.com/en/tutorials/dnd/basics/
*/
/* Prevent the text contents of draggable elements from being selectable. */
[draggable] {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
/* Required to make elements draggable in old WebKit */
-khtml-user-drag: element;
-webkit-user-drag: element;
cursor: move;
}
JavaScript
/* Drag and Drop code adapted from http://www.html5rocks.com/en/tutorials/dnd/basics/ */
var canvas = new fabric.Canvas('canvas');
/*
NOTE: the start and end handlers are events for the <img> elements; the rest are bound to the canvas container.
*/
function handleDragStart(e) {
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
this.classList.add('img_dragging');
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}
e.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object.
// NOTE: comment above refers to the article (see top) -natchiketa
return false;
}
function handleDragEnter(e) {
// this / e.target is the current hover target.
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over'); // this / e.target is previous target element.
}
function handleDrop(e) {
// this / e.target is current target element.
/*
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
*/
e.stopPropagation(); // Stops some browsers from redirecting.
e.preventDefault(); // Stops some browsers from redirecting.
// handle desktop images
if(e.dataTransfer.files.length > 0){
var files = e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (f.type.match('image.*')) {
// Read the File objects in this FileList.
var reader = new FileReader();
// listener for the onload event
reader.onload = function(evt) {
// create img element
var img = document.createElement('img');
img.src= evt.target.result;
...