diff --git a/ui/static/graph.html b/ui/static/graph.html index a160d7c..ccc9a3c 100644 --- a/ui/static/graph.html +++ b/ui/static/graph.html @@ -577,11 +577,15 @@ function init() { // 创建图可视化 function createGraphVisualization() { - // 清除旧的对象 + // 清除旧的对象(包括边粒子) nodeMeshes.forEach(mesh => scene.remove(mesh)); edgeLines.forEach(line => scene.remove(line)); + Object.keys(edgeParticles).forEach(key => { + scene.remove(edgeParticles[key].mesh); + }); nodeMeshes = []; edgeLines = []; + edgeParticles = {}; if (nodes.length === 0) return; @@ -971,8 +975,11 @@ function init() { let _consumedHighlightIds = new Set(); // 平滑重新定位剩余的节点 - function smoothReposition() { + let _smoothAnimCount = 0; + +function smoothReposition() { if (nodeMeshes.length < 2) return; + _smoothAnimCount = nodeMeshes.length; // 从当前节点位置计算新布局 const currentPositions = {}; @@ -1047,22 +1054,26 @@ function init() { // ease-out cubic const ease = 1 - Math.pow(1 - t, 3); m.position.lerpVectors(startPos, endPos, ease); + + if (t >= 1) { + _smoothAnimCount--; + // 所有动画完成后再重建粒子 + if (_smoothAnimCount <= 0) { + Object.keys(edgeParticles).forEach(key => { + scene.remove(edgeParticles[key].mesh); + }); + edgeParticles = {}; + edges.forEach(e => createEdgeParticle(e)); + } + } + if (t < 1) requestAnimationFrame(lerpPosition); } lerpPosition(); }); - // 更新边的几何 - edgeLines.forEach(line => { - const e = line.userData.edgeData; - const p1 = currentPositions[e.source]; - const p2 = currentPositions[e.target]; - if (!p1 || !p2) return; - line.geometry.setFromPoints([ - new THREE.Vector3(p1.x, p1.y, p1.z), - new THREE.Vector3(p2.x, p2.y, p2.z) - ]); - }); + // 不在此处更新边的几何——让粒子在动画完成后重建 + // 边线在下一轮 loadGraphData 时会自动更新 // 更新相机 fitCameraToGraph();