feat:init
This commit is contained in:
1 parent
53d0eeac6b
commit
ae0c050010
494 files changed
+17701
-2318
No files matched your search
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* 计算阻止点击的区域(分成多个矩形块)
|
||||
* 用于 Spotlight 和 Overlay 组件
|
||||
*/
|
||||
export interface BlockingDiv {
|
||||
top: number;
|
||||
left: number;
|
||||
width: string | number;
|
||||
height: string | number;
|
||||
}
|
||||
|
||||
export interface Rect {
|
||||
top: number;
|
||||
left: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据高亮区域计算需要阻止点击的 div 块
|
||||
* @param rects 高亮区域的矩形列表(视口坐标)
|
||||
* @param viewportWidth 视口宽度
|
||||
* @param viewportHeight 视口高度
|
||||
* @returns 阻止点击的 div 块列表
|
||||
*/
|
||||
export function getBlockingDivs(
|
||||
rects: Rect[],
|
||||
viewportWidth: number,
|
||||
viewportHeight: number
|
||||
): BlockingDiv[] {
|
||||
if (rects.length === 0) return [];
|
||||
|
||||
const blocks: BlockingDiv[] = [];
|
||||
|
||||
// 找出所有孔的边界
|
||||
const minTop = Math.min(...rects.map((r) => r.top));
|
||||
const maxBottom = Math.max(...rects.map((r) => r.top + r.height));
|
||||
const minLeft = Math.min(...rects.map((r) => r.left));
|
||||
const maxRight = Math.max(...rects.map((r) => r.left + r.width));
|
||||
|
||||
// 顶部大块
|
||||
if (minTop > 0) {
|
||||
blocks.push({
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: minTop,
|
||||
});
|
||||
}
|
||||
|
||||
// 底部大块
|
||||
if (maxBottom < viewportHeight) {
|
||||
blocks.push({
|
||||
top: maxBottom,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: viewportHeight - maxBottom,
|
||||
});
|
||||
}
|
||||
|
||||
// 左侧大块(中间部分)
|
||||
if (minLeft > 0) {
|
||||
blocks.push({
|
||||
top: minTop,
|
||||
left: 0,
|
||||
width: minLeft,
|
||||
height: maxBottom - minTop,
|
||||
});
|
||||
}
|
||||
|
||||
// 右侧大块(中间部分)
|
||||
if (maxRight < viewportWidth) {
|
||||
blocks.push({
|
||||
top: minTop,
|
||||
left: maxRight,
|
||||
width: viewportWidth - maxRight,
|
||||
height: maxBottom - minTop,
|
||||
});
|
||||
}
|
||||
|
||||
// 对于多个孔的情况,填充孔之间的间隙
|
||||
if (rects.length > 1) {
|
||||
// 按位置排序
|
||||
const sortedByTop = [...rects].sort((a, b) => a.top - b.top);
|
||||
const sortedByLeft = [...rects].sort((a, b) => a.left - b.left);
|
||||
|
||||
// 填充垂直间隙
|
||||
for (let i = 0; i < sortedByTop.length - 1; i++) {
|
||||
const current = sortedByTop[i]!;
|
||||
const next = sortedByTop[i + 1]!;
|
||||
const gap = next.top - (current.top + current.height);
|
||||
|
||||
if (gap > 0) {
|
||||
blocks.push({
|
||||
top: current.top + current.height,
|
||||
left: Math.max(current.left, next.left),
|
||||
width: Math.min(current.width, next.width),
|
||||
height: gap,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 填充水平间隙
|
||||
for (let i = 0; i < sortedByLeft.length - 1; i++) {
|
||||
const current = sortedByLeft[i]!;
|
||||
const next = sortedByLeft[i + 1]!;
|
||||
const gap = next.left - (current.left + current.width);
|
||||
|
||||
if (gap > 0) {
|
||||
blocks.push({
|
||||
top: Math.max(current.top, next.top),
|
||||
left: current.left + current.width,
|
||||
width: gap,
|
||||
height: Math.min(current.height, next.height),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
Reference in new issue
Block a user