fix(canvas): 画布批量生成 - 修复节点丢失、资源引用及刷新状态不一致
This commit is contained in:
1 parent
dc1ad68015
commit
6f45240599
26 files changed
+533
-179
No files matched your search
@@ -7,6 +7,7 @@ import { canvasNodeRenderBudget, canvasNodeRenderPadding, CANVAS_MAX_RENDERED_CO
|
||||
import { buildCanvasNodeMentionReferenceMap, buildCanvasResourceReferences, buildToolMentionReference, parseToolMentionTokens } from "@/lib/canvas/canvas-resource-references";
|
||||
import { buildSkillMentionReferences } from "@/lib/canvas/canvas-skill-mentions";
|
||||
import { buildCanvasSpatialIndex, canvasNodeBounds, type CanvasSpatialIndex, type CanvasSpatialIndexEntry } from "@/lib/canvas/canvas-spatial-index";
|
||||
import { selectCanvasVisibleNodes } from "@/lib/canvas/canvas-node-visibility";
|
||||
import type { Skill } from "@/services/api/skills";
|
||||
import type { Asset, ImageAsset } from "@/stores/use-asset-store";
|
||||
import type { DirectorScene } from "@/types/director";
|
||||
@@ -154,6 +155,7 @@ export function useCanvasRenderModel({
|
||||
const viewWidth = viewportSize.width / viewport.k;
|
||||
const viewHeight = viewportSize.height / viewport.k;
|
||||
return {
|
||||
view: { left: viewLeft, top: viewTop, right: viewLeft + viewWidth, bottom: viewTop + viewHeight },
|
||||
enter: { left: viewLeft - enterPadding, top: viewTop - enterPadding, right: viewLeft + viewWidth + enterPadding, bottom: viewTop + viewHeight + enterPadding },
|
||||
retain: { left: viewLeft - retainPadding, top: viewTop - retainPadding, right: viewLeft + viewWidth + retainPadding, bottom: viewTop + viewHeight + retainPadding },
|
||||
};
|
||||
@@ -177,30 +179,19 @@ export function useCanvasRenderModel({
|
||||
const visibleNodes = useMemo(() => {
|
||||
const frames: CanvasNodeData[] = [];
|
||||
const regular: CanvasNodeData[] = [];
|
||||
const renderedNodeIds = renderedNodeIdsRef.current;
|
||||
const renderBudget = canvasNodeRenderBudget(viewport.k);
|
||||
const forcedNodeIds = new Set([...selectedNodeIds, ...(dragPreview?.nodeIds || [])].slice(0, renderBudget));
|
||||
const candidates = nodeSpatialIndex
|
||||
.query(renderBounds.retain, renderBudget + forcedNodeIds.size)
|
||||
.map((nodeId) => nodeById.get(nodeId))
|
||||
.filter((node): node is CanvasNodeData => Boolean(node));
|
||||
const candidateIds = new Set(candidates.map((node) => node.id));
|
||||
for (const nodeId of forcedNodeIds) {
|
||||
if (candidateIds.has(nodeId)) continue;
|
||||
const node = nodeById.get(nodeId);
|
||||
if (node) candidates.push(node);
|
||||
}
|
||||
const prioritized = candidates.filter((node) => forcedNodeIds.has(node.id));
|
||||
const remaining = candidates.filter((node) => !forcedNodeIds.has(node.id)).slice(0, Math.max(0, renderBudget - prioritized.length));
|
||||
[...prioritized, ...remaining].forEach((node) => {
|
||||
if (renderHiddenNodeIds.has(node.id)) return;
|
||||
const retained = forcedNodeIds.has(node.id) || renderedNodeIds.has(node.id);
|
||||
const insideEnterBounds = node.position.x + node.width > renderBounds.enter.left && node.position.x < renderBounds.enter.right && node.position.y + node.height > renderBounds.enter.top && node.position.y < renderBounds.enter.bottom;
|
||||
if (!retained && !insideEnterBounds) return;
|
||||
selectCanvasVisibleNodes({
|
||||
index: nodeSpatialIndex,
|
||||
nodeById,
|
||||
...renderBounds,
|
||||
hiddenIds: renderHiddenNodeIds,
|
||||
retainedIds: renderedNodeIdsRef.current,
|
||||
forcedIds: new Set([...selectedNodeIds, ...(dragPreview?.nodeIds || [])]),
|
||||
budget: canvasNodeRenderBudget(viewport.k),
|
||||
}).forEach((node) => {
|
||||
(isFrameNode(node) ? frames : regular).push(node);
|
||||
});
|
||||
return [...frames, ...regular];
|
||||
}, [dragPreview, nodeById, nodeSpatialIndex, renderBounds, renderHiddenNodeIds, selectedNodeIds]);
|
||||
}, [dragPreview, nodeById, nodeSpatialIndex, renderBounds, renderHiddenNodeIds, selectedNodeIds, viewport.k]);
|
||||
useEffect(() => {
|
||||
renderedNodeIdsRef.current = new Set(visibleNodes.map((node) => node.id));
|
||||
}, [visibleNodes]);
|
||||
|
||||
Reference in new issue
Block a user