这是我解决这个问题的方法。
我将点放在旋转的div外面。这样,我可以确保拖动事件会产生正常行为(不会在奇怪的方向跳跃)。我使用可拖动的处理程序将点附加到鼠标光标上。transformOffset
是一个非常特定的函数,仅适用于这个非常特定的转换(旋转),如果任何其他转换被添加到任何父元素中,它将会出现问题(如果您已经在进行旋转操作,则很可能会发生这种情况)。 - David Mulder我现在正在工作,所以无法为您完成工作,但我可以解释一下解决您问题的最简洁方法背后的数学原理(可能不是最简单的解决方案,但与其他一些技巧相比,一旦实施起来就更加灵活)。
首先,您必须意识到您正在使用的旋转插件正在对您的元素应用变换(transform: rotate(30deg)
),然后由您的浏览器将其转换为矩阵(matrix(0.8660254037844387, 0.49999999999999994, -0.49999999999999994, 0.8660254037844387, 0, 0)
)。
其次,有必要了解通过旋转元素,子元素的轴完全随之旋转绝对和完全地旋转(长时间寻找后没有任何真正的技巧可以规避这一点,这是有道理的),因此唯一的方法将子元素取出父元素,就像其他答案建议的那样,但我假设这在您的应用程序中不是一个选项。
现在,我们需要做的就是取消父元素的原始矩阵,这是一个两步过程。首先,我们需要使用以下代码找到矩阵:
var styles = window.getComputedStyle(el, null);
var matrix = styles.getPropertyValue("-webkit-transform") ||
styles.getPropertyValue("-moz-transform") ||
styles.getPropertyValue("-ms-transform") ||
styles.getPropertyValue("-o-transform") ||
styles.getPropertyValue("transform");
rotate(-30deg)
),可以使用此库(或您的数学书:P)进行操作。left
、top
和手动三角函数1来极大地简化此过程,仅适用于旋转(绕过了逆矩阵甚至矩阵的整个需求),但其明显的缺点是它仅适用于常规旋转并且需要根据使用情况进行更改。1这就是Mohamed Ali在他的答案中所做的事情(在他的jsFiddle中的transformOffset
函数)。
免责声明,我已经有一段时间没有做这些工作了,而且我的矩阵理解从来不是非常好的,因此如果您发现任何错误,请务必指出/纠正。
仅适用于Webkit的webkitConvertPointFromPageToNode
函数处理缺失的行为:
var point = webkitConvertPointFromPageToNode(
document.getElementById("outer"),
new WebKitPoint(event.pageX, event.pageY)
);
jsFiddle: http://jsfiddle.net/kB4ra/108/
为了覆盖其他浏览器,您可以使用在这个StackOverflow答案中描述的方法:https://dev59.com/bmw15IYBdhLWcg3wLI3I#6994825
function coords(event, element) {
function a(width) {
var l = 0, r = 200;
while (r - l > 0.0001) {
var mid = (r + l) / 2;
var a = document.createElement('div');
a.style.cssText = 'position: absolute;left:0;top:0;background: red;z-index: 1000;';
a.style[width ? 'width' : 'height'] = mid.toFixed(3) + '%';
a.style[width ? 'height' : 'width'] = '100%';
element.appendChild(a);
var x = document.elementFromPoint(event.clientX, event.clientY);
element.removeChild(a);
if (x === a) {
r = mid;
} else {
if (r === 200) {
return null;
}
l = mid;
}
}
return mid;
}
var l = a(true),
r = a(false);
return (l && r) ? {
x: l,
y: r
} : null;
}
$('#outer').mousemove(function(event){
var point = convertCoordinates(event, $("#outer"));
$("#point").css({left: point.x+1, top: point.y+1});
});
getRotateAngle
函数用于旋转 - 这将使得在http://jsfiddle.net/kB4ra/118中考虑旋转变得可行(即使鼠标在#outer之外也可以工作)。 - Brilliand在我看来,如果您不旋转div,则div会完全跟随鼠标。 这可能是插件的问题...也许您可以正确模拟可拖动功能?
这基本上可以做到你需要的,但它有些错误。绑定拖动事件处理程序,拦截ui对象并修改它以使用父元素的偏移X和Y。所有的X、Y、top、left等都在这些对象中。我会尽量在今天稍晚一点的时候给你一个更好的例子。祝你好运!
NaN
导致的。 - Starx可能这是您的jQuery库的问题,或者您可以通过分配内部div和外部div的z-order值来检查此问题,请确保您为内部div赋予更高的数字。