我完全沉迷于一个学校项目,我们将在其中编写看板风格的webapp。我希望能够生成带有某些选项的六角形卡片,并能够在将其放置到蜂鸣器时以蜂窝方式将其拖到蜂鸣器中。我尝试了不同的尝试,但遇到了麻烦,所以我一直在寻找一些提示,或者在途中有人可以帮助我。
我已经尝试了一些方法,包括最后一个涉及JavaScript和JQuery的解决方案,但是六边形使得捕捉非常不准确。另外,避免任何库也很不错,但这不是强制性的。
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="container">
<div id="hex" data-x="20" data-y="20" class="hexagon draggable ui-widget-content"></div>
<div id="hex" data-x="50" data-y="50" class="hexagon draggable ui-widget-content"></div>
<div id="hex" data-x="50" data-y="50" class="hexagon draggable ui-widget-content"></div>
<div id="hex" data-x="50" data-y="50" class="hexagon draggable ui-widget-content"></div>
<div id="hex" data-x="50" data-y="50" class="hexagon draggable ui-widget-content"></div>
</div>
<div>
<p id="position">
Position
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
.hexagon {
position: relative;
width: 150px;
height: 86.60px;
background-color: #64C7CC;
margin: 43.30px 0;
}
.hexagon:before,
.hexagon:after {
content: "";
position: absolute;
width: 0;
border-left: 75px solid transparent;
border-right: 75px solid transparent;
}
.hexagon:before {
bottom: 100%;
border-bottom: 43.30px solid #64C7CC;
}
.hexagon:after {
top: 100%;
width: 0;
border-top: 43.30px solid #64C7CC;
}
.ui-widget-content {
border: 1px solid #64C7CC;
background-color: #64C7CC;
color: #222222;
}
.container {
background-color: #FF0000;
position: relative;
width: 800px;
height: 900px;
}
var AXIS_RANGE = 12;
var CORNER_RANGE = 14;
var CORNER_EXCLUDE_AXIS = 8;
var AXIS_EXTRA_RANGE = -6;
var myItems = [];
var currentElement = null;
var offX1, offY1, offX2, offY2;
function getPosition(element) {
return {
x: parseFloat(element.getAttribute('data-x')) || 0,
y: parseFloat(element.getAttribute('data-y')) || 0
};
}
function isBetween(value, min, length) {
return min - AXIS_EXTRA_RANGE < value && value < (min + length) + AXIS_EXTRA_RANGE;
}
function getDistance(value1, value2) {
return Math.abs(value1 - value2);
}
function getSnapCoords(element, axis) {
var result = {
isOK: false
};
if (currentElement && currentElement !== element) {
var pos = getPosition(element);
var cur = getPosition(currentElement);
var distX1a = getDistance(pos.x, cur.x);
var distX1b = getDistance(pos.x, cur.x + currentElement.offsetWidth);
var distX2a = getDistance(pos.x + element.offsetWidth, cur.x);
var distX2b = getDistance(pos.x + element.offsetWidth, cur.x + currentElement.offsetWidth);
var distY1a = getDistance(pos.y, cur.y);
var distY1b = getDistance(pos.y, cur.y + currentElement.offsetHeight);
var distY2a = getDistance(pos.y + element.offsetHeight, cur.y);
var distY2b = getDistance(pos.y + element.offsetHeight, cur.y + currentElement.offsetHeight);
var distXa = Math.min(distX1a, distX2a);
var distXb = Math.min(distX1b, distX2b);
var distYa = Math.min(distY1a, distY2a);
var distYb = Math.min(distY1b, distY2b);
if (distXa < distXb) {
result.offX = offX1;
} else {
result.offX = offX2
}
if (distYa < distYb) {
result.offY = offY1;
} else {
result.offY = offY2
}
var distX1 = Math.min(distX1a, distX1b);
var distX2 = Math.min(distX2a, distX2b);
var distY1 = Math.min(distY1a, distY1b);
var distY2 = Math.min(distY2a, distY2b);
var distX = Math.min(distX1, distX2);
var distY = Math.min(distY1, distY2);
var dist = Math.max(distX, distY);
var acceptAxis = dist > CORNER_EXCLUDE_AXIS;
result.x = distX1 < distX2 ? pos.x : pos.x + element.offsetWidth;
result.y = distY1 < distY2 ? pos.y : pos.y + element.offsetHeight;
var inRangeX1 = isBetween(pos.x, cur.x, currentElement.offsetWidth);
var inRangeX2 = isBetween(cur.x, pos.x, element.offsetWidth);
var inRangeY1 = isBetween(pos.y, cur.y, currentElement.offsetHeight);
var inRangeY2 = isBetween(cur.y, pos.y, element.offsetHeight);
switch (axis) {
case "x":
result.isOK = acceptAxis && (inRangeY1 || inRangeY2);
break;
case "y":
result.isOK = acceptAxis && (inRangeX1 || inRangeX2);
break;
default:
result.isOK = true;
break;
}
}
return result;
}
$('.draggable').each(function() {
var pos = getPosition(this);
this.style.transform = 'translate(' + pos.x + 'px, ' + pos.y + 'px)';
myItems.push(getPosition(this));
});
interact('.draggable').draggable({
onstart: function(event) {
currentElement = event.target;
var pos = getPosition(currentElement);
offX1 = event.clientX - pos.x;
offY1 = event.clientY - pos.y;
offX2 = event.clientX - currentElement.offsetWidth - pos.x;
offY2 = event.clientY - currentElement.offsetHeight - pos.y;
},
onmove: dragMoveListener,
snap: {
targets:
(function() {
var snapPoints = [];
$('.draggable').each(function() {
(function(element) {
// Slide along the X axis
snapPoints.push(
function(x, y) {
var data = getSnapCoords(element, "x");
if (data.isOK) {
return {
x: data.x + data.offX,
range: AXIS_RANGE
};
}
});
// Slide along the Y axis
snapPoints.push(
function(x, y) {
var data = getSnapCoords(element, "y");
if (data.isOK) {
return {
y: data.y + data.offY,
range: AXIS_RANGE
};
}
});
// Snap to corner
snapPoints.push(
function(x, y) {
var data = getSnapCoords(element);
if (data.isOK) {
return {
x: data.x + data.offX,
y: data.y + data.offY,
range: CORNER_RANGE
};
}
});
})(this);
});
return snapPoints;
})()
},
onend: function(event) {
$('.draggable').each(function() {
currentElement = null;
myItems.push(getPosition(this));
});
}
});
function dragMoveListener(event) {
var target = event.target;
var oldPos = getPosition(target);
var x = oldPos.x + event.dx;
var y = oldPos.y + event.dy;
// keep the dragged position in the data-x/data-y attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
$('#position').text('x: ' + x + ' - y: ' + y);
var result = $.grep(myItems, function(e) {
if (e.x == parseInt(target.getAttribute('data-x')) || e.y == parseInt(target.getAttribute('data-y')))
return 1;
});
if (result.length >= 1)
target.style.backgroundColor = '#64C7CC';
else
target.style.backgroundColor = '#64C7CC';
}
因此,回顾一下,我想要实现的可能性是生成新的六边形卡,在其中写标题和评论,然后能够拖放,使它们贴紧厚实形状以形成蜂窝结构。 / p>
任何帮助将不胜感激!
答案 0 :(得分:0)
我确定您现在已经找到了解决方案,但以防万一其他人都在寻找类似的东西。
jQuery提供了许多交互功能,您可以使用它们进行所需的操作。
这是一个使用可拖动的交互和捕捉支持的示例: https://jqueryui.com/draggable/#snap-to
然后,如果要在两个列表之间进行排序并拖动,请执行以下操作: https://jqueryui.com/sortable/#connect-lists
这些资源很容易解释,希望对您有帮助。