JSFiddle - React, Tailwind, and code Playground
by Glenn Reed
HTML
<!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Drag and Drop Practice </title>
<meta name="description" content="A simple HTML5 Template for new projects.">
<meta name="author" content="KiwiHeretic">
<meta property="og:title" content="A Basic HTML5 Template">
<meta property="og:type" content="website">
<meta property="og:url" content="https://www.sitepoint.com/a-basic-html5-template/">
<meta property="og:description" content="A simple HTML5 Template for new projects.">
<meta property="og:image" content="image.png">
<link rel="icon" href="/favicon.ico">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="stylesheet" href="css/styles.css?v=1.0">
</head>
<body>
<!-- your content here... -->
<h1>Learning to do drag and drop in javascript</h1>
<div class="container">
<div class="left-region">
<div class="canvas">
<canvas id="universe">
</canvas>
</div>
<div id="object-block-2" class="objects">
<div class="box">
<span class="object" draggable="true">O</span>
<!--
<img src="asteroid.png" draggable="true" alt="asteroid">
-->
</div>
</div>
</div>
</div>
</div>
<script src="js/canvas-utils.js"></script>
<script>
document.onreadystatechange = function () {
if (document.readyState === "complete") {
var dragged;
var universe = new Universe(document.querySelector("canvas#universe"));
//var imgs = document.querySelectorAll("img[draggable='true']");
var imgs = document.querySelectorAll("div.box span.object");
imgs.forEach( function (elmt) {
var obj = new DraggableObject(elmt);
universe.add(obj);
});
}
}
...
CSS
h1 {
text-align: center;
}
canvas {
border: 1px solid grey;
width: 600px;
background-color: black;
}
div.container {
display: flex;
gap: 20px;
margin: 20px
}
div.objects {
margin: 10px 0;
}
div.objects div.box {
border:3px dashed grey;
width: 60px;
background-color: black;
}
div.box span.object {
color: white;
font-size: 32px;
}
div.objects div.box img {
width: 50px;
}
div#mouse-values {
margin: 20px;
}
div#mouse-values input {
width: 50px;
}
polygon.arrow {
fill:#0a0;
stroke:purple;
stroke-width:2;
}
polygon.arrow:hover {
fill: yellow;
}
JavaScript
class DraggableObject {
constructor(object) {
this.universe = null;
this.element = object;
this.element.addEventListener('dragstart', this.onDragStart.bind(this));
}
onDragStart(event) {
console.log("Drag start");
if (this.universe) {
this.universe.dragged = this;
console.log(this);
}
}
}
class Universe {
constructor(canvas) {
this.canvas = canvas;
this.dragged = null;
this.objects = [];
this.canvas.addEventListener( 'dragenter', elmt => { elmt.preventDefault(); console.log('drag enter'); } );
this.canvas.addEventListener( 'dragover', elmt => elmt.preventDefault() );
this.canvas.addEventListener( 'drop', function(evt) {
console.log(evt);
this.evt = evt;
this.objects.forEach( function(e) {
if (e == this.dragged ) {
console.log(e.element);
var ctx = this.canvas.getContext("2d");
ctx.strokeStyle = "#FFFFFF";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(this.evt.offsetX, this.evt.offsetY, 5, 0, 2 * Math.PI);
ctx.stroke();
}
}.bind(this));
}.bind(this) );
}
add(obj) {
this.objects.push(obj);
obj.universe = this;
}
}