Files
shanghai-residences/src/components/spotlight/utils.ts
T
zhongyidian 76c67b492e feat: 更新 ESLint 和 Prettier 配置,增强代码质量管理
- 在 .gitignore 中添加 public/audio/* 以忽略音频文件。
- 更新 bun.lock,添加 eslint-config-prettier 和 eslint-plugin-prettier 依赖,确保 ESLint 与 Prettier 的兼容性。
- 修改 eslint.config.ts,整合 Prettier 规则,优化代码风格一致性。
- 在 package.json 中添加 lint:fix 和 format 脚本,简化代码格式化和修复流程。
- 更新 tailwind.config.ts 和其他组件文件,统一代码风格,提升可读性。
2026-03-05 13:50:47 +08:00

122 lines
2.9 KiB
TypeScript

/**
* 计算阻止点击的区域(分成多个矩形块)
* 用于 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
}