首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript拖拽-插图风格的“智能向导”

Javascript拖拽-插图风格的“智能向导”
EN

Stack Overflow用户
提问于 2013-11-19 15:06:10
回答 5查看 3.4K关注 0票数 4

我正在寻找一种方法来实现风格的“智能指南”时拖放Javascript。我目前正在使用jQuery UI的draggable

代码语言:javascript
复制
$('.object').draggable({
    containment: 'parent',
    snap: '.other-objects',
    snapTolerance: 5
})

这完成了我想要的90%的功能--我可以在它的父母内部拖动.object,当它足够接近它的时候,它会把它的边缘拉到.other-objects上。

然而,我想要的是出现一条线(或者某种向导),如果它与另一个物体的边缘相一致,那么我就可以把东西连在一起,而不用它们直接挨着。

有没有人知道这是否可能,或者我会怎么做?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-11-19 16:45:56

我开始和jsFiddle混在一起。这并不完美,但它应该会让你开始。

大部分逻辑位于jQuery UI的拖动事件处理程序中:

代码语言:javascript
复制
function (event, ui) {

        // You'll want to debounce this function so that it doesn't run every mouse move (e.g. see Ben Alman's site @ http://tinyurl.com/37dyjug)
        var debounceTime = 200; // milliseconds
        setTimeout(function () {

            // Loop through all 'other-object's and see if we're lined up
            $(".other-object").each(function (idx, other) {
                var $other = $(other);

                // Determine whether we're "close enough" to display the line
                var padding = 1;
                var closeToLeft = Math.abs($other.offset().left - ui.offset.left) < padding;
                var closeToTop = Math.abs($other.offset().top - ui.offset.top) < padding;
                // You can add closeToRight/closeToBottom, but you may need to do some calculation, e.g. right = left + width

                // If we're close, display a line, otherwise remove that same line
                // TODO: Find a better way of tagging which 'other-object' this line belongs to, using IDs or something more stable than the index of the jQuery each() function!
                var id = 'leftOther' + idx;
                if (closeToLeft) {
                    console.debug(idx, 'left');
                    $('.parent').not(':has(#' + id + ')').append('<div id="' + id + '" class="line vertical" style="left: ' + $other.offset().left + 'px;"/>');
                } else {
                    $('#' + id).remove();
                }

                id = 'topOther' + idx;
                if (closeToTop) {
                    console.debug(idx, 'top');
                    $('.parent').not(':has(#' + id + ')').append('<div id="topOther' + idx + '" class="line horizontal" style="top: ' + $other.offset().top + 'px;"/>');
                } else {
                    $('#' + id).remove();
                }
            }); // End of 'other-object' loop

        }, debounceTime); // End of setTimeout
    } // End of drag function

如果稍后我有时间,我会回来再想一想,但我想你会喜欢半个答案,所以现在就开始吧。

票数 4
EN

Stack Overflow用户

发布于 2014-02-27 07:42:05

我把小提琴叉在上面,增加了中线的支撑。

代码语言:javascript
复制
drag: function(event, ui) {
    var inst = $(this).data("draggable"), o = inst.options;
    var d = o.tolerance;
    $(".objectx").css({"display":"none"});
    $(".objecty").css({"display":"none"});
        var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
            y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height,
            xc = (x1 + x2) / 2, yc = (y1 + y2) / 2;
        for (var i = inst.elements.length - 1; i >= 0; i--){
            var l = inst.elements[i].left, r = l + inst.elements[i].width,
                t = inst.elements[i].top, b = t + inst.elements[i].height,
                hc = (l + r) / 2, vc = (t + b) / 2;
                var ls = Math.abs(l - x2) <= d;
                var rs = Math.abs(r - x1) <= d;
                var ts = Math.abs(t - y2) <= d;
                var bs = Math.abs(b - y1) <= d;
                var hs = Math.abs(hc - xc) <= d;
                var vs = Math.abs(vc - yc) <= d; 
            if(ls) {
                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
                $(".objectx").css({"left":l-d-4,"display":"block"});
            }
            if(rs) {
                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
                 $(".objectx").css({"left":r-d-4,"display":"block"});
            }

            if(ts) {
                ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
                $(".objecty").css({"top":t-d-4,"display":"block"});
            }
            if(bs) {
                ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
                $(".objecty").css({"top":b-d-4,"display":"block"});
            }
            if(hs) {
                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: hc - inst.helperProportions.width/2 }).left - inst.margins.left;
                 $(".objectx").css({"left":hc-d-4,"display":"block"});
            }
            if(vs) {
                ui.position.top = inst._convertPositionTo("relative", { top: vc - inst.helperProportions.height/2, left: 0 }).top - inst.margins.top;
                $(".objecty").css({"top":vc-d-4,"display":"block"});
            }


        };
    }

这样,在行/列中对齐元素就更容易了。

检查下面的小提琴:

http://jsfiddle.net/elin/A6CpP/

票数 8
EN

Stack Overflow用户

发布于 2013-11-19 18:37:14

您可以尝试创建这样的插件

代码语言:javascript
复制
$.ui.plugin.add("draggable", "smartguides", {
start: function(event, ui) {
    var i = $(this).data("draggable"), o = i.options;
    i.elements = [];
    $(o.smartguides.constructor != String ? ( o.smartguides.items || ':data(draggable)' ) : o.smartguides).each(function() {
        var $t = $(this); var $o = $t.offset();
        if(this != i.element[0]) i.elements.push({
            item: this,
            width: $t.outerWidth(), height: $t.outerHeight(),
            top: $o.top, left: $o.left
        });
    });
},
drag: function(event, ui) {
    var inst = $(this).data("draggable"), o = inst.options;
    var d = o.tolerance;
    $(".objectx").css({"display":"none"});
    $(".objecty").css({"display":"none"});
        var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
            y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
        for (var i = inst.elements.length - 1; i >= 0; i--){
            var l = inst.elements[i].left, r = l + inst.elements[i].width,
                t = inst.elements[i].top, b = t + inst.elements[i].height;
                var ls = Math.abs(l - x2) <= d;
                var rs = Math.abs(r - x1) <= d;
                var ts = Math.abs(t - y2) <= d;
                var bs = Math.abs(b - y1) <= d;
            if(ls) {
                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
                $(".objectx").css({"left":l-d-4,"display":"block"});
            }
            if(rs) {
                ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
                 $(".objectx").css({"left":r-d-4,"display":"block"});
            }
            if(ts) {
                ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
                $(".objecty").css({"top":t-d-4,"display":"block"});
            }
            if(bs) {
                ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
                $(".objecty").css({"top":b-d-4,"display":"block"});
            }
        };
    }
});    

像这样使用它

代码语言:javascript
复制
$('.other-objects').draggable({
    containment: 'parent',
    smartguides:".other-objects",
    tolerance:5
});    

http://jsfiddle.net/Vd5X6/

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20075009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档