我使用以下脚本来获取鼠标单击坐标处的重叠DIV元素列表。
在此示例中,如果DIV未旋转,脚本可以正常工作:
http://jsfiddle.net/eyxt2tt1/2/
如果我在DIV上apply a rotation
并且用户点击(在此示例中靠近红色标记)
http://jsfiddle.net/eyxt2tt1/3/
脚本将始终返回两个DIV,而不应只考虑一个。
我需要知道:
注意:
$(document).click(function (e) {
var hitElements = getHitElements(e);
var output = $('#output');
output.html('');
for (var i = 0; i < hitElements.length; ++i) {
output.html(output.html() + '<br />' + hitElements[i][0].tagName + ' ' + hitElements[i][0].id);
};
});
var getHitElements = function (e) {
var x = e.pageX;
var y = e.pageY;
var hitElements = [];
$(':visible').each(function () {
console.log($(this).attr("id"), $(this).outerWidth());
var offset = $(this).offset();
console.log('+++++++++++++++++++++');
console.log('pageX: ' + x);
console.log('pageY: ' + y);
console.log($(this).attr("id"), $(this).offset());
console.log('+++++++++++++++++++++');
if (offset.left < x && (offset.left + $(this).outerWidth() > x) && (offset.top < y && (offset.top + $(this).outerHeight() > y))) {
console.log('included: ', $(this).attr("id"));
console.log('from 0p far x: ', $(this).attr("id"), offset.left + $(this).outerWidth());
console.log('from 0p far y: ', $(this).attr("id"), offset.top + $(this).outerHeight());
hitElements.push($(this));
}
});
return hitElements;
}
答案 0 :(得分:2)
你必须使用线性代数。
我修改了你的小提琴 - http://jsfiddle.net/pcdk2s0g/
var getHitElements = function (e) {
var mx = e.pageX;
var my = e.pageY;
var hitElements = [];
$(':visible').each(function () {
//Parse CSS matrix
var matrix = [];
var matrixVal = $(this).css('transform');
if(matrixVal != "none"){
var matrixParsed = matrixVal.substr(7, matrixVal.length - 8).split(',');
for(var i in matrixParsed) matrix[i] = parseFloat(matrixParsed[i]);
} else {
matrix = [1, 0, 0, 1, 0, 0];
}
var hW = this.offsetWidth / 2; //Half of width
var hH = this.offsetHeight / 2; //Half of height
var o = { x: this.offsetLeft + hW, y: this.offsetTop + this.offsetHeight / 2} //Transform origin
//Define shape points and transform by matrix
var p1 = {
x: o.x + matrix[0] * -hW + matrix[2] * -hH + matrix[4],
y: o.y + matrix[1] * -hW + matrix[3] * -hH + matrix[5]
}; //Left top
var p2 = {
x: o.x + matrix[0] * +hW + matrix[2] * -hH + matrix[4],
y: o.y + matrix[1] * +hW + matrix[3] * -hH + matrix[5]
}; //Right top
var p3 = {
x: o.x + matrix[0] * +hW + matrix[2] * +hH + matrix[4],
y: o.y + matrix[1] * +hW + matrix[3] * +hH + matrix[5]
}; //Right bottom
var p4 = {
x: o.x + matrix[0] * -hW + matrix[2] * +hH + matrix[4],
y: o.y + matrix[1] * -hW + matrix[3] * +hH + matrix[5]
}; //Left bottom
//Calculate edge normal vectors & C vars
var v1 = { x: -(p2.y - p1.y), y: (p2.x - p1.x) }; //Top
var v2 = { x: -(p3.y - p2.y), y: (p3.x - p2.x) }; //Right
var v3 = { x: -(p4.y - p3.y), y: (p4.x - p3.x) }; //Bottom
var v4 = { x: -(p1.y - p4.y), y: (p1.x - p4.x) }; //Left
var c1 = -(v1.x * p1.x + v1.y * p1.y);
var c2 = -(v2.x * p2.x + v2.y * p2.y);
var c3 = -(v3.x * p3.x + v3.y * p3.y);
var c4 = -(v4.x * p4.x + v4.y * p4.y);
//Check cursor distance from edge using general line quation: ax + by + c = 0
var isInner = function(v, c, x, y){
return (v.x * x + v.y * y + c) / Math.sqrt( v.x*v.x + v.y*v.y ) > 0;
}
//Check if mouse point is in shape coords using general line equation
if(isInner(v1, c1, mx, my) && isInner(v2, c2, mx, my) && isInner(v3, c3, mx, my) && isInner(v4, c4, mx, my))
hitElements.push($(this));
});
return hitElements;
}
它使用CSS转换属性,由浏览器转换为CSS矩阵。
代码解析CSS矩阵,计算新的边缘点并检查光标是否在翻译元素中。
适用于任何角度或CSS转换。
代码可以改进,例如你也可以解析CSS transform-origin属性。
答案 1 :(得分:1)
如果您只是以90°的步幅旋转,那么您可以使用element.getBoundingClientRect()
或此问题的代码:How to get the position of element transformed with css rotate
如果以任意角度旋转,则需要计算矩形的角点以获得四边形多边形。然后,您可以使用此答案:JS- Check if Point Inside A Polygon?