Javascript 拖放&x2B;弹六边形Trello样卡片

Javascript 拖放&x2B;弹六边形Trello样卡片,javascript,html,css,Javascript,Html,Css,我完全被困在一个学校项目中,我们要编写一个看板风格的网络应用程序。我希望能够生成带有一些选项的六边形卡片,并且能够在将它们放在一起时以蜂窝状的方式拖动和捕捉它们。我尝试过不同的方法,但我被卡住了,所以我在寻找一些技巧,或者是否有人能在路上帮助我 我尝试了一些方法,包括最后一个涉及JavaScript和一些JQuery的解决方案,但是六边形使捕捉非常不精确。另外,避免使用任何库也很好,但这不是强制性的 试验 位置 var轴_范围=12; var角点_范围=14; var角点不包括轴=8;

我完全被困在一个学校项目中,我们要编写一个看板风格的网络应用程序。我希望能够生成带有一些选项的六边形卡片,并且能够在将它们放在一起时以蜂窝状的方式拖动和捕捉它们。我尝试过不同的方法,但我被卡住了,所以我在寻找一些技巧,或者是否有人能在路上帮助我

我尝试了一些方法,包括最后一个涉及JavaScript和一些JQuery的解决方案,但是六边形使捕捉非常不精确。另外,避免使用任何库也很好,但这不是强制性的


试验

位置


var轴_范围=12;
var角点_范围=14;
var角点不包括轴=8;
var轴额外范围=-6;
var myItems=[];
var currentElement=null;
变量offX1、offY1、offX2、offY2;
函数getPosition(元素){
返回{
x:parseFloat(element.getAttribute('data-x'))| | 0,
y:parseFloat(element.getAttribute('data-y'))| | 0
};
}
函数isBetween(值、最小值、长度){
返回最小-轴额外范围<值和值<(最小+长度)+轴额外范围;
}
函数getDistance(值1、值2){
返回Math.abs(值1-值2);
}
函数getSnapCoords(元素、轴){
var结果={
伊索克:错
};
if(currentElement&¤tElement!==元素){
var pos=获取位置(元素);
var cur=getPosition(currentElement);
var distX1a=getDistance(位置x,当前x);
var distX1b=getDistance(位置x,电流x+currentElement.offsetWidth);
var distX2a=getDistance(位置x+元素偏移网络宽度,当前x);
var distX2b=getDistance(位置x+element.offsetWidth,当前x+currentElement.offsetWidth);
var distY1a=获取距离(位置y,当前y);
var distY1b=getDistance(位置y,当前y+当前元素偏移视线);
var distY2a=getDistance(位置y+元素偏视,当前y);
var distY2b=getDistance(位置y+element.offsetHeight,当前y+currentElement.offsetHeight);
var distXa=数学最小值(distX1a,distX2a);
var distXb=数学最小值(distX1b,distX2b);
var distYa=数学最小值(distY1a,distY2a);
var distYb=数学最小值(distY1b,distY2b);
if(distXa角点_排除_轴;
结果.x=distX1

.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';
}