perf: trim editor render selection lookups
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user