javascript - 为什么 jquery sortable 不适用于 Canvas ?

标签 javascript html css jquery-ui jquery-plugins

我有两个容器 sortable1sortable2 并且都有多个 Canvas 。我正在使用 jquery sortable 插件将 Canvas 的位置从一个容器更改为另一个容器或在同一容器内,代码是:

$( function() {
    $( "#sortable1, #sortable2" ).sortable({
        connectWith: ".sortable_card",
        appendTo:".column_box_one",
        helper: "clone",
    }).disableSelection();
}); 

当我移动 Canvas 以更改位置时,它会在没有图像和文本内容的情况下移动,所以有人可以建议如何修复它吗?实际上我想克隆 Canvas 而不会在排序过程中丢失任何数据。

谢谢

最佳答案

没有示例,我试图按照您的描述复制问题。我构建了以下基本示例:

$(function() {
  function draw(cObj, cA, cB) {
    var ctx = cObj[0].getContext('2d');
    ctx.fillStyle = cA;
    ctx.fillRect(10, 10, 50, 50);
    ctx.fillStyle = cB;
    ctx.fillRect(30, 30, 50, 50);
  }

  draw($("#canvas-1"), "rgb(255,0,0)", "rgba(0,255,0,0.5)");
  draw($("#canvas-2"), "rgb(0,255,0)", "rgba(0,0,255,0.5)");
  draw($("#canvas-3"), "rgb(0,0,255)", "rgba(255,0,0,0.5)");
  draw($("#canvas-4"), "rgb(0,255,0)", "rgba(255,0,0,0.5)");
  draw($("#canvas-5"), "rgb(255,0,0)", "rgba(0,0,255,0.5)");
  draw($("#canvas-6"), "rgb(0,0,0)", "rgba(20,20,20,0.5)");
  draw($("#canvas-7"), "rgb(20,20,20)", "rgba(40,40,40,0.5)");
  draw($("#canvas-8"), "rgb(40,40,40)", "rgba(60,60,60,0.5)");
  draw($("#canvas-9"), "rgb(60,60,60)", "rgba(80,80,80,0.5)");

  $("#sortable1, #sortable2").sortable({
    connectWith: ".connectedSortable"
  }).disableSelection();
});
#sortable1,
#sortable2 {
  border: 1px solid #eee;
  min-height: 20px;
  list-style-type: none;
  margin: 0;
  padding: 5px 0 0 0;
  float: left;
  margin-right: 10px;
  width: 105px;
}

#sortable1 li,
#sortable2 li {
  margin: 0;
  padding: 0;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul id="sortable1" class="connectedSortable">
  <li class="ui-state-default"><canvas id="canvas-1" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-2" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-3" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-4" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-5" width="100" height="100"></canvas></li>
</ul>

<ul id="sortable2" class="connectedSortable">
  <li class="ui-state-default"><canvas id="canvas-6" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-7" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-8" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-9" width="100" height="100"></canvas></li>
</ul>

这没有问题,不会复制您所描述的内容。然后我添加了 helper: "clone" 选项,我可以立即看到 helper 不包含上下文,因为它只是 Canvas 容器的克隆,而不是它的上下文。

我们需要一个函数来读取上下文并将其添加到我们的克隆中。

A function that will return a DOMElement to use while dragging. The function receives the event and the element being sorted.

来源:Helper | Sortable Widget | jQuery UI API Documentation

$(function() {
  function draw(cObj, cA, cB) {
    var ctx = cObj[0].getContext('2d');
    ctx.fillStyle = cA;
    ctx.fillRect(10, 10, 50, 50);
    ctx.fillStyle = cB;
    ctx.fillRect(30, 30, 50, 50);
  }

  function clone(cObj, aObj) {
    if (aObj == undefined) {
      aObj = {};
    }
    var newCanvas = $("<canvas>").attr(aObj).prop({
      width: cObj.width(),
      height: cObj.height()
    });
    var ctx = newCanvas[0].getContext("2d");
    ctx.drawImage(cObj[0], 0, 0);
    return newCanvas;
  }

  draw($("#canvas-1"), "rgb(255,0,0)", "rgba(0,255,0,0.5)");
  draw($("#canvas-2"), "rgb(0,255,0)", "rgba(0,0,255,0.5)");
  draw($("#canvas-3"), "rgb(0,0,255)", "rgba(255,0,0,0.5)");
  draw($("#canvas-4"), "rgb(0,255,0)", "rgba(255,0,0,0.5)");
  draw($("#canvas-5"), "rgb(255,0,0)", "rgba(0,0,255,0.5)");
  draw($("#canvas-6"), "rgb(0,0,0)", "rgba(20,20,20,0.5)");
  draw($("#canvas-7"), "rgb(20,20,20)", "rgba(40,40,40,0.5)");
  draw($("#canvas-8"), "rgb(40,40,40)", "rgba(60,60,60,0.5)");
  draw($("#canvas-9"), "rgb(60,60,60)", "rgba(80,80,80,0.5)");

  $("#sortable1, #sortable2").sortable({
    connectWith: ".connectedSortable",
    helper: function(e, item) {
      var li = $("<li>").css("border", "1px solid #000");
      var newCan = clone($("canvas", item));
      li.append(newCan);
      return li[0];
    }
  }).disableSelection();
});
#sortable1,
#sortable2 {
  border: 1px solid #eee;
  min-height: 20px;
  list-style-type: none;
  margin: 0;
  padding: 5px 0 0 0;
  float: left;
  margin-right: 10px;
  width: 105px;
}

#sortable1 li,
#sortable2 li {
  margin: 0;
  padding: 0;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul id="sortable1" class="connectedSortable">
  <li class="ui-state-default"><canvas id="canvas-1" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-2" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-3" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-4" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-5" width="100" height="100"></canvas></li>
</ul>

<ul id="sortable2" class="connectedSortable">
  <li class="ui-state-default"><canvas id="canvas-6" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-7" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-8" width="100" height="100"></canvas></li>
  <li class="ui-state-default"><canvas id="canvas-9" width="100" height="100"></canvas></li>
</ul>

现在我们有了一个合适的 helper 。助手仅在排序期间存在,并在列表更新后被销毁。您将需要评估从源列表中完全“克隆”该元素的重要性,因为它不像可拖动的那样保留原始元素。 Sortable 具有不同的逻辑,其设计理念是您将元素移动到列表(或另一个列表)中的另一个位置,并且不希望有一个挥之不去的克隆。

如果真的很重要,可以考虑从 Draggable 开始,然后拖入 Sortable。如果您需要两者都可排序,则必须使用 startstopupdate 来创建、克隆和重新附加元素回到开始,到它在原始列表中的正确位置。说起来容易做起来难。

关于javascript - 为什么 jquery sortable 不适用于 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57215160/

相关文章:

javascript - 动态向 Laravel 表单添加字段

javascript - 单击 anchor ,在同一窗口中下载文档

javascript - 用javascript html5将整个图像包裹在圆柱形杯子上

javascript - 防止 JavaScript 方法运行两次直到其执行结束

javascript - jQuery - 选择当前表行值

javascript - 如果对象传播不是可迭代的,它如何工作?

javascript - 如何防止关闭html标签在Jquery事件启动后自动出现?

javascript - CSS:隐藏元素仍然占用打印输出空间

javascript - 动态 JavaScript 日期选择器

javascript - Next Div 左右浮动两个div后显示不正确