perf(canvas): 画布渲染 - 增加节点渲染预算与性能模式控制
This commit is contained in:
@@ -1,50 +0,0 @@
|
||||
import { CanvasNodeType, type CanvasMediaPerformanceMode, type CanvasNodeData } from "@/types/canvas";
|
||||
|
||||
const STORAGE_KEY = "canvas-media-performance-mode";
|
||||
|
||||
// 屏外预加载的软预算;屏内节点不可因预算而消失,媒体仍由节点按需加载。
|
||||
export const CANVAS_MAX_RENDERED_NODES = 720;
|
||||
export const CANVAS_MAX_RENDERED_CONNECTIONS = 5000;
|
||||
|
||||
export function readCanvasMediaPerformanceMode(): CanvasMediaPerformanceMode {
|
||||
try {
|
||||
const stored = window.localStorage.getItem(STORAGE_KEY);
|
||||
return stored === "quality" || stored === "performance" ? stored : "auto";
|
||||
} catch {
|
||||
return "auto";
|
||||
}
|
||||
}
|
||||
|
||||
export function persistCanvasMediaPerformanceMode(mode: CanvasMediaPerformanceMode) {
|
||||
try {
|
||||
window.localStorage.setItem(STORAGE_KEY, mode);
|
||||
} catch {
|
||||
// 浏览器禁用本地存储时保留当前会话内的选择。
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldReduceCanvasMediaEffects(mode: CanvasMediaPerformanceMode, nodes: CanvasNodeData[]) {
|
||||
if (mode === "performance") return true;
|
||||
if (mode === "quality") return false;
|
||||
const mediaCount = nodes.filter((node) => node.type === CanvasNodeType.Image || node.type === CanvasNodeType.Video || node.type === CanvasNodeType.Audio).length;
|
||||
return nodes.length >= 80 || mediaCount >= 32;
|
||||
}
|
||||
|
||||
export function canvasNodeRenderPadding(reduceMediaEffects: boolean, previouslyRendered: boolean) {
|
||||
if (previouslyRendered) return reduceMediaEffects ? 640 : 384;
|
||||
return reduceMediaEffects ? 128 : 192;
|
||||
}
|
||||
|
||||
export function canvasNodeRenderBudget(scale: number) {
|
||||
if (scale < 0.14) return 280;
|
||||
if (scale < 0.28) return 420;
|
||||
return CANVAS_MAX_RENDERED_NODES;
|
||||
}
|
||||
|
||||
export function resolveActiveCanvasMediaNodeId(selectedNodeIds: ReadonlySet<string>, nodeById: ReadonlyMap<string, CanvasNodeData>) {
|
||||
if (selectedNodeIds.size !== 1) return null;
|
||||
const nodeId = selectedNodeIds.values().next().value;
|
||||
if (!nodeId) return null;
|
||||
const type = nodeById.get(nodeId)?.type;
|
||||
return type === CanvasNodeType.Video || type === CanvasNodeType.Audio ? nodeId : null;
|
||||
}
|
||||
12
web/src/lib/canvas/canvas-render-budget.ts
Normal file
12
web/src/lib/canvas/canvas-render-budget.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export const CANVAS_MAX_RENDERED_NODES = 720;
|
||||
export const CANVAS_MAX_RENDERED_CONNECTIONS = 5000;
|
||||
|
||||
export function canvasNodeRenderPadding(previouslyRendered: boolean) {
|
||||
return previouslyRendered ? 384 : 192;
|
||||
}
|
||||
|
||||
export function canvasNodeRenderBudget(scale: number) {
|
||||
if (scale < 0.14) return 280;
|
||||
if (scale < 0.28) return 420;
|
||||
return CANVAS_MAX_RENDERED_NODES;
|
||||
}
|
||||
Reference in New Issue
Block a user