Skip to content

Instantly share code, notes, and snippets.

@valdeir2000
Last active February 10, 2018 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save valdeir2000/c6a322083fa2eb1ac096b008fe7836cc to your computer and use it in GitHub Desktop.
Save valdeir2000/c6a322083fa2eb1ac096b008fe7836cc to your computer and use it in GitHub Desktop.
StackOverflow - #275596
<!DOCTYPE hml>
<html>
<head>
<title>Title of the document</title>
<style>
* {margin:0;padding:0}
#img {margin:0 auto;height:auto;overflow:hidden;position:relative;width:350px;}
#img #main {left:0;position:relative;top:0;width:350px;}
#img #arrow {left:0;position:absolute;top:0;}
#area {background:red;height:50px;width:50px;left:0;position:relative;top:0;z-index:1}
a {cursor:default;-webkit-appearance: button;background-color: buttonface;color: buttontext;border-color: buttonface;font: 400 13.3333px Arial;-webkit-writing-mode: horizontal-tb;text-decoration:none;box-sizing: border-box;border-width: 2px;border-style: outset;border-color: buttonface;border-image: initial;}
</style>
</head>
<body>
<div id="img">
<img id="main" src="http://via.placeholder.com/350x350?text=Clique+para+carregar+uma+imagem" />
<img id="arrow" draggable="true" src="arrow.png" />
<button id="btnSendFile">Send File</button>
<a id="btnDownload">Download</a>
</div>
<script>
'use strict';
class DragAndDrop {
constructor(imgArea, imgMain, imgArrow, options) {
options = options || {};
if (
!(imgArea instanceof HTMLDivElement) ||
!(imgMain instanceof HTMLImageElement) ||
!(imgArrow instanceof HTMLImageElement) ||
!(options instanceof Object)
) {
throw Error("Arguments Invalid");
}
this.imgArea = imgArea;
this.imgArrow = imgArrow;
this.options = Object.assign({
arrowHeight: 100,
arrowWidth: 100,
btnDownload: null,
}, options);
this._setArrowSize();
this._setDragStart();
this._setDragDrop();
this._setDragOver();
this.imgArea.insertAdjacentHTML('beforeEnd', '<canvas id="psr_canvas" style="display:none"></canvas>');
this.canvas = document.querySelector("#psr_canvas");
this.options.btnDownload.addEventListener("mousedown", this._setConfigButtonDownload.bind(this));
}
_setDragStart() {
this.imgArrow.addEventListener("dragstart", (ev) => {
let left = ev.target.style.getPropertyValue("left") || 0;
let top = ev.target.style.getPropertyValue("top") || 0;
ev.dataTransfer.setData("left", parseInt(left) - ev.clientX);
ev.dataTransfer.setData("top", parseInt(top) - ev.clientY);
if ( (typeof this.options.dragStart) == "function" ) {
this.options.dragStart(ev);
}
});
}
_setDragDrop() {
this.imgArea.addEventListener("drop", (ev) => {
let left = ev.dataTransfer.getData("left") || 0;
let top = ev.dataTransfer.getData("top") || 0;
imgArrow.style.left = parseInt(left) + ev.clientX;
imgArrow.style.top = parseInt(top) + ev.clientY;
if ( (typeof this.options.dragDrop) == "function" ) {
this.options.dragDrop(ev);
}
});
}
_setDragOver() {
this.imgArea.addEventListener("dragover", (ev) => {
ev.preventDefault();
if ( (typeof this.options.dragOver) == "function" ) {
this.options.dragOver(ev);
}
return false;
});
}
_setArrowSize() {
this.imgArrow.style.setProperty("height", this.options.arrowHeight);
this.imgArrow.style.setProperty("width", this.options.arrowWidth);
}
_setConfigButtonDownload() {
this.buildCanvas();
this.canvas.toBlob( result => {
let reader = new FileReader();
reader.addEventListener("load", response => {
this.options.btnDownload.setAttribute("href", response.target.result);
this.options.btnDownload.setAttribute("download", "valdeir-psr.jpg");
});
reader.readAsDataURL(result);
}, "image/jpeg", 1);
}
buildCanvas() {
this.canvas.width = imgMain.width;
this.canvas.height = imgMain.height;
let ctx = this.canvas.getContext("2d");
ctx.clearRect(0, 0, imgMain.width, imgMain.height);
ctx.drawImage(imgMain, 0, 0, imgMain.width, imgMain.height)
ctx.drawImage(imgArrow, parseInt(imgArrow.style.left), parseInt(imgArrow.style.top), imgArrow.width, imgArrow.height);
return this.canvas;
}
}
const imgArea = document.querySelector("#img");
const imgMain = document.querySelector("#img #main");
const imgArrow = document.querySelector("#img #arrow");
const btnDownload = document.querySelector("#btnDownload");
const btnSendFile = document.querySelector("#btnSendFile");
let DnD = new DragAndDrop(imgArea, imgMain, imgArrow, {
arrowHeight: 100,
arrowWidth: 100,
btnDownload: btnDownload,
dragStart: () => {
console.log("Start");
},
dragOver: () => {
console.log("Over");
},
dragDrop: () => {
console.log("Drop")
}
});
imgMain.addEventListener("click", () => {
let element = '<form id="psr" style="display:none"><input type="file" /></form>';
document.body.insertAdjacentHTML('beforeEnd', element);
element = document.querySelector("#psr input");
element.addEventListener("change", function() {
let reader = new FileReader();
reader.addEventListener("load", result => {
imgMain.src = result.target.result;
});
reader.readAsDataURL(this.files[0]);
element.remove();
});
element.click();
});
btnSendFile.addEventListener("click", () => {
DnD.buildCanvas().toBlob(blob => {
let form = new FormData();
form.append("file", blob);
let xhr = new XMLHttpRequest();
xhr.onload = function(result) { alert( result.target.responseText ); }
xhr.open("POST", "upload.php", true);
xhr.send(form);
});
});
</script>
</body>
</html>
<?php
move_uploaded_file($_FILES['file']['tmp_name'], 'psr.jpg');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment