如何检测圆角Div与方形Div是否发生重叠?
解决方案
要实现圆形(带round类)与方形(无round类)元素的重叠检测,需要针对不同元素组合(圆-圆、圆-方、方-方)实现对应的碰撞逻辑,以下是修改后的完整代码:
修改后的JavaScript代码
let $label = $('.overlap-label span'); // 判断两个矩形是否重叠(方形-方形场景) const rectanglesOverlap = (rect1, rect2) => { return !(rect1.right < rect2.left || rect1.left > rect2.right || rect1.bottom < rect2.top || rect1.top > rect2.bottom); }; // 判断圆是否与方形重叠(圆-方场景) const circleRectangleOverlap = (circle, rect) => { // 计算圆心到方形的最近点坐标 const closestX = Math.max(rect.left, Math.min(circle.x, rect.right)); const closestY = Math.max(rect.top, Math.min(circle.y, rect.bottom)); // 计算圆心到该点的距离 const distance = Math.hypot(circle.x - closestX, circle.y - closestY); // 距离小于等于圆半径则重叠,或者圆完全在方形内、方形完全在圆内 return distance <= circle.rad || rectanglesOverlap(circle.rect, rect); }; // 通用重叠检测函数,适配所有元素组合 const hasOverlap = (elem1, elem2) => { if (elem1.isRound && elem2.isRound) { // 圆-圆检测 return Math.hypot(elem1.x - elem2.x, elem1.y - elem2.y) <= elem1.rad + elem2.rad; } else if (elem1.isRound) { // 圆-方检测(elem1是圆,elem2是方) return circleRectangleOverlap(elem1, elem2.rect); } else if (elem2.isRound) { // 方-圆检测(elem2是圆,elem1是方) return circleRectangleOverlap(elem2, elem1.rect); } else { // 方-方检测 return rectanglesOverlap(elem1.rect, elem2.rect); } }; // 获取元素的坐标、形状类型等信息 const getElementInfo = (className) => { const elem = document.querySelector(className); const rect = elem.getBoundingClientRect(); const isRound = elem.classList.contains('round'); const rad = elem.offsetHeight / 2; return { x: rect.left + rad, // 圆心/矩形中心x坐标 y: rect.top + rad, // 圆心/矩形中心y坐标 rad: rad, // 圆的半径 isRound: isRound, // 是否为圆形 rect: { // 元素的矩形边界 top: rect.top, bottom: rect.bottom, left: rect.left, right: rect.right } }; }; // 检测重叠并更新标签文字 const checkForOverlap = () => { const smallElem = getElementInfo(".circle.small"); const largeElem = getElementInfo(".circle.large"); $label.text(hasOverlap(smallElem, largeElem)); }; // 初始化拖拽事件 $('.parent').draggable().on('drag', checkForOverlap);
修改后的CSS代码(保留原样式)
.circle { width: var(--square); height: var(--square); background: var(--bg); display: inline-block; } .round { border-radius: 50%; } .parent { display: inline-block; } .small { --square: 50px; --bg: red; } .large { --square: 100px; --bg: green; }
修改后的HTML代码(更新标签文字适配全场景)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/themes/base/jquery-ui.min.css" /> <div class="overlap-label">元素是否重叠? <span>false</span></div> <div class="parent"> <div class="circle small round"></div> </div> <div class="parent"> <div class="circle large round"></div> </div>
逻辑说明
- 方形-方形检测:通过判断两个矩形的边界是否存在分离来确定是否重叠。
- 圆-圆检测:保留原有的圆心距离判断逻辑。
- 圆-方形检测:计算圆心到方形的最近点距离,若距离小于等于圆半径则判定重叠;同时处理圆完全在方形内或方形完全在圆内的特殊情况。
内容的提问来源于stack exchange,提问作者Ghayas Ud Din
相关产品推荐
相关产品推荐

