feat:init

This commit is contained in:
zhongyidian committed 2025-12-29 19:19:10 +08:00
1 parent 53d0eeac6b
commit ae0c050010
494 files changed
+17701 -2318

No files matched your search

+121
View File
@@ -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;
}