add offset to multi avatar layer

This commit is contained in:
bridge
2025-11-24 23:20:39 +08:00
parent 9295d71a90
commit 991f9908d6
3 changed files with 81 additions and 7 deletions

View File

@@ -0,0 +1,59 @@
export interface Point {
x: number
y: number
}
interface PositionedObject {
id: string
x: number
y: number
}
/**
* 计算角色在格子内的视觉偏移量,避免重叠
* @param items 包含坐标的对象列表
* @param radius 偏移半径相对于格子大小的比例0.25 表示 1/4 格子宽)
*/
export function calculateVisualOffsets<T extends PositionedObject>(
items: T[],
radius: number = 0.25
): Map<string, Point> {
const groups = new Map<string, T[]>()
const offsets = new Map<string, Point>()
// 1. 按坐标分组
for (const item of items) {
const key = `${item.x},${item.y}`
if (!groups.has(key)) {
groups.set(key, [])
}
groups.get(key)!.push(item)
}
// 2. 计算每组的偏移
for (const group of groups.values()) {
const count = group.length
// 只有一个人时,不需要偏移,居中显示
if (count <= 1) {
offsets.set(group[0].id, { x: 0, y: 0 })
continue
}
// 多人时,按圆形分布
// 无论多少人,都均匀分布在圆周上
// 起始角度 -PI/2 (即正上方),让排列更符合直觉
const angleStep = (Math.PI * 2) / count
group.forEach((item, index) => {
const angle = index * angleStep - Math.PI / 2
offsets.set(item.id, {
x: Math.cos(angle) * radius,
y: Math.sin(angle) * radius
})
})
}
return offsets
}