拖放到缩放元素上
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);
});
这是我的实际代码和 link 我的 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.
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
本身。
要解决此问题,您必须从可拖动对象的偏移量中减去 formBackground
的偏移量。
此外,您需要将 position
设置为 absolute
,因此可拖动对象始终相对于 formBackground
而不是之前的可拖动对象呈现。
The CSS position
property is explained here.
为此,删除这段话(fiddle 中的第 19-22 行):
$(objName).css({
"left": pos.left,
"top": pos.top
});
并在 element.addClass("tempclass");
之后添加以下段落(当前为第 43 行):
element.css({
"position": "absolute",
"left": ui.offset.left - $(this).offset().left,
"top": ui.offset.top - $(this).offset().top
});
接下来要处理的是:
2。偏移缩放
如果现在您要在第 1 行设置 var percent = 1.0;
,则可拖动对象应保持在原处。
然而,对于任何其他因素,它不会,因为它的偏移量也会成倍增加。
The CSS transform
property and its scale()
value are explained here,但是文档没有提到这也适用于对象的偏移量,它似乎就是那样。
您可以通过 percent
:
将上面的代码段简单地编辑为 divide left
和 top
element.css({
"position": "absolute",
"left": (ui.offset.left - $(this).offset().left) / percent,
"top": (ui.offset.top - $(this).offset().top) / percent
});
现在,无论 percent
设置的是什么,可拖动对象的左上角应该始终保持在您放置它的位置。
我分叉并编辑了您的 fiddle 以反映这两个更改。因为我还没有 10 个声望,所以我不能 post 超过 2 个链接,但无论如何这里是:http://jsfiddle.net/n7yns9eq/2/
3。 (可选)左上角锚定转换
我发现将元素的 "point of reference" 设为中心而不是左上角对用户更友好。这对我来说似乎更直观。如果您也发现了这一点,请按以下步骤操作:
从 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
});
请注意,您 不能 使用 element
而不是 $(ui.draggable)
,因为此时 element
尚未呈现,并且没有为 height
设置明确的值,element.height()
将 return 0
.
Fiddle: http://jsfiddle.net/9xbgqdeo/1/
4。死区和非比例移动
我注意到的另一个问题是现在,如果您在 formBackground
的最左边三分之一的下方放置一个可拖动对象,则不会发生放置。我不知道这是由浏览器引擎(未调整对象功能区域的大小)还是 jquery(忽略转换)引起的。
我能想到的解决这个问题的唯一方法是使 body
可丢弃而不是 formBackground
,检查它是否在 formBackground
的边界内,如果是,将其附加到那里,丢弃否则。
请注意,如果您的页面没有填满整个浏览器 window,要使它起作用,您必须设置以下内容 CSS:
html, body {
width: 100%;
height: 100%;
}
并且不要忘记将 droppable 函数中的每个 this
替换为 $('.formBackground')
。
此外,当从 formBackground
抓取一个现有的可拖动对象并四处移动时,它会偏离光标,我认为ider 不需要。为防止这种情况发生,我建议将 div 移回其原始父级并恢复在 formBackground
.
上放置时所做的偏移更改。
老实说,我现在懒得证明ide fiddles 这两个变化(编辑: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});
我有一个 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);
});
这是我的实际代码和 link 我的 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.
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
本身。
要解决此问题,您必须从可拖动对象的偏移量中减去 formBackground
的偏移量。
此外,您需要将 position
设置为 absolute
,因此可拖动对象始终相对于 formBackground
而不是之前的可拖动对象呈现。
The CSS position
property is explained here.
为此,删除这段话(fiddle 中的第 19-22 行):
$(objName).css({
"left": pos.left,
"top": pos.top
});
并在 element.addClass("tempclass");
之后添加以下段落(当前为第 43 行):
element.css({
"position": "absolute",
"left": ui.offset.left - $(this).offset().left,
"top": ui.offset.top - $(this).offset().top
});
接下来要处理的是:
2。偏移缩放
如果现在您要在第 1 行设置 var percent = 1.0;
,则可拖动对象应保持在原处。
然而,对于任何其他因素,它不会,因为它的偏移量也会成倍增加。
The CSS transform
property and its scale()
value are explained here,但是文档没有提到这也适用于对象的偏移量,它似乎就是那样。
您可以通过 percent
:
left
和 top
element.css({
"position": "absolute",
"left": (ui.offset.left - $(this).offset().left) / percent,
"top": (ui.offset.top - $(this).offset().top) / percent
});
现在,无论 percent
设置的是什么,可拖动对象的左上角应该始终保持在您放置它的位置。
我分叉并编辑了您的 fiddle 以反映这两个更改。因为我还没有 10 个声望,所以我不能 post 超过 2 个链接,但无论如何这里是:http://jsfiddle.net/n7yns9eq/2/
3。 (可选)左上角锚定转换
我发现将元素的 "point of reference" 设为中心而不是左上角对用户更友好。这对我来说似乎更直观。如果您也发现了这一点,请按以下步骤操作:
从 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
});
请注意,您 不能 使用 element
而不是 $(ui.draggable)
,因为此时 element
尚未呈现,并且没有为 height
设置明确的值,element.height()
将 return 0
.
Fiddle: http://jsfiddle.net/9xbgqdeo/1/
4。死区和非比例移动
我注意到的另一个问题是现在,如果您在 formBackground
的最左边三分之一的下方放置一个可拖动对象,则不会发生放置。我不知道这是由浏览器引擎(未调整对象功能区域的大小)还是 jquery(忽略转换)引起的。
我能想到的解决这个问题的唯一方法是使 body
可丢弃而不是 formBackground
,检查它是否在 formBackground
的边界内,如果是,将其附加到那里,丢弃否则。
请注意,如果您的页面没有填满整个浏览器 window,要使它起作用,您必须设置以下内容 CSS:
html, body {
width: 100%;
height: 100%;
}
并且不要忘记将 droppable 函数中的每个 this
替换为 $('.formBackground')
。
此外,当从 formBackground
抓取一个现有的可拖动对象并四处移动时,它会偏离光标,我认为ider 不需要。为防止这种情况发生,我建议将 div 移回其原始父级并恢复在 formBackground
.
老实说,我现在懒得证明ide fiddles 这两个变化(编辑: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});