[英]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.offsetX和MouseEvent.offsetY 。 來自文檔:
MouseEvent接口的
offsetX
/offsetY
只讀屬性提供該事件與目標節點的填充邊緣之間的鼠標指針的X
/Y
坐標的偏移量。
所以,在dragstart
,你會做到:
x = e.offsetX;
y = e.offsetY;
然后,當你將圖像放入你的圖像時,讓我們稱它為畫布 (注意斜體,因為它不是<canvas>
元素,而是你用作放置區的任何其他元素,在這個特定的例子中是<div>
),你需要知道光標相對於那個畫布的位置,所以你可能會認為你可以再次使用offsetX
和offsetY
,而你的部分是正確的。 如果你將圖像放在畫布上本身就會給你預期的值,但是其中可能還有其他圖像,你可以將當前的圖像放在另一個圖像的頂部,相對於那個圖像得到offsetX
和offsetY
而不是。
你可以做的是使用MouseEvent.pageX
和MouseEvent.pageY
並從該值中減去該canvas元素的(左上角)的位置,你可以從HTMLElement.offsetLeft和HTMLElement.offsetTop中獲得它的位置:
e.pageX - imageCanvas.offsetLeft;
e.pageY - imageCanvas.offsetTop;
這樣,您將獲得光標相對於canvas元素的位置。
現在,你需要減去x
和y
你存儲在價值觀dragstart
,這會給你的left
和top
拖動圖像,相對於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.