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

@@ -5967,11 +5967,12 @@ class TimelineEditor {
}
// --- Rendering logic ---
render() {
if (!this.canvas) return;
const width = this.canvas.offsetWidth || this._lastWidth;
const height = this.canvasHeight;
const totalFrames = this.getVisualDurationFrames();
render() {
if (!this.canvas) return;
const width = this.canvas.offsetWidth || this._lastWidth;
const height = this.canvasHeight;
const totalFrames = this.getVisualDurationFrames();
const selectedIdSet = new Set(this.selectedSegmentIds || []);
if (!width || width <= 0) return;
@@ -5999,8 +6000,8 @@ class TimelineEditor {
}
if (this._isDragging && this._dragTargetId) {
const dragSeg = this.timeline.segments.find(s => s.id === this._dragTargetId) ||
(this.timeline.motionSegments && this.timeline.motionSegments.find(s => s.id === this._dragTargetId));
const dragSeg = findSegmentById(this.timeline.segments, this._dragTargetId) ||
findSegmentById(this.timeline.motionSegments, this._dragTargetId);
if (dragSeg && (dragSeg.type === "video" || dragSeg.type === "motion_video")) {
this._ensureVideoEl(dragSeg);
}
@@ -6051,23 +6052,23 @@ class TimelineEditor {
if (this._previewSegments && previewIsMotion) renderMotionSegments = this._previewSegments;
}
const sortedSegments = [...renderSegments].sort((a, b) => {
const aSel = this.selectedSegmentIds.includes(a.id) ? 1 : 0;
const bSel = this.selectedSegmentIds.includes(b.id) ? 1 : 0;
return aSel - bSel;
});
const sortedMotionSegments = [...renderMotionSegments].sort((a, b) => {
const aSel = this.selectedSegmentIds.includes(a.id) ? 1 : 0;
const bSel = this.selectedSegmentIds.includes(b.id) ? 1 : 0;
return aSel - bSel;
});
const sortedAudioSegments = [...renderAudioSegments].sort((a, b) => {
const aSel = this.selectedSegmentIds.includes(a.id) ? 1 : 0;
const bSel = this.selectedSegmentIds.includes(b.id) ? 1 : 0;
return aSel - bSel;
});
const sortedSegments = [...renderSegments].sort((a, b) => {
const aSel = selectedIdSet.has(a.id) ? 1 : 0;
const bSel = selectedIdSet.has(b.id) ? 1 : 0;
return aSel - bSel;
});
const sortedMotionSegments = [...renderMotionSegments].sort((a, b) => {
const aSel = selectedIdSet.has(a.id) ? 1 : 0;
const bSel = selectedIdSet.has(b.id) ? 1 : 0;
return aSel - bSel;
});
const sortedAudioSegments = [...renderAudioSegments].sort((a, b) => {
const aSel = selectedIdSet.has(a.id) ? 1 : 0;
const bSel = selectedIdSet.has(b.id) ? 1 : 0;
return aSel - bSel;
});
if (this.retakeMode) {
// Draw Retake Mode Filmstrip and Overlay
@@ -6417,7 +6418,7 @@ class TimelineEditor {
const rawEndX = ((seg.start + seg.length) / totalFrames) * width;
const startX = Math.floor(rawStartX);
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 imgObj = originalSeg ? originalSeg.imgObj : seg.imgObj;
@@ -6753,7 +6754,7 @@ class TimelineEditor {
const startX = Math.floor((seg.start / totalFrames) * width);
const rawEndX = ((seg.start + seg.length) / totalFrames) * width;
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;
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.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 videoEl = originalSeg ? originalSeg.videoEl : seg.videoEl;
@@ -6974,7 +6975,7 @@ class TimelineEditor {
const rawEndX = ((seg.start + seg.length) / totalFrames) * width;
const startX = Math.floor(rawStartX);
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;
if ((this._isDragging && this.selectionType === "audio" && seg.id === this._dragTargetId) || (this._ghostSegmentId && seg.id === this._ghostSegmentId)) {
@@ -9840,16 +9841,19 @@ class TimelineEditor {
let clickedSeg = null;
let trackType = "";
if (isMotionTrack) {
clickedSeg = this.timeline.motionSegments.find(s => cursor >= s.start && cursor <= s.start + s.length);
trackType = "motion";
} else if (isAudioTrack) {
clickedSeg = this.timeline.audioSegments.find(s => cursor >= s.start && cursor <= s.start + s.length);
trackType = "audio";
} else if (isImageTrack) {
clickedSeg = this.timeline.segments.find(s => cursor >= s.start && cursor <= s.start + s.length);
trackType = clickedSeg ? clickedSeg.type : "";
}
if (isMotionTrack) {
clickedSeg = findActiveSegmentAtFrame(this.timeline.motionSegments, cursor, "motion_video");
trackType = "motion";
} else if (isAudioTrack) {
clickedSeg = findActiveSegmentAtFrame(this.timeline.audioSegments, cursor, "audio");
trackType = "audio";
} else if (isImageTrack) {
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 : "";
}
if (clickedSeg) {
this.showContextMenu(e.clientX, e.clientY, clickedSeg, trackType);
@@ -10105,9 +10109,9 @@ class TimelineEditor {
seg.prompt = text;
this.commitChanges();
this.render();
if (this.selectedIndex === this.timeline.segments.findIndex(s => s.id === seg.id)) {
this.updateUIFromSelection();
}
if (this.selectedIndex === findSegmentIndexById(this.timeline.segments, seg.id)) {
this.updateUIFromSelection();
}
}
} catch (err) {
console.error("Failed to paste prompt", err);
@@ -10204,9 +10208,9 @@ class TimelineEditor {
seg.imgObj = img;
this.commitChanges();
this.render();
if (this.selectedIndex === this.timeline.segments.findIndex(s => s.id === seg.id)) {
this.updateUIFromSelection();
}
if (this.selectedIndex === findSegmentIndexById(this.timeline.segments, seg.id)) {
this.updateUIFromSelection();
}
};
img.src = imgUrl;
}
@@ -10249,9 +10253,9 @@ class TimelineEditor {
seg.imgObj = img;
this.commitChanges();
this.render();
if (this.selectedIndex === this.timeline.segments.findIndex(s => s.id === seg.id)) {
this.updateUIFromSelection();
}
if (this.selectedIndex === findSegmentIndexById(this.timeline.segments, seg.id)) {
this.updateUIFromSelection();
}
};
img.src = imgUrl;
}