perf: trim editor render selection lookups

This commit is contained in:
OpenClaw Agent
2026-07-09 21:02:30 +00:00
parent e87b5d8d8f
commit 264fdcf7cd

View File

@@ -5972,6 +5972,7 @@ class TimelineEditor {
const width = this.canvas.offsetWidth || this._lastWidth; const width = this.canvas.offsetWidth || this._lastWidth;
const height = this.canvasHeight; const height = this.canvasHeight;
const totalFrames = this.getVisualDurationFrames(); const totalFrames = this.getVisualDurationFrames();
const selectedIdSet = new Set(this.selectedSegmentIds || []);
if (!width || width <= 0) return; if (!width || width <= 0) return;
@@ -5999,8 +6000,8 @@ class TimelineEditor {
} }
if (this._isDragging && this._dragTargetId) { if (this._isDragging && this._dragTargetId) {
const dragSeg = this.timeline.segments.find(s => s.id === this._dragTargetId) || const dragSeg = findSegmentById(this.timeline.segments, this._dragTargetId) ||
(this.timeline.motionSegments && this.timeline.motionSegments.find(s => s.id === this._dragTargetId)); findSegmentById(this.timeline.motionSegments, this._dragTargetId);
if (dragSeg && (dragSeg.type === "video" || dragSeg.type === "motion_video")) { if (dragSeg && (dragSeg.type === "video" || dragSeg.type === "motion_video")) {
this._ensureVideoEl(dragSeg); this._ensureVideoEl(dragSeg);
} }
@@ -6052,20 +6053,20 @@ class TimelineEditor {
} }
const sortedSegments = [...renderSegments].sort((a, b) => { const sortedSegments = [...renderSegments].sort((a, b) => {
const aSel = this.selectedSegmentIds.includes(a.id) ? 1 : 0; const aSel = selectedIdSet.has(a.id) ? 1 : 0;
const bSel = this.selectedSegmentIds.includes(b.id) ? 1 : 0; const bSel = selectedIdSet.has(b.id) ? 1 : 0;
return aSel - bSel; return aSel - bSel;
}); });
const sortedMotionSegments = [...renderMotionSegments].sort((a, b) => { const sortedMotionSegments = [...renderMotionSegments].sort((a, b) => {
const aSel = this.selectedSegmentIds.includes(a.id) ? 1 : 0; const aSel = selectedIdSet.has(a.id) ? 1 : 0;
const bSel = this.selectedSegmentIds.includes(b.id) ? 1 : 0; const bSel = selectedIdSet.has(b.id) ? 1 : 0;
return aSel - bSel; return aSel - bSel;
}); });
const sortedAudioSegments = [...renderAudioSegments].sort((a, b) => { const sortedAudioSegments = [...renderAudioSegments].sort((a, b) => {
const aSel = this.selectedSegmentIds.includes(a.id) ? 1 : 0; const aSel = selectedIdSet.has(a.id) ? 1 : 0;
const bSel = this.selectedSegmentIds.includes(b.id) ? 1 : 0; const bSel = selectedIdSet.has(b.id) ? 1 : 0;
return aSel - bSel; return aSel - bSel;
}); });
@@ -6417,7 +6418,7 @@ class TimelineEditor {
const rawEndX = ((seg.start + seg.length) / totalFrames) * width; const rawEndX = ((seg.start + seg.length) / totalFrames) * width;
const startX = Math.floor(rawStartX); const startX = Math.floor(rawStartX);
const pxWidth = Math.max(1, Math.floor(rawEndX) - startX); const pxWidth = Math.max(1, Math.floor(rawEndX) - startX);
const isSelected = this.selectedSegmentIds.includes(seg.id); const isSelected = selectedIdSet.has(seg.id);
const originalSeg = this.timeline.segments.find(s => s.id === seg.id); const originalSeg = this.timeline.segments.find(s => s.id === seg.id);
const imgObj = originalSeg ? originalSeg.imgObj : seg.imgObj; const imgObj = originalSeg ? originalSeg.imgObj : seg.imgObj;
@@ -6753,7 +6754,7 @@ class TimelineEditor {
const startX = Math.floor((seg.start / totalFrames) * width); const startX = Math.floor((seg.start / totalFrames) * width);
const rawEndX = ((seg.start + seg.length) / totalFrames) * width; const rawEndX = ((seg.start + seg.length) / totalFrames) * width;
const pxWidth = Math.max(1, Math.floor(rawEndX) - startX); const pxWidth = Math.max(1, Math.floor(rawEndX) - startX);
const isSelected = this.selectedSegmentIds.includes(seg.id); const isSelected = selectedIdSet.has(seg.id);
const trackY = RULER_HEIGHT + this.blockHeight + this.audioTrackHeight; const trackY = RULER_HEIGHT + this.blockHeight + this.audioTrackHeight;
if ((this._isDragging && this.selectionType === "motion" && seg.id === this._dragTargetId) || (this._ghostSegmentId && seg.id === this._ghostSegmentId)) { if ((this._isDragging && this.selectionType === "motion" && seg.id === this._dragTargetId) || (this._ghostSegmentId && seg.id === this._ghostSegmentId)) {
@@ -6779,7 +6780,7 @@ class TimelineEditor {
this.ctx.fillStyle = "#000"; this.ctx.fillStyle = "#000";
this.ctx.fillRect(startX, trackY + 1, pxWidth, this.motionTrackHeight - 2); this.ctx.fillRect(startX, trackY + 1, pxWidth, this.motionTrackHeight - 2);
const originalSeg = this.timeline.motionSegments.find(s => s.id === seg.id); const originalSeg = findSegmentById(this.timeline.motionSegments, seg.id);
const imgObj = originalSeg ? originalSeg.imgObj : seg.imgObj; const imgObj = originalSeg ? originalSeg.imgObj : seg.imgObj;
const videoEl = originalSeg ? originalSeg.videoEl : seg.videoEl; const videoEl = originalSeg ? originalSeg.videoEl : seg.videoEl;
@@ -6974,7 +6975,7 @@ class TimelineEditor {
const rawEndX = ((seg.start + seg.length) / totalFrames) * width; const rawEndX = ((seg.start + seg.length) / totalFrames) * width;
const startX = Math.floor(rawStartX); const startX = Math.floor(rawStartX);
const pxWidth = Math.max(1, Math.floor(rawEndX) - startX); const pxWidth = Math.max(1, Math.floor(rawEndX) - startX);
const isSelected = this.selectedSegmentIds.includes(seg.id); const isSelected = selectedIdSet.has(seg.id);
const trackY = RULER_HEIGHT + this.blockHeight; const trackY = RULER_HEIGHT + this.blockHeight;
if ((this._isDragging && this.selectionType === "audio" && seg.id === this._dragTargetId) || (this._ghostSegmentId && seg.id === this._ghostSegmentId)) { if ((this._isDragging && this.selectionType === "audio" && seg.id === this._dragTargetId) || (this._ghostSegmentId && seg.id === this._ghostSegmentId)) {
@@ -9841,13 +9842,16 @@ class TimelineEditor {
let trackType = ""; let trackType = "";
if (isMotionTrack) { if (isMotionTrack) {
clickedSeg = this.timeline.motionSegments.find(s => cursor >= s.start && cursor <= s.start + s.length); clickedSeg = findActiveSegmentAtFrame(this.timeline.motionSegments, cursor, "motion_video");
trackType = "motion"; trackType = "motion";
} else if (isAudioTrack) { } else if (isAudioTrack) {
clickedSeg = this.timeline.audioSegments.find(s => cursor >= s.start && cursor <= s.start + s.length); clickedSeg = findActiveSegmentAtFrame(this.timeline.audioSegments, cursor, "audio");
trackType = "audio"; trackType = "audio";
} else if (isImageTrack) { } else if (isImageTrack) {
clickedSeg = this.timeline.segments.find(s => cursor >= s.start && cursor <= s.start + s.length); clickedSeg = findActiveSegmentAtFrame(this.timeline.segments, cursor, "image")
|| findActiveSegmentAtFrame(this.timeline.segments, cursor, "video")
|| findActiveSegmentAtFrame(this.timeline.segments, cursor, "text")
|| findActiveSegmentAtFrame(this.timeline.segments, cursor, "ghost");
trackType = clickedSeg ? clickedSeg.type : ""; trackType = clickedSeg ? clickedSeg.type : "";
} }
@@ -10105,7 +10109,7 @@ class TimelineEditor {
seg.prompt = text; seg.prompt = text;
this.commitChanges(); this.commitChanges();
this.render(); this.render();
if (this.selectedIndex === this.timeline.segments.findIndex(s => s.id === seg.id)) { if (this.selectedIndex === findSegmentIndexById(this.timeline.segments, seg.id)) {
this.updateUIFromSelection(); this.updateUIFromSelection();
} }
} }
@@ -10204,7 +10208,7 @@ class TimelineEditor {
seg.imgObj = img; seg.imgObj = img;
this.commitChanges(); this.commitChanges();
this.render(); this.render();
if (this.selectedIndex === this.timeline.segments.findIndex(s => s.id === seg.id)) { if (this.selectedIndex === findSegmentIndexById(this.timeline.segments, seg.id)) {
this.updateUIFromSelection(); this.updateUIFromSelection();
} }
}; };
@@ -10249,7 +10253,7 @@ class TimelineEditor {
seg.imgObj = img; seg.imgObj = img;
this.commitChanges(); this.commitChanges();
this.render(); this.render();
if (this.selectedIndex === this.timeline.segments.findIndex(s => s.id === seg.id)) { if (this.selectedIndex === findSegmentIndexById(this.timeline.segments, seg.id)) {
this.updateUIFromSelection(); this.updateUIFromSelection();
} }
}; };