关于svg无法使用droppable的二三事

121 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

1、前言

辛辛苦苦六七天,当我终于把时间轴的拖拽所需要的技术细节搞懂后,才发现SVG无法作为容器用以droppable(),就是说svgjQueryUI只能结合一半,即只能结合draggable()部分。行吧,那就想办法搞定droppable()部分。

2、模拟jQueryUIdroppable()

如果按droppable()的操作流程是:

1、选中组件移入svg容器--》移到相应位置--》松开鼠标,讲组件放置到SVG容器中

2、选中组件移入svg容器--》移出svg容器

基于上面两种操作,可以通过 鼠标移入移出弹起事件模拟jQueryUI的droppable行为。

mouseover 记录放置当前区域信息
mouseout  清空放置区域记录
mouseup   鼠标抬起时放置元素

2.1 draggable部分

因为不能使用droppable(),所以无法使用 ui 对象来传递拖拽DOM对象,此时使用组件ID来记录拖拽的对象。

var thisEleId = "";//记录拖拽的组件元素,不同的组件有不同的ID标记
$( ".draggable" ).draggable({
    helper: "clone",
    cursor: "pointer",
    zIndex: 9999,
    cursorAt: { left: -2 },
    start: function (event, ui) {
        thisEleId = ui.helper.context.id;//记录拖动元素的ID
    },
    stop: function(event, ui){
        thisEleId = "";//拖动结束时,讲 thisEleId 置空,以免出现bug
    }
});

2.2 mouseup事件

当鼠标在svg容器内松开时,判断thisEleId是否为空,如果不为空,则代表有组件拖进来了,鼠标弹起时,讲元素复制一份到SVG容器里。

//container 为 svg容器的ID
$("#container").on("mouseup", function (ev) {
    if (thisEleId != "") {
        var currentX = ev.offsetX;//鼠标移动中的当前位置
        var currentY = ev.offsetY;//鼠标移动中的当前位置
        console.log(currentX+"==="+currentY);
        if(thisEleId == "circles"){//创建一个同心圆
            var newDom = $("#circlesSvg").clone(true);
            newDom.attr("id","circlesSvg"+count);
            newDom.css("display","");
            newDom.attr("transform","translate("+currentX+","+currentY+")");
            $("#container").append(newDom);
            bindMouseEvent($("#circlesSvg"+count));
            count++;
        }
    }
});

2.3