我正在使用interact.js库进行拖放功能。我使用原始图像而不是div作为我的可拖动对象,这似乎工作正常:
<img id="drag4" src="images/SVG/ksTire.svg" class="draggable js-drag" style="width:85px">
我无法弄清楚如何在拖动开始之前将图像返回到其原始起点。我需要将原始坐标存储在js变量中,并根据某些事件将图像返回到其确切的原始起始位置。我在事件上尝试了各种x / y坐标,并尝试了getElementById,没有运气。每当我尝试将图像返回到原始位置时,有些方法会在第一次将其恢复原状,但是当我再次开始拖动它时,它会在一个陌生的地方离开,而不是在鼠标指针下面。
有人可以提供一些示例代码,说明如何不断将可拖动对象捕捉回其初始位置吗?我已经在代码中找到了调用它的位置,我需要的是如何将图像恢复到正确的位置,然后在发生后继续正常运行。
注意:interact.js不是基于jquery构建的,所以在这种特殊情况下我更喜欢非jquery解决方案。
以下是我的dropzone.js的全部内容,大多数相关内容都与此问题相关:
(function(interact) {
'use strict';
var transformProp;
var startPos = null;
var startX = 0;
var startY = 0;
var validDrop = false;
interact.maxInteractions(Infinity);
// setup draggable elements.
/* block below was copied from https://github.com/taye/interact.js/issues/79 -- try to get this working */
// setup drop areas.
setupDropzone('#drop1', '#drag1, #drag2, #drag4');
setupDropzone('#drop2', '#drag4');
setupDropzone('#drop4', '#drag4');
setupDropzone('#drop5', '#drag1, #drag2, #drag4');
setupDropzone('#drop6', '#drag3');
setupDropzone('#drop7', '#drag1');
/* SNAP code was copied from http://kundprojekt.soonce.com/lintex/zonbuilder/ and https://github.com/taye/interact.js/issues/79 -- try to get this working */
// dropzone #1 accepts draggable #1
//setupDropzone('#drop1', '#drag1');
// dropzone #2 accepts draggable #1 and #2
//setupDropzone('#drop2', '#drag1, #drag2');
// every dropzone accepts draggable #3
//setupDropzone('.js-drop', '#drag3');
/**
* Setup a given element as a dropzone.
*
* @param {HTMLElement|String} el
* @param {String} accept
*/
function setupDropzone(el, accept) {
interact(el)
.dropzone({
accept: accept,
ondropactivate: function(event) {
addClass(event.relatedTarget, '-drop-possible');
},
ondropdeactivate: function(event) {
removeClass(event.relatedTarget, '-drop-possible');
}
})
.snap({
mode: 'anchor',
anchors: [],
range: Infinity,
elementOrigin: {
x: 0.5,
y: 0.5
},
endOnly: true
})
.on('dropactivate', function(event) {
var active = event.target.getAttribute('active') | 0;
// change style if it was previously not active
if (active === 0) {
addClass(event.target, '-drop-possible');
//event.target.textContent = 'Drop me here!';
}
event.target.setAttribute('active', active + 1);
})
.on('dropdeactivate', function(event) { // this fires after each drop, whether a drop into a valid drop zone occurs or not
var active = event.target.getAttribute('active') | 0;
// change style if it was previously active
// but will no longer be active
if (active === 1) {
removeClass(event.target, '-drop-possible');
//event.target.textContent = 'Dropzone';
}
event.target.setAttribute('active', active - 1);
if (!validDrop) {
//document.getElementById("drag4").style.position = 'absolute';
//document.getElementById("drag4").style.left = startX + "px";
//document.getElementById("drag4").style.top = startY + "px";
}
})
.on('dragstart', function(event) {
// snap to the start position
if (!startPos) {
var rect = interact.getElementRect(event.target);
// record center point when starting the very first a drag
startPos = {
x: rect.left + rect.width / 2,
y: rect.top + rect.height / 2
}
}
event.interactable.snap({
anchors: [startPos]
});
})
.on('dragenter', function(event) {
addClass(event.target, '-drop-over');
var dropRect = interact.getElementRect(event.target),
dropCenter = {
x: dropRect.left + dropRect.width / 2,
y: dropRect.top + dropRect.height / 2
};
event.draggable.snap({
anchors: [dropCenter]
});
//event.relatedTarget.textContent = 'I\'m in';
})
.on('dragleave', function(event) {
removeClass(event.target, '-drop-over');
event.draggable.snap(false);
// when leaving a dropzone, snap to the start position
event.draggable.snap({
anchors: [startPos]
});
var svgFilename = getSVGFilename(event.relatedTarget.src);
if (document.getElementById("message").innerHTML) {
document.getElementById("message").innerHTML = document.getElementById("message").innerHTML.replace(svgFilename + "<br>", "");
}
//event.relatedTarget.textContent = 'Drag me…';
})
.on('drop', function(event) { // this only fires when an object is dropped into a valid drop zone for that object
validDrop = true;
removeClass(event.target, '-drop-over');
var svgFilename = getSVGFilename(event.relatedTarget.src);
document.getElementById("message").innerHTML += svgFilename + "<br>";
//event.relatedTarget.textContent = 'Dropped';
});
}
function getAbsolutePosition(el) {
var el2 = el;
var curtop = 0;
var curleft = 0;
if (document.getElementById || document.all) {
do {
curleft += el.offsetLeft - el.scrollLeft;
curtop += el.offsetTop - el.scrollTop;
el = el.offsetParent;
el2 = el2.parentNode;
while (el2 != el) {
curleft -= el2.scrollLeft;
curtop -= el2.scrollTop;
el2 = el2.parentNode;
}
} while (el.offsetParent);
} else if (document.layers) {
curtop += el.y;
curleft += el.x;
}
return [curleft, curtop];
};
function getSVGFilename(url) {
if (url.indexOf("/") > -1)
return url.substr(url.lastIndexOf('/') + 1);
else
return "";
}
function addClass(element, className) {
if (element.classList) {
return element.classList.add(className);
} else {
element.className += ' ' + className;
}
}
function removeClass(element, className) {
if (element.classList) {
return element.classList.remove(className);
} else {
element.className = element.className.replace(new RegExp(className + ' *', 'g'), '');
}
}
interact('.js-drag')
.draggable({
max: Infinity
})
.on('dragstart', function(event) {
validDrop = false;
event.interaction.x = parseInt(event.target.getAttribute('data-x'), 10) || 0;
event.interaction.y = parseInt(event.target.getAttribute('data-y'), 10) || 0;
var absolutePosition = getAbsolutePosition(event.target);
startX = absolutePosition[0];
startY = absolutePosition[1];
})
.on('dragmove', function(event) {
event.interaction.x += event.dx;
event.interaction.y += event.dy;
if (transformProp) {
event.target.style[transformProp] =
'translate(' + event.interaction.x + 'px, ' + event.interaction.y + 'px)';
} else {
event.target.style.left = event.interaction.x + 'px';
event.target.style.top = event.interaction.y + 'px';
}
})
.on('dragend', function(event) {
event.target.setAttribute('data-x', event.interaction.x);
event.target.setAttribute('data-y', event.interaction.y);
});
interact(document).on('ready', function() {
transformProp = 'transform' in document.body.style ? 'transform' : 'webkitTransform' in document.body.style ? 'webkitTransform' : 'mozTransform' in document.body.style ? 'mozTransform' : 'oTransform' in document.body.style ? 'oTransform' : 'msTransform' in document.body.style ? 'msTransform' : null;
});
}(window.interact));
这是我的基本html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>WorkScreen Prototype #1</title>
<script src="js/interact.js"></script>
<script src="js/dropzones.js"></script>
<link rel="stylesheet" href="css/dropzones.css">
</head>
<body style="background-color: #CCC; height: 852px">
<a href="ShowSVGs.aspx" target="_blank">View All SVGs</a>
<div style="margin-top:55px">
<div style="float: left; vertical-align: top">
<img id="drag1" src="images/SVG/ksBatteryBox.svg" class="draggable js-drag" style="width:80px"><br />
<img id="drag2" src="images/SVG/ksBumper6308700.svg" class="draggable js-drag" style="width:85px"><br />
<img id="drag3" src="images/SVG/ksHood8090130.svg" class="draggable js-drag" style="width:165px"><br />
<img id="drag4" src="images/SVG/ksTire.svg" class="draggable js-drag" style="width:85px"><br />
</div>
<div style="float: left;vertical-align:top;margin-left:-72px">
<div style ="margin-left:100px;">
<div id="drop1" class="dropzone js-drop" style="margin-left:186px;"></div>
<div id="drop2" class="dropzone js-drop" style="margin-left:90px"></div>
<div style="">
<div id="drop6" class="dropzone js-drop" style="clear: both; margin-left: 0px; margin-top: 37px"></div>
<div style="float:left"><img src="images/BaseTruck.png" /></div>
<div id="drop7" class="dropzone js-drop" style="float: left; margin-left: 251px; margin-top: 153px; position: absolute;"></div>
<div id="drop3" class="dropzone js-drop" style="float:left; margin-left:10px;margin-top:37px"></div>
</div>
<div id="drop5" class="dropzone js-drop" style="clear: both; margin-left: 186px;"></div>
<div id="drop4" class="dropzone js-drop" style="margin-left: 90px;"></div>
<br /><br />
<div id="message" style="clear: both; margin-left: 0px; margin-top: 44px; width: 245px; display: inherit; border: 2px solid gray; padding: 7px;"></div>
</div>
</div>
</div>
</body>
</html>
答案 0 :(得分:0)
这是解决方案以防万一。无需确定相对于窗口的确切位置,以便将元素返回到其加载时间位置。就这样做:
function resetCoords(evt) {
evt.relatedTarget.style.left = "0px";
evt.relatedTarget.style.top = "0px";
evt.interaction.x = 0;
evt.interaction.y = 0;
}
然后像这样调用resetCoords:
.on('dropdeactivate', function(event) { // this fires after each drop, whether a drop into a valid drop zone occurs or not
var active = event.target.getAttribute('active') | 0;
// change style if it was previously active
// but will no longer be active
if (active === 1) {
removeClass(event.target, '-drop-possible');
//event.target.textContent = 'Dropzone';
}
event.target.setAttribute('active', active - 1);
if (!validDrop) {
resetCoords(event);
}
})
在.on('drop...)
事件中,您将validDrop设置为true,否则它将为false。