Interact.js 设置拖到 td 的中心
Interact.js Setting dragged on center of td
我正在努力创建某种调度程序,我正在使用 interact.js 来处理元素的所有拖动&drop/snapping,但我很难居中和制作捕捉到 TD
的元素
您可以检查this fiddle to see what I got,如果您将可拖动对象拖动到任何单元格的左上角,您会看到捕捉有点起作用,但它不会使元素居中,也不会总是发生,它必须在一个特定的位置才能使捕捉工作,而不是总是将它捕捉到单元格的内部,有时,拖动元素会将它的一部分从单元格中移出。
我已经查看了插件 github 上的 Snap 示例,它让我了解了如何实现我正在寻找的东西。网格系统对我不起作用,因为该项目需要一个空列作为某种空白。
任何帮助将不胜感激。
单元格上方的十字是捕捉的位置,我的意思是,这是锚点的位置,并不完美,我仍在努力使它们居中
这是代码
var element = document.getElementById("schedule");
var anchors = [];
document.querySelectorAll(".dropzone").forEach(function (td, i) {
var boundRect = td.getBoundingClientRect();
var anchor = {
x: boundRect.left + 30,
y: boundRect.top + 15,
range: 20
}
anchors.push(anchor);
});
anchors.forEach(function(anchor, i){
var textNode = document.createElement("div");
textNode.appendChild(document.createTextNode("+"));
textNode.style.position = "absolute";
textNode.style.top = anchor.y + "px";
textNode.style.left = anchor.x + "px";
textNode.style.zIndex = 100;
textNode.style.fontWeight = "bolder";
document.querySelector("#wrapper").appendChild(textNode);
});
// target elements with the "draggable" class
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// snapping to grid
snap: {
targets: anchors,
enabled: true,
endOnly: true,
//offset: 'startCoords'
},
// keep the element within the area of it's parent
restrict: {
drag: element,
endOnly: false,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
// enable autoScroll
autoScroll: true,
// call this function on every dragmove event
onmove: dragMoveListener,
// call this function on every dragend event
onend: function (event) {
}
});
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '#dragabble',
// Require a 75% element overlap for a drop to be possible
overlap: 0.6,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
draggableElement.textContent = 'Dragged in';
var dropRect = interact.getElementRect(event.target),
dropCenter = {
x: dropRect.left + 30,
y: dropRect.top + 15
};
event.draggable.snap({
anchors: dropCenter
});
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
event.relatedTarget.textContent = 'Dragged out';
event.draggable.snap(false);
},
ondrop: function (event) {
event.relatedTarget.textContent = 'Dropped';
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
function dragMoveListener(event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
// this is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener;
好吧,没关系,我决定按照我想要的方式实现自己的捕捉it/need。
我刚刚在 ondrop
事件中添加了一些代码,以将 dragabble
设置到它着陆的 td 中心,并制作了我需要的快照
var element = document.getElementById("schedule");
// target elements with the "draggable" class
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// keep the element within the area of it's parent
restrict: {
drag: element,
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
// enable autoScroll
autoScroll: true,
// call this function on every dragmove event
onmove: dragMoveListener,
// call this function on every dragend event
onend: function (event) {
}
});
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '#dragabble',
// Require a 75% element overlap for a drop to be possible
overlap: 0.6,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
draggableElement.textContent = 'Dragged in';
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
event.relatedTarget.textContent = 'Dragged out';
},
ondrop: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target,
dropRect = getOffset(dropzoneElement),
x = dropRect.left,
y = dropRect.top;
draggableElement.textContent = 'Dropped';
// translate the element
draggableElement.style.webkitTransform =
draggableElement.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
draggableElement.setAttribute('data-x', x);
draggableElement.setAttribute('data-y', y);
event.relatedTarget.textContent = 'Dropped';
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
function dragMoveListener(event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
function getOffset(el) {
el = el.getBoundingClientRect();
return {
left: el.left + window.scrollX,
top: el.top + window.scrollY
}
}
// this is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener;
td
{
width: 68px;
height: 32px;
}
#wrapper
{
width: 100%;
height: 100%;
}
#dropZone {
height: 140px;
background-color: Gray;
}
.dropzone {
background-color: #ccc;
border: dashed 4px transparent;
border-radius: 4px;
/*margin: 10px auto 30px;*/
padding: 6px;
/*width: 80%;*/
transition: background-color 0.3s;
}
.drop-active {
border-color: #aaa;
}
.drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
}
.drag-drop {
display: inline-block;
width: 60px;
height: 30px;
/*padding: 2em 0.5em;*/
color: #fff;
background-color: #29e;
border: solid 2px #fff;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
transition: background-color 0.3s;
}
.drag-drop.can-drop {
color: #000;
background-color: #4e4;
}
#draggable::before {
content: "#" attr(id);
font-weight: bold;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.6/interact.min.js"></script>
<div id="wrapper">
<div id="dragabble" class="draggable drag-drop">
#yes-drop
</div>
<!--<div id="dropZone" class="dropzone"></div>-->
<table id="schedule" width="100%">
<thead>
<tr>
<th></th>
<th>Ven1</th>
<th>Ven2</th>
<th>Ven3</th>
<th>Ven4</th>
<th>Ven5</th>
<th>N.Crane</th>
<th>S.Crane</th>
<th>TrainWell 1</th>
<th>TrainWell 2</th>
<th>InbShip</th>
<th>InbCoat</th>
<th>InbTrain</th>
</tr>
</thead>
<tbody>
<tr>
<td>0/0[2]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
<tr>
<td>0/6[3]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
<tr>
<td>0/6[2]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
<tr>
<td>0/6[4]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
</tbody>
</table>
</div>
无论如何,如果有人有建议或知道如何使用 interact.js 的捕捉功能使其工作,将不胜感激,无论是捕捉网格还是锚点
我正在努力创建某种调度程序,我正在使用 interact.js 来处理元素的所有拖动&drop/snapping,但我很难居中和制作捕捉到 TD
的元素您可以检查this fiddle to see what I got,如果您将可拖动对象拖动到任何单元格的左上角,您会看到捕捉有点起作用,但它不会使元素居中,也不会总是发生,它必须在一个特定的位置才能使捕捉工作,而不是总是将它捕捉到单元格的内部,有时,拖动元素会将它的一部分从单元格中移出。
我已经查看了插件 github 上的 Snap 示例,它让我了解了如何实现我正在寻找的东西。网格系统对我不起作用,因为该项目需要一个空列作为某种空白。
任何帮助将不胜感激。
单元格上方的十字是捕捉的位置,我的意思是,这是锚点的位置,并不完美,我仍在努力使它们居中
这是代码
var element = document.getElementById("schedule");
var anchors = [];
document.querySelectorAll(".dropzone").forEach(function (td, i) {
var boundRect = td.getBoundingClientRect();
var anchor = {
x: boundRect.left + 30,
y: boundRect.top + 15,
range: 20
}
anchors.push(anchor);
});
anchors.forEach(function(anchor, i){
var textNode = document.createElement("div");
textNode.appendChild(document.createTextNode("+"));
textNode.style.position = "absolute";
textNode.style.top = anchor.y + "px";
textNode.style.left = anchor.x + "px";
textNode.style.zIndex = 100;
textNode.style.fontWeight = "bolder";
document.querySelector("#wrapper").appendChild(textNode);
});
// target elements with the "draggable" class
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// snapping to grid
snap: {
targets: anchors,
enabled: true,
endOnly: true,
//offset: 'startCoords'
},
// keep the element within the area of it's parent
restrict: {
drag: element,
endOnly: false,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
// enable autoScroll
autoScroll: true,
// call this function on every dragmove event
onmove: dragMoveListener,
// call this function on every dragend event
onend: function (event) {
}
});
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '#dragabble',
// Require a 75% element overlap for a drop to be possible
overlap: 0.6,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
draggableElement.textContent = 'Dragged in';
var dropRect = interact.getElementRect(event.target),
dropCenter = {
x: dropRect.left + 30,
y: dropRect.top + 15
};
event.draggable.snap({
anchors: dropCenter
});
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
event.relatedTarget.textContent = 'Dragged out';
event.draggable.snap(false);
},
ondrop: function (event) {
event.relatedTarget.textContent = 'Dropped';
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
function dragMoveListener(event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
// this is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener;
好吧,没关系,我决定按照我想要的方式实现自己的捕捉it/need。
我刚刚在 ondrop
事件中添加了一些代码,以将 dragabble
设置到它着陆的 td 中心,并制作了我需要的快照
var element = document.getElementById("schedule");
// target elements with the "draggable" class
interact('.draggable')
.draggable({
// enable inertial throwing
inertia: true,
// keep the element within the area of it's parent
restrict: {
drag: element,
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
// enable autoScroll
autoScroll: true,
// call this function on every dragmove event
onmove: dragMoveListener,
// call this function on every dragend event
onend: function (event) {
}
});
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '#dragabble',
// Require a 75% element overlap for a drop to be possible
overlap: 0.6,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
draggableElement.textContent = 'Dragged in';
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
event.relatedTarget.textContent = 'Dragged out';
},
ondrop: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target,
dropRect = getOffset(dropzoneElement),
x = dropRect.left,
y = dropRect.top;
draggableElement.textContent = 'Dropped';
// translate the element
draggableElement.style.webkitTransform =
draggableElement.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
draggableElement.setAttribute('data-x', x);
draggableElement.setAttribute('data-y', y);
event.relatedTarget.textContent = 'Dropped';
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
function dragMoveListener(event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
function getOffset(el) {
el = el.getBoundingClientRect();
return {
left: el.left + window.scrollX,
top: el.top + window.scrollY
}
}
// this is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener;
td
{
width: 68px;
height: 32px;
}
#wrapper
{
width: 100%;
height: 100%;
}
#dropZone {
height: 140px;
background-color: Gray;
}
.dropzone {
background-color: #ccc;
border: dashed 4px transparent;
border-radius: 4px;
/*margin: 10px auto 30px;*/
padding: 6px;
/*width: 80%;*/
transition: background-color 0.3s;
}
.drop-active {
border-color: #aaa;
}
.drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
}
.drag-drop {
display: inline-block;
width: 60px;
height: 30px;
/*padding: 2em 0.5em;*/
color: #fff;
background-color: #29e;
border: solid 2px #fff;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
transition: background-color 0.3s;
}
.drag-drop.can-drop {
color: #000;
background-color: #4e4;
}
#draggable::before {
content: "#" attr(id);
font-weight: bold;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.6/interact.min.js"></script>
<div id="wrapper">
<div id="dragabble" class="draggable drag-drop">
#yes-drop
</div>
<!--<div id="dropZone" class="dropzone"></div>-->
<table id="schedule" width="100%">
<thead>
<tr>
<th></th>
<th>Ven1</th>
<th>Ven2</th>
<th>Ven3</th>
<th>Ven4</th>
<th>Ven5</th>
<th>N.Crane</th>
<th>S.Crane</th>
<th>TrainWell 1</th>
<th>TrainWell 2</th>
<th>InbShip</th>
<th>InbCoat</th>
<th>InbTrain</th>
</tr>
</thead>
<tbody>
<tr>
<td>0/0[2]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
<tr>
<td>0/6[3]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
<tr>
<td>0/6[2]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
<tr>
<td>0/6[4]</td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
<td class="dropzone"></td>
</tr>
</tbody>
</table>
</div>
无论如何,如果有人有建议或知道如何使用 interact.js 的捕捉功能使其工作,将不胜感激,无论是捕捉网格还是锚点