2

我一直在研究一个脚本,它将可拖动 div 的包含限制为一个圆圈(而不是一个矩形父 div)。我找到了这个帖子:如何限制圆圈区域内的运动这似乎解决了我的一些问题。我已经准备好适当的函数,当我在拖动函数中调用这些函数时,它将返回 div 的正确 x 和 y 位置。我知道这一点是因为我可以在拖动功能期间检查控制台日志并检查 div 的位置。但是,我的问题是我似乎无法在拖动事件期间设置实际位置。控制台报告了正确的位置值,但 div 实际上从未被限制在圆形边界。例如,如果我将 div 拖到圆的中心,然后将其垂直向上移动到圆的边界之外...... div 不会在圆处停止,但是控制台会将位置钳位到 [0,50]/ /50 是 X 和 Y 轴的圆心。我在其他一些线程上读到我可能必须使用辅助对象,但我似乎没有用这种方法得到任何结果。我发布了一个简化的示例,希望有人可以提供帮助。谢谢你。

this.light = document.createElement("div");
this.light.style.position='absolute';
this.light.style.left="20px";
this.light.style.top="40px";
this.light.style.width="20px";
this.light.style.height="20px";

$(parentdiv).append(this.light);

var circle_cenx = 50.0;
var circle_ceny = 50.0;
var circle_radius = 50.0;

$(this.light).draggable({ 
    drag: function( event, ui ){
        var position = $(that.light).position();
        var result = limit(position.left+10, position.top+10, circle_cenx, circle_ceny);
        $(that.light).css({'top': result.y, 'left': result.x});
        position = $(that.light).position();
        console.log(position);
    }
});

function limit(x, y, cenx, ceny) {
    var dist = distance([x, y], [cenx, ceny]);
    if (dist <= circle_radius) {
        return {x: x, y: y};
    } 
    else {
        x = x - circle_cenx;
        y = y - circle_ceny;
        var radians = Math.atan2(y, x);
        return {
           x: Math.cos(radians) * circle_cenx + circle_radius,
           y: Math.sin(radians) * circle_ceny + circle_radius
        }
    } 
}

function distance(dot1, dot2) {
    var x1 = dot1[0],
        y1 = dot1[1],
        x2 = dot2[0],
        y2 = dot2[1];
    return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
4

3 回答 3

5

是的,我终于弄明白了。我原以为 .position 是只读属性……但事实证明,您也可以使用它来设置位置。因此,在上面的代码中,我创建了一个名为 result 的变量,并存储了 limit 函数的返回值(它返回了包含在包含圈内的鼠标的 x 和 y 值)。所以,在那之后你只需要这样称呼:

ui.position={'top': result.y-10, 'left': result.x-10};

您需要删除该行:

$(that.light).css({'top': result.y, 'left': result.x});

这应该是你所需要的。希望这可以帮助。

于 2013-03-01T00:36:58.483 回答
1

由于我很确定算法并不完全正确,并且您提供的信息对我非常有帮助,因此我很感激并创建了一个 jsfiddle 演示,供大家查看算法的实际应用。我还提供了一个默认界面来玩。

http://jsfiddle.net/s7Uy2

再次感谢。

编码:

CSS:

.ui-controlpad {
width:150px;
height:150px;
border:1px solid black;
-moz-border-radius:75px;
border-radius:75px;
z-index:1000;
}
.ui-controlpad-pad {
position:relative;
width:75px;
height:75px;
top:37.5px;
left:37.5px;
border:1px solid black;
-moz-border-radius:37.5px;
border-radius:37.5px;
z-index:1001;
background-color:grey;
}

html:

<div id="Controlpad"></div>

Javascript:

jQuery.fn.extend({
    controlpad: function (options) {
        $(this[0]).append('<div class="ui-controlpad"></div>');
        $(".ui-controlpad").append('<div class="ui-controlpad-pad"></div>');
        $(".ui-controlpad-pad").draggable({
           drag: options.ondrag,
           revert: true
        });
    }
});
function limit(x, y, cenx, ceny, r) {
    var dist = distance([x, y], [cenx, ceny]);
    if (dist <= r) {
        return { x: x, y: y };
    }
    else {
        x = x - cenx;
        y = y - ceny;
        var radians = Math.atan2(y, x);
        return {
            x: Math.cos(radians) * r + cenx,
            y: Math.sin(radians) * r + ceny
        }
    }
}

function distance(dot1, dot2) {
    var x1 = dot1[0],
        y1 = dot1[1],
        x2 = dot2[0],
        y2 = dot2[1];
    return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
$(document).ready(function(){
    var circle_cenx = 37.5;
    var circle_ceny = 37.5;
    var circle_radius = 37.5;
    $("#Controlpad").controlpad({
        ondrag: function(event, ui){
            var result = limit(ui.position.left, ui.position.top, circle_cenx, circle_ceny, circle_radius);
            ui.position = { 'top': result.y, 'left': result.x };
        }
    });
});
于 2014-02-27T09:18:44.493 回答
0

检查是否包含可拖动元素。希望下面的链接对你有帮助

http://api.jqueryui.com/draggable/#option-containment

contaiment: [x1, y1, x2, y2];

您可以抓住光标位置并进行数学运算以相应地设置 x1、y1、x2 和 y2 的值​​。

于 2013-02-12T12:03:59.133 回答