Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
728 views
in Technique[技术] by (71.8m points)

jquery - Javascript drag/drop - Illustrator style 'smart guides'

I'm looking for a way to implement Adobe Illustrator style 'smart guides' when dragging/dropping in Javascript. I'm currently using jQuery UI's draggable:

$('.object').draggable({
    containment: 'parent',
    snap: '.other-objects',
    snapTolerance: 5
})

This does 90% of what I want - I can drag .object around within it's parent, and it will snap it's edges to .other-objects when it gets close enough.

What I want, however, is for a line of some kind (or a guide of some kind) to appear, if it's in line with the edge of another object, so I can snap stuff in a row without them being directly next to each other.

Does anybody know if this is possible, or how I'd go about doing it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I forked the fiddle above, added support for midlines.

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"});
            }


        };
    }

This way it would be easier to align elements in a row/column.

Check the fiddle below:
http://jsfiddle.net/elin/A6CpP/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...