4

我正在尝试使用 SVG 构建座位预订网络应用程序。想象一下,我在 svg 中创建了代表一个空座位的矩形。我想允许用户在“rect”上放置一个 html“image”元素来保留座位。

但是,我无法让 droppable 在 SVG elemnets 上工作。任何人都知道为什么会这样?这是代码:

$('#target').svg();
var svg = $("#target").svg('get');
svg.rect(20, 10, 100, 50, 10, 10, { fill: '#666', class: "droppable" });
$('rect')
        .droppable({
           accept: '.product',
           tolerance: 'touch',
           drop: function (event, ui) {
              alert('df');
           }
        }
4

4 回答 4

8

我查看了 jQuery-ui 源代码并弄清楚为什么它不能与 SVG 一起使用。jQuery 认为它们的宽度和高度为 0px,因此交集测试失败。

在将参数传递给原始函数之前,我包装了 $.ui.intersect 并设置了正确的大小信息。可能有更多的比例对象需要修复,但我在这里做的两个足以修复我的:

$.ui.intersect_o = $.ui.intersect;
$.ui.intersect = function(draggable, droppable, toleranceMode) {
    //Fix helper
    if (draggable.helperProportions && draggable.helperProportions.width === 0 && draggable.helperProportions.height === 0) {
        draggable.helperProportionsBBox = draggable.helperProportionsBBox || $(draggable.element).get(0).getBBox();
        draggable.helperProportions = draggable.helperProportionsBBox;
    }

    //Fix droppable
    if (droppable.proportions && droppable.proportions.width === 0 && droppable.proportions.height === 0) {
        droppable.proportionsBBox = droppable.proportionsBBox || $(droppable.element).get(0).getBBox();
        droppable.proportions = droppable.proportionsBBox;
    }

    return $.ui.intersect_o(draggable, droppable, toleranceMode);
};
于 2014-06-18T01:44:59.387 回答
3

使用 jQuery UI 1.11.4 我不得不将 Eddie 的解决方案更改为以下内容,因为 draggable.proportions 现在是一个函数:

$.ui.intersect_o = $.ui.intersect;
$.ui.intersect = function (draggable, droppable, toleranceMode, event) {
//Fix helper
if (draggable.helperProportions && draggable.helperProportions.width === 0 && draggable.helperProportions.height === 0) {
   draggable.helperProportionsBBox = draggable.helperProportionsBBox || $(draggable.element).get(0).getBBox();
   draggable.helperProportions = draggable.helperProportionsBBox;
}

if (droppable.proportions && !droppable.proportions().width && !droppable.proportions().height)
   if (typeof $(droppable.element).get(0).getBBox === "function") {
       droppable.proportionsBBox = droppable.proportionsBBox || $(droppable.element).get(0).getBBox();
       droppable.proportions = function () {
           return droppable.proportionsBBox;
       };
   }

    return $.ui.intersect_o(draggable, droppable, toleranceMode, event);
};
于 2016-05-25T13:21:22.567 回答
1

如果您想限制svg 元素的下降以仅命中可见内容(例如在polygons中),您可能希望在 Peter Baumann 的建议中使用此添加:

$.ui.intersect_o = $.ui.intersect;
$.ui.intersect = function (draggable, droppable, toleranceMode, event) {
    //Fix helper
    if (draggable.helperProportions && draggable.helperProportions.width === 0 && draggable.helperProportions.height === 0) {
        draggable.helperProportionsBBox = draggable.helperProportionsBBox || $(draggable.element).get(0).getBBox();
        draggable.helperProportions = draggable.helperProportionsBBox;
    }

    if (droppable.proportions && !droppable.proportions().width && !droppable.proportions().height)
        if (typeof $(droppable.element).get(0).getBBox === "function") {
            droppable.proportionsBBox = droppable.proportionsBBox || $(droppable.element).get(0).getBBox();
            droppable.proportions = function () {
                return droppable.proportionsBBox;
            };
        }

    var intersect = $.ui.intersect_o(draggable, droppable, toleranceMode, event);
    if (intersect) {
        var dropTarget = $(droppable.element).get(0);
        if (dropTarget.ownerSVGElement && (typeof (dropTarget.isPointInFill) === 'function') && (typeof (dropTarget.isPointInStroke) === 'function')) {
            var x = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left + draggable.helperProportions.width / 2,
                y = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top  + draggable.helperProportions.height / 2,
                p = dropTarget.ownerSVGElement.createSVGPoint();
            p.x = x;
            p.y = y;
            p = p.matrixTransform(dropTarget.getScreenCTM().inverse());
            if(!(dropTarget.isPointInFill(p) || dropTarget.isPointInStroke(p)))
                intersect = false;
        }
    }
    return intersect;
};
于 2016-06-09T12:20:25.850 回答
0

如果有人有同样的问题,droppable 在 jquery SVG 中不起作用。所以最后,我做了以下事情来创建我自己的可放置事件:

  1. 在 draggable 中,设置当前被拖拽的目标为 draggedObj ,

  2. 在 mouse up 事件中,检查 draggedObj 是否为 null,如果不为 null,则根据当前位置放置 item。(如果您在检测当前位置方面需要帮助,请告诉我)

于 2012-09-27T01:28:50.607 回答