我已经为此寻找答案而找不到......所以希望有人可以帮助我。我正在尝试创建一个可拖动的div(使用jquery ui),它包含在一个圆圈中(而不是一个正方形)。现在,我已经将遏制设置链接到它的父div,但无论我尝试什么......它仍然允许可拖动元素进入父方形div的角落。我已经尝试设置父div的border-radius,这样它就是圆形而不是正方形(但这可能只是一个css的东西,并没有影响实际的div形状)。有谁知道如何将可拖动的div限制为圆圈? 谢谢, 安迪
var containment_radius = 50;
$(this.dragobject).draggable({
drag: function() {
var position = $(this.dragobject).position();
var result = limit(position.left, position.top, containment_radius, containment_radius);
if (!result.limit) {
$(this.dragobject).x = result.x + "px";
$(this.dragobject).y = result.y + "px";
}
console.log(result);
}
});
function limit(x, y, x1, y1) {
var dist = distance([x, y], [x1, y1]);
if (dist <= containment_radius) {
return {x: x, y: y};
} else {
return {limit: true};
}
}
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));
}
答案 0 :(得分:0)
请参阅this answer,其中显示了如何使用drag
事件进行约束。这是通过更新ui.position
事件处理程序中的drag
变量来完成的。
答案 1 :(得分:0)
Duopixel回复了这个确切的问题,其中一个示例包含在一个圆圈中,而不是正如andyopayne所建议的波浪。
How to constrain movement within the area of a circle
这是一个例子 http://jsfiddle.net/7Asn6/
诀窍是计算与初始和当前阻力位置坐标的距离,
Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
然后用
计算新的x和y坐标 x: Math.cos(radians) * canvas.radius + canvas.center[0],
y: Math.sin(radians) * canvas.radius + canvas.center[1]
在拖回回调中:
答案 2 :(得分:0)
此解决方案遵循Luke H关于更新ui.position的建议。它实现起来很简单(不需要扩展可拖动库存的小部件),但我不喜欢它,因为必须从可拖动的外部访问半径而不是从包含本身中取出。
var radius = 128;
$('.color-picker-map-selector').draggable({
containment: '.map',
drag: function( event, ui ) {
var x = ui.position.left - radius,
y = radius - ui.position.top,
h = Math.sqrt(x*x + y*y);
if (Math.floor(h) > radius) {
ui.position.top = radius - Math.round(radius * y / h);
ui.position.left = Math.round(radius * x / h) + radius;
}
}
});
不需要像许多例子那样使用正弦和余弦等精细的数学函数。
我首选的解决方案是通过添加形状选项(&#39;矩形,圆形&#39;)来扩展小部件,并覆盖内部_generatePosition函数。它使用容器的宽度和高度来查找中心,如果容器不是正方形,它会将可拖动的约束为椭圆。
// add shape option to stock draggable
$.widget( "ui.draggable", $.ui.draggable, {
options: {
shape: 'rectangular'
},
_generatePosition( event, constrainPosition ) {
var position = this._super( event, constrainPosition );
if (this.options.shape != 'circular') return position;
if ( constrainPosition ) {
if ( this.containment ) {
if ( this.relativeContainer ) {
co = this.relativeContainer.offset();
containment = [
this.containment[ 0 ] + co.left,
this.containment[ 1 ] + co.top,
this.containment[ 2 ] + co.left,
this.containment[ 3 ] + co.top
];
} else {
containment = this.containment;
}
var xRadius = Math.floor((containment[ 2 ] - containment[ 0 ]) / 2),
yRadius = Math.floor((containment[ 3 ] - containment[ 1 ]) / 2),
x = position.left - xRadius,
y = yRadius - position.top,
h = Math.sqrt(x*x + y*y);
if (Math.floor(h) > Math.min(xRadius, yRadius)) {
var ye = Math.round(yRadius * y / h),
xe = Math.round(xRadius * x / h);
if ((Math.abs(y) > Math.abs(ye)) || (Math.abs(x) > Math.abs(xe))) {
position.left = xe + xRadius;
position.top = yRadius - ye;
}
}
}
}
return position;
}
});
如果jQuery UI人员更改了_generatePosition的名称和用法,那么会有一些小问题,但是如果他们要更改函数的内部因此它会调用一些辅助函数,比如_constrain()会简化它会很好这段代码非常重要。
另请注意,此解决方案不适用于网格对齐,但可以通过一些额外的代码来完成。
干杯!