feat:
1. local msg/file share by webrtc fix: 1. meta clean goroutine walk error 2. clean interval to args(--clean)
This commit is contained in:
75
frontend/src/page/local/component/bubble-layout.ts
Normal file
75
frontend/src/page/local/component/bubble-layout.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import {Bubble, Client} from "./types.ts";
|
||||
|
||||
// 生成随机颜色
|
||||
export const generateColor = () => {
|
||||
const hue = Math.random() * 360;
|
||||
return `hsla(${hue},
|
||||
${Math.random() * 30 + 40}%,
|
||||
${Math.random() * 10 + 75}%, 0.9)`;
|
||||
};
|
||||
|
||||
// 防碰撞位置生成
|
||||
export const generateBubbles = (clients: Client[], currentUserId: string): Bubble[] => {
|
||||
if (!clients) return [];
|
||||
|
||||
const BUBBLE_SIZE = 100;
|
||||
const centerX = window.innerWidth / 2;
|
||||
const centerY = window.innerHeight / 2;
|
||||
|
||||
const bubbles: Bubble[] = [];
|
||||
let currentRadius = 0;
|
||||
let angleStep = (2 * Math.PI) / 6; // 初始6个位置
|
||||
|
||||
for (let index = 0; index < clients.length; index++) {
|
||||
let attempt = 0;
|
||||
let validPosition = false;
|
||||
|
||||
if (clients[index].id === currentUserId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (!validPosition && attempt < 100) {
|
||||
// 螺旋布局算法
|
||||
const angle = angleStep * (index + attempt);
|
||||
const radius = currentRadius + (attempt * BUBBLE_SIZE * 0.8);
|
||||
|
||||
// 极坐标转笛卡尔坐标
|
||||
const x = centerX + radius * Math.cos(angle);
|
||||
const y = centerY + radius * Math.sin(angle);
|
||||
|
||||
// 边界检测
|
||||
const inBounds = x >= 0 && x <= window.innerWidth - BUBBLE_SIZE &&
|
||||
y >= 0 && y <= window.innerHeight - BUBBLE_SIZE;
|
||||
|
||||
// 碰撞检测
|
||||
const collision = bubbles.some(pos => {
|
||||
const distance = Math.sqrt(
|
||||
Math.pow(pos.x - x, 2) +
|
||||
Math.pow(pos.y - y, 2)
|
||||
);
|
||||
return distance < BUBBLE_SIZE * 1.5;
|
||||
});
|
||||
|
||||
if (inBounds && !collision) {
|
||||
bubbles.push({
|
||||
id: clients[index].id,
|
||||
name: clients[index].name,
|
||||
x: x,
|
||||
y: y,
|
||||
color: generateColor(),
|
||||
radius: 0,
|
||||
angle: 0
|
||||
});
|
||||
|
||||
// 动态调整布局参数
|
||||
currentRadius = Math.max(currentRadius, radius);
|
||||
angleStep = (2 * Math.PI) / Math.max(6, bubbles.length * 0.7);
|
||||
validPosition = true;
|
||||
}
|
||||
|
||||
attempt++;
|
||||
}
|
||||
}
|
||||
|
||||
return bubbles;
|
||||
};
|
||||
Reference in New Issue
Block a user