繁体   English   中英

在JavaScript中捕捉拖放项目

[英]Snapping Drag and Drop Items in JavaScript

我试图使用拖放将图片从一个<div>移动到另一个。

目前,我可以将图片移动到目的地<div>中的任何位置,但我真正想要的是图片在放下时会卡在一起。 理想情况下,它们可以在任何一侧(不仅仅是在底部或右侧)拼接在一起。

我尝试了一些不同的东西(包括使用<canvas> )但它没有用。

这是我到目前为止:

 var clone; var offsetx = null; var offsety = null; var isClone = false; function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { offsetx = ev.target.offsetLeft - event.clientX; offsety = ev.target.offsetTop - event.clientY; ev.dataTransfer.setData("text", ev.target.id); } function dropTrash(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); var remove = document.getElementById(data); remove.parentNode.removeChild(remove); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); } function dropClone(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); var num = Math.random() * (1000 - 1) + 1; isClone = true; clone = document.getElementById(data).cloneNode(true); clone.id = "newId" + num.toString(); clone.style.position = "absolute"; clone.style.left = (event.clientX+offsetx)+"px"; clone.style.top = (event.clientY+offsety)+"px"; ev.target.appendChild(clone); } 
 html, body { height: 100%; padding: 0; margin: 0; } div { width: 50%; height: 50%; float: left; } #div1 { background: #DDD; } #div2 { background: #AAA; } #div3 { background: #777; } #div4 { background: #444; } #imgDiv { width: 611px; height: 324px; border: 5px solid #DDD; } 
 <div id="div1"> </div> <div id="div2"> </div> <div id="div3" ondrop="dropTrash(event)" ondragover="allowDrop(event)"> <img id="drag1" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Bartagame_fcm.jpg/1200px-Bartagame_fcm.jpg" draggable="true" ondragstart="drag(event)" width="105" height="105"> <img id="drag2" src="http://www.earthtimes.org/newsimage/lizard_Ngo_Van_Tri_big_281.jpg" draggable="true" ondragstart="drag(event)" width="105" height="105"> </div> <div id="div4"> <div align="center" id="imgDiv" ondrop="dropClone(event)" ondragover="allowDrop(event)"></div> </div> 

当您开始拖动图像时,您需要存储光标相对于该特定图像的位置。

MouseEvent中有多个位置属性可以帮助您计算,但如果浏览器支持不是问题,我会选择MouseEvent.offsetXMouseEvent.offsetY 来自文档:

MouseEvent接口的offsetX / offsetY只读属性提供该事件与目标节点的填充边缘之间的鼠标指针的X / Y坐标的偏移量。

所以,在dragstart ,你会做到:

x = e.offsetX;
y = e.offsetY;

然后,当你将图像放入你的图像时,让我们称它为画布 (注意斜体,因为它不是<canvas>元素,而是你用作放置区的任何其他元素,在这个特定的例子中是<div> ),你需要知道光标相对于那个画布的位置,所以你可能会认为你可以再次使用offsetXoffsetY ,而你的部分是正确的。 如果你将图像放在画布上本身就会给你预期的值,但是其中可能还有其他图像,你可以将当前的图像放在另一个图像的顶部,相对于那个图像得到offsetXoffsetY而不是。

你可以做的是使用MouseEvent.pageXMouseEvent.pageY并从该值中减去该canvas元素的(左上角)的位置,你可以从HTMLElement.offsetLeftHTMLElement.offsetTop中获得它的位置:

e.pageX - imageCanvas.offsetLeft;
e.pageY - imageCanvas.offsetTop;

这样,您将获得光标相对于canvas元素的位置。

现在,你需要减去xy你存储在价值观dragstart ,这会给你的lefttop拖动图像,相对于canvas元素的左上角的值:

image.style.left = (e.pageX - imagesCanvas.offsetLeft - x) + 'px';
image.style.top = (e.pageY - imagesCanvas.offsetTop - y) + 'px';

它们一起看起来像这样:

 let x; let y; let currentTarget = null; let cloneElement = false; function startDrag(e, clone) { const target = e.target; if (target.tagName === 'IMG') { x = e.offsetX; y = e.offsetY; currentTarget = target; cloneElement = clone; } } function cloneImage(e) { startDrag(e, true); } function moveImage(e) { startDrag(e, false); } function removeImage(e) { if (!cloneElement) { currentTarget.remove(); } } function stickImage(e) { const image = cloneElement ? currentTarget.cloneNode(true) : currentTarget; imagesCanvas.appendChild(image); // + 1 for the border image.style.left = (e.pageX - imagesCanvas.offsetLeft - x + 1) + 'px'; image.style.top = (e.pageY - imagesCanvas.offsetTop - y + 1) + 'px'; currentTarget = null; } function allowDrag(e) { e.preventDefault(); } // Bind event listeners: const imagesBarElement = document.getElementById('imagesBar'); const imagesCanvasElement = document.getElementById('imagesCanvas'); document.addEventListener('dragenter', allowDrag); document.addEventListener('dragover', allowDrag); imagesBarElement.addEventListener('dragstart', cloneImage); imagesBarElement.addEventListener('drop', removeImage); imagesCanvasElement.addEventListener('dragstart', moveImage); imagesCanvasElement.addEventListener('drop', stickImage); 
 body { margin: 0; font-size: 0; display: flex; flex-direction: column; height: 100vh; user-select: none; } img { width: 100px; height: 100px; } #imagesBar { height: 100px; border-bottom: 1px solid #CCC; padding: 10px 0; } #imagesBar > img { margin: 0 0 0 10px; } #imagesCanvas { position: relative; background: #EEE; flex-grow: 1; overflow: hidden; } #imagesCanvas > img { position: absolute; } 
 <div id="imagesBar"> <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Bartagame_fcm.jpg/1200px-Bartagame_fcm.jpg" draggable="true"> <img src="http://www.earthtimes.org/newsimage/lizard_Ngo_Van_Tri_big_281.jpg" draggable="true"> </div> <div id="imagesCanvas"></div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM