gpt4 book ai didi

Jquery可通过CSS 'zoom'属性进行拖放

转载 作者:行者123 更新时间:2023-12-01 05:51:51 28 4
gpt4 key购买 nike

在我的应用程序中,我有一个 CSS 缩放可以变化的 div。

不幸的是,这会扰乱坐标空间。当超过可缩放区域 1 页 px != 1px 时:)

当涉及到 droppables 时,它完全破坏了相交检测。

我正在寻找关于我应该从哪里开始尝试处理这个问题的提示?

我在这里做了一个演示。

fiddle :

http://jsfiddle.net/crRvp/1/

HTML:

<div id="dse">
<div id="ds">Drop here!</div>
</div>
<p>
<div id="widget">Drag me!</div>
</p>

CSS:

#dse{
position:relative;
width:640px;
height:360px;
zoom:0.75;
-moz-transform: scale(0.75);
-moz-transform-origin:0 0;
-o-transform: scale(0.75);
-o-transform-origin:0 0;
}

#ds{
position:relative;
zoom:1;
width:640px;
height:360px;
border: solid 1px black;
font-size:2em;
}

#widget{
position:relative;
width:150px;
height:50px;
border: solid 1px black;
}

.droppableActive{
background-color:red;
}

.droppableHover{
background-color:green;
}

JS:

$("#widget").draggable({
opacity : 0.7,
scroll : false,
revert: function(dropped){
var wasDropped = dropped && dropped[0].id == "ds";
if(!wasDropped){$(this).animate({ top: 0, left: 0 }, 'slow');}
return !wasDropped;
}
,
stop: function(evt, ui) {

var canvasLeft = $('#ds').offset().left;
var canvasTop = $('#ds').offset().top;

alert('ui.position.left: ' + (ui.position.left) + ' canvasLeft: ' + canvasLeft);
alert('ui.position.top: ' + (ui.position.top) + ' canvasTop: ' + canvasTop);
}
});

$("#ds").droppable({
activeClass: 'droppableActive',
hoverClass: 'droppableHover',
accept: "#widget",
drop: function(evt, ui){
id = ui.draggable.attr('id');
alert('id: ' + id);
}
});

最佳答案

我遇到了同样的问题,但仅就我而言,可放置和可拖动的元素都位于缩放容器中(具有 zoom css 属性!)。

可拖动可以通过“dragFix”修复轻松修复:

var zoomScale = parseFloat($('.container').css('zoom'));

$('.drag__item').draggable({
drag: function (event, ui) {
var changeLeft = ui.position.left - ui.originalPosition.left;
var newLeft = ui.originalPosition.left + changeLeft / zoomScale;
var changeTop = ui.position.top - ui.originalPosition.top;
var newTop = ui.originalPosition.top + changeTop / zoomScale;

ui.position.left = newLeft;
ui.position.top = newTop;
}
});

要修复droppable,我们需要编辑 jquery-ui 代码。考虑到编辑库源代码不是一个好主意,让我们重写 intersect 方法。问题是 x1y1 坐标(可拖动元素的顶部、左侧)在之前的“dragFix”修复后被破坏,因此,相交检测无法按预期工作。因此我们需要标准化x1y1坐标。

var intersect = $.ui.intersect = (function () {
function isOverAxis(x, reference, size) {
return (x >= reference) && (x < (reference + size));
}

return function (draggable, droppable, toleranceMode, event) {
if (!droppable.offset) {
return false;
}

var x1 = draggable.offset.left + draggable.position.left - draggable.originalPosition.left + draggable.margins.left,//here is the fix for scaled container
y1 = draggable.offset.top + draggable.position.top - draggable.originalPosition.top + draggable.margins.top,//here is the fix for scaled container
x2 = x1 + draggable.helperProportions.width,
y2 = y1 + draggable.helperProportions.height,
l = droppable.offset.left,
t = droppable.offset.top,
r = l + droppable.proportions().width,
b = t + droppable.proportions().height;

switch (toleranceMode) {
case 'fit':
return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
case 'intersect':
return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
x2 - (draggable.helperProportions.width / 2) < r && // Left Half
t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
y2 - (draggable.helperProportions.height / 2) < b); // Top Half
case 'pointer':
return isOverAxis(event.pageY, t, droppable.proportions().height) &&
isOverAxis(event.pageX, l, droppable.proportions().width);
case 'touch':
return (
(y1 >= t && y1 <= b) || // Top edge touching
(y2 >= t && y2 <= b) || // Bottom edge touching
(y1 < t && y2 > b) // Surrounded vertically
) && (
(x1 >= l && x1 <= r) || // Left edge touching
(x2 >= l && x2 <= r) || // Right edge touching
(x1 < l && x2 > r) // Surrounded horizontally
);
default:
return false;
}
};
})();

From jquery 1.12 $.ui.intersect function is scoped so that it cannot be directly modified afterwards. It is called in $.ui.ddmanager as a local variable, so even if you modify $.ui.intersect, it won't be used. Customizing it is a bit more complex. You can do it this way, basically you rescope intersect and then redefine drag and drop method on $.ui.ddmanager so that it calls the modified intersect:

from this answer

$.ui.ddmanager.drag = function (draggable, event) {
// If you have a highly dynamic page, you might try this option. It renders positions
// every time you move the mouse.
if (draggable.options.refreshPositions) {
$.ui.ddmanager.prepareOffsets(draggable, event);
}

// Run through all droppables and check their positions based on specific tolerance options
$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function () {

if (this.options.disabled || this.greedyChild || !this.visible) {
return;
}

var parentInstance, scope, parent,
intersects = intersect(draggable, this, this.options.tolerance, event),
c = !intersects && this.isover ?
'isout' :
(intersects && !this.isover ? 'isover' : null);
if (!c) {
return;
}

if (this.options.greedy) {

// find droppable parents with same scope
scope = this.options.scope;
parent = this.element.parents(':data(ui-droppable)').filter(function () {
return $(this).droppable('instance').options.scope === scope;
});

if (parent.length) {
parentInstance = $(parent[0]).droppable('instance');
parentInstance.greedyChild = (c === 'isover');
}
}

// We just moved into a greedy child
if (parentInstance && c === 'isover') {
parentInstance.isover = false;
parentInstance.isout = true;
parentInstance._out.call(parentInstance, event);
}

this[c] = true;
this[c === 'isout' ? 'isover' : 'isout'] = false;
this[c === 'isover' ? '_over' : '_out'].call(this, event);

// We just moved out of a greedy child
if (parentInstance && c === 'isout') {
parentInstance.isout = false;
parentInstance.isover = true;
parentInstance._over.call(parentInstance, event);
}
});

}

$.ui.ddmanager.drop = function (draggable, event) {
var dropped = false;

// Create a copy of the droppables in case the list changes during the drop (#9116)
$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function () {

if (!this.options) {
return;
}
if (!this.options.disabled && this.visible &&
intersect(draggable, this, this.options.tolerance, event)) {
dropped = this._drop.call(this, event) || dropped;
}

if (!this.options.disabled && this.visible && this.accept.call(this.element[0],
(draggable.currentItem || draggable.element))) {
this.isout = true;
this.isover = false;
this._deactivate.call(this, event);
}

});
return dropped;
}

JSFiddle example

关于Jquery可通过CSS 'zoom'属性进行拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21166755/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com