繁体   English   中英

拖放到缩放元素上

[英]Dragging and Dropping onto a scaled element

我有一个div元素,我希望能够拖动到缩放元素。 但是,当我这样做时,div元素不会转到元素的右边坐标,但是当我第二次拖动它时它会这样做。

我还认为在添加元素时它会扩展,我想尝试避免。

谁能帮我解决这个问题? (特别是整个没有去正确的地方的东西)

我已经尝试过这样的东西来获得div的实际坐标,但我不知道如何将其转换为可拖动的元素,因为当我拖动某些东西时mousemove不起作用。

$("body").on("mousemove", ".formBackground", function(e){
    div_x = (e.offsetX != null) ? e.offsetX : e.originalEvent.layerX;
    div_y = (e.offsetY != null) ? e.offsetY : e.originalEvent.layerY; 

    console.log("x "+div_x+" y "+div_y); 
});

这是我的实际代码和我的JSFIDDLE的链接

HTML

<div id="drag1" class="drag" style="font-size:12px;background-color:#E2F4FE;width:220px;padding:10px;color:#000;font-weight:normal;">New box</div>
<br />
<br />
<div id="formBox">
    <div id="formScale">
        <div class="formContent">
            <div class="formBackground" style="background-image:url('http://i.imgur.com/roOQNaS.png');"></div>
        </div>
    </div>
</div>

JS

var percent = 1.5;

$("#formScale").css({
    'transform': 'scale(' + percent + ')',
        '-moz-transform': 'scale(' + percent + ')',
        '-webkit-transform': 'scale(' + percent + ')',
        '-ms-transform': 'scale(' + percent + ')'
});

var counter = 0;
//Make element draggable
$(".drag").draggable({
    helper: 'clone',
    containment: 'frame',
    //When first dragged
    stop: function (ev, ui) {
        var pos = $(ui.helper).offset();
        objName = "#clonediv" + counter
        $(objName).css({
            "left": pos.left,
                "top": pos.top
        });
        $(objName).removeClass("drag");
        //When an existiung object is dragged
        $(objName).draggable({
            containment: 'frame',
            stop: function (ev, ui) {
                var pos = $(ui.helper).offset();
                console.log($(this).attr("id"));
                console.log(pos.left)
                console.log(pos.top)
            }
        });
    }
});


$(".formBackground").droppable({
    drop: function (ev, ui) {
        if (ui.draggable.attr('id').search(/drag[0-9]/) != -1) {
            counter++;
            var element = $(ui.draggable).clone();
            element.addClass("tempclass");
            $(this).append(element);
            $(".tempclass").attr("id", "clonediv" + counter);
            $("#clonediv" + counter).removeClass("tempclass");
            //Get the dynamically item id
            draggedNumber = ui.draggable.attr('id').search(/drag([0-9])/)
            itemDragged = "dragged" + RegExp.$1
            console.log(itemDragged)
            $("#clonediv" + counter).addClass(itemDragged);
        }
    }
});

CSS

#formBox {
    position:relative;
}
#formScale {
    border:1px solid red;
    position:relative;
    width:350px;
    height:200px;
    margin:0;
    -webkit-transform-origin: 0 0;
    -moz-transform-origin: 0 0;
    transform-origin: 0 0;
    -ms-transform-origin: 0 0;
}
.formContent {
    position:absolute;
    width:100%;
    height:100%;
}
.formBackground {
    width:100%;
    height:100%;
    background-size:contain;
    background-position:center;
    background-repeat:no-repeat;
}

如果我正确理解你的目标,你需要处理很多事情。

1.相对位置

当HTML元素的父元素发生更改(即元素附加到其他元素)时,它在屏幕上的位置会发生变化,除非它的position属性是fixed (这不是默认值)。
因此,当你将你的div附加到$('.formBackground') (我只是将它formBackground ),它的位置变得相对于它之前的兄弟,或者,如果没有先前的兄弟,则形成formBackground本身。
要解决此问题,您必须从draggable的偏移量中减去formBackground的偏移量。
此外,您需要将position设置为absolute ,因此draggable始终相对于formBackground而不是之前的draggable呈现。

这里解释了CSS position属性

为此,请删除此段落(小提琴中的第19-22行):

$(objName).css({
    "left": pos.left,
        "top": pos.top
});

而是在element.addClass("tempclass");之后添加以下段落element.addClass("tempclass"); (目前第43行):

element.css({
    "position": "absolute",
    "left": ui.offset.left - $(this).offset().left,
    "top": ui.offset.top - $(this).offset().top
});

接下来需要注意的是:

2.偏移缩放

如果现在你要设置var percent = 1.0; 在第1行中,draggable应该保持准确的位置。
然而,对于任何其他因素,它不会,因为它的偏移也是相乘的。

这里解释了CSS transform属性及其scale() ,但是文档没有提到这也适用于对象的偏移,它似乎就是这样。

您只需编辑上面的代码段,即可按percent划分lefttop

element.css({
    "position": "absolute",
    "left": (ui.offset.left - $(this).offset().left) / percent,
    "top": (ui.offset.top - $(this).offset().top) / percent
});

现在,无论设置的percent如何,可拖动的左上角应始终保持在您放置它的位置。

我分叉并编辑了你的小提琴,以反映这两个变化。 由于我还没有10个声望,我不能发布超过2个链接,但无论如何它在这里: http://jsfiddle.net/n7yns9eq/2/http://jsfiddle.net/n7yns9eq/2/

3.(可选)左上角锚定的转换

我发现将元素作为中心而不是左上角的“参考点”更加用户友好。 对我来说似乎更直观。 如果你也发现了,这里是如何做到的:

left / top你必须减去一半的width / height将增加。 在代码中:

element.css({
    "position": "absolute",
    "left": (ui.offset.left - $(this).offset().left - $(ui.draggable).width() * (percent - 1) / 2) / percent,
    "top": (ui.offset.top - $(this).offset().top - $(ui.draggable).height() * (percent - 1) / 2) / percent
});

请注意,不是$(ui.draggable) ,而是不能使用element ,因为此时element尚未呈现,并且由于没有为height设置显式值,因此element.height()将返回0

小提琴: http://jsfiddle.net/9xbgqdeo/1/http://jsfiddle.net/9xbgqdeo/1/

4.死区和非比例移动

我注意到的另一个问题是,现在,如果你在formBackground的最左边三分之一的formBackground放一个拖动,那么就不会发生formBackground 我不知道这是由浏览器引擎(不是调整对象的功能区域)或jquery(忽略转换)引起的。
我能想到解决这个问题的唯一方法是使body droppable而不是formBackground ,检查它是否在formBackground的边框内,如果是,则将其附加在那里,否则丢弃它。
请注意,如果您的页面未填满整个浏览器窗口,则可以使用此选项,您必须设置以下CSS:

html, body {
    width: 100%;
    height: 100%;
}

而且不要忘记,以取代所有的this在可投放功能$('.formBackground')

此外,当从formBackground抓取现有的draggable并移动它时,它会偏离光标,我认为这是不需要的。 为了防止这种情况,我建议将div移回原始父级并恢复在formBackground删除时所做的偏移更改。

老实说,我现在懒得为这两个变化提供小提琴(编辑: http://jsfiddle.net/gtc17z6b/1/http://jsfiddle.net/gtc17z6b/1/ ),但我希望无论如何这都能解决你的问题。

我会看一下这个库:

https://greensock.com/draggable

它确实以正确的方式处理规模和变换:

http://codepen.io/gavrochelegnou/pen/KpWVqo

就像喝一杯水一样容易:

Draggable.create(".box", {type:"x,y", edgeResistance:0.65, bounds:".container", throwProps:true});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM