JQuery UI set up my own tolerance

那年仲夏 提交于 2020-01-24 16:17:10

问题


I´m working on game for my little baby. I want to change default tolerance in droppable object. I know, that there are default values like touch, fit, intersect and pointer. But in my app it doesn't work correctly, because I want something between fit and intersect. When I use fit, it is too difficult to insert into correct position, and when I use intersect, it is too light. Here is my HTML source:

<!DOCTYPE html>
<html lang="sk">
    <head>
        <title>
            Puzzle Slovakia
        </title>
        <script src="jquery-2.1.3.min.js"></script>
        <script src="jquery-ui.js"></script>
        <script src="jquery.ui.touch-punch.js"></script>
        <script type="text/JavaScript" src="javas.js"></script>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
        <section>
            <div id="game">
                <div id="complete">
                    <img src="images/map.png">
                </div>
            </div>
        </section>
    </body>
</html>

And there is my JS code:

window.onload = function() {
    var hra = document.getElementById("game");
    hra.innerHTML+="<div class='place' id='BAp'></div><img class='puzzle' id='BA' src='images/puzzle/BA.png'>";
    hra.innerHTML+="<div class='place' id='TTp'></div><img class='puzzle' id='TT' src='images/puzzle/TT.png'>";
    hra.innerHTML+="<div class='place' id='TNp'></div><img class='puzzle' id='TN' src='images/puzzle/TN.png'>";
    hra.innerHTML+="<div class='place' id='ZAp'></div><img class='puzzle' id='ZA' src='images/puzzle/ZA.png'>";
    hra.innerHTML+="<div class='place' id='BBp'></div><img class='puzzle' id='BB' src='images/puzzle/BB.png'>";
    hra.innerHTML+="<div class='place' id='KEp'></div><img class='puzzle' id='KE' src='images/puzzle/KE.png'>";
    hra.innerHTML+="<div class='place' id='PPp'></div><img class='puzzle' id='PP' src='images/puzzle/PP.png'>";
    hra.innerHTML+="<div class='place' id='NRp'></div><img class='puzzle' id='NR' src='images/puzzle/NR.png'>"; 

    $('.puzzle').draggable( {
        containment:'parent',
        cursor:'move',
    });

    $('.place').droppable ( {
        accept: '.puzzle',
        drop: dropPicture,
        tolerance: 'intersect'
    });
}

function dropPicture( event, ui ) {
  if ( $(this).attr('id') == ui.draggable.attr('id') + "p" ) {
    ui.draggable.draggable( 'disable' );
    ui.draggable.attr('class','done');
    $(this).droppable( 'disable' );
    ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } );
  } 
}

回答1:


You could modify intersect function of jquery-ui to allow this. Most flexible way would be to be able to add a custom function returning true when droppable should be activated, and false when not. This would give complete control on the tolerance. Something like this:

$.ui.intersect = function(draggable, droppable, toleranceMode) {

  if (!droppable.offset) {
    return false;
  }

  var draggableLeft, draggableTop,
    x1 = (draggable.positionAbs || draggable.position.absolute).left,
    y1 = (draggable.positionAbs || draggable.position.absolute).top,
    x2 = x1 + draggable.helperProportions.width,
    y2 = y1 + draggable.helperProportions.height,
    l = droppable.offset.left,
    t = droppable.offset.top,
    r = l + droppable.proportions.width,
    b = t + droppable.proportions.height;
  
  // With next line this allows to set a function as toleranceMode
  if (typeof toleranceMode === "function") {
    return toleranceMode(draggable, droppable);
  } else {
    // If it's not a function, then normal code applies
    switch (toleranceMode) {
      case "custom":
        return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
          x2 - (draggable.helperProportions.width / 2) < r && // Left Half
          t < y1 && // Bottom Half
          b > y1 + 15); // Top Half
      case "fit":
        return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
      case "intersect":
        return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
          x2 - (draggable.helperProportions.width / 2) < r && // Left Half
          t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
          y2 - (draggable.helperProportions.height / 2) < b); // Top Half
      case "pointer":
        draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
        draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
        return isOverAxis(draggableTop, t, droppable.proportions().height) && isOverAxis(draggableLeft, l, droppable.proportions().width);
      case "touch":
        return (
          (y1 >= t && y1 <= b) || // Top edge touching
          (y2 >= t && y2 <= b) || // Bottom edge touching
          (y1 < t && y2 > b) // Surrounded vertically
        ) && (
          (x1 >= l && x1 <= r) || // Left edge touching
          (x2 >= l && x2 <= r) || // Right edge touching
          (x1 < l && x2 > r) // Surrounded horizontally
        );
      default:
        return false;
    }
  }

};

$("#draggable").draggable();


$("#droppable").droppable({
  hoverClass: "hover",
  tolerance: function(draggable, droppable) {
    // Calculations will be made on the small div 
    // inside the draggable. This is the equivalent 
    // of touch tolerance, but applied not to the draggable
    // itself, but to another div
    var toleranceDiv = $('#toleranceDiv');
    x1 = toleranceDiv.offset().left,
      y1 = toleranceDiv.offset().top,
      x2 = x1 + toleranceDiv.width(),
      y2 = y1 + toleranceDiv.height(),
      l = droppable.offset.left,
      t = droppable.offset.top,
      r = l + droppable.proportions.width,
      b = t + droppable.proportions.height;
    return (
      (y1 >= t && y1 <= b) || // Top edge touching
      (y2 >= t && y2 <= b) || // Bottom edge touching
      (y1 < t && y2 > b) // Surrounded vertically
    ) && (
      (x1 >= l && x1 <= r) || // Left edge touching
      (x2 >= l && x2 <= r) || // Right edge touching
      (x1 < l && x2 > r) // Surrounded horizontally
    );
  },
  over: function(event, ui) {
    $('#draggable').css('opacity', 0.8);
  },
  out: function(event, ui) {
    $('#draggable').css('opacity', 0.5);
  },
  drop: function(event, ui) {
    console.log('dropped');
  }
});
#draggable {
  width: 100px;
  height: 100px;
  background-color: blue;
  opacity: 0.5;
  position: absolute;
}
#toleranceDiv {
  width: 20px;
  height: 20px;
  top: 30px;
  left: 30px;
  background-color: yellow;
  position: absolute;
}
#droppable {
  width: 200px;
  height: 200px;
  background-color: green;
  opacity: 1;
  top: 250px;
  left: 250px;
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<div id="droppable"></div>
<div id="draggable">
  <div id="toleranceDiv">
  </div>
</div>


来源:https://stackoverflow.com/questions/29924907/jquery-ui-set-up-my-own-tolerance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!