melhorando a leitura de projetos no mmpCreator
Deploy / Deploy (push) Successful in 2m7s Details

This commit is contained in:
JotaChina 2025-12-23 20:15:03 -03:00
parent 51b408909e
commit 9c7f62ada4
2 changed files with 95 additions and 10 deletions

View File

@ -323,6 +323,16 @@ body.sidebar-hidden .sample-browser { width: 0; min-width: 0; border-right: none
flex-direction: column;
position: relative;
overflow: hidden;
position: relative;
overflow-x: auto; /* barra horizontal */
overflow-y: auto; /* se quiser rolar vertical com várias tracks */
}
/* Importantíssimo: esses caras precisam poder ficar mais largos que a tela */
#audio-timeline-ruler,
#audio-track-container{
position: relative;
min-width: 100%; /* no mínimo ocupa a viewport */
}
#audio-track-container { flex-grow: 1; overflow: auto; }

View File

@ -57,19 +57,47 @@ export function renderAudioEditor() {
const pixelsPerSecond = getPixelsPerSecond();
let maxTime = appState.global.loopEndTime;
appState.audio.clips.forEach((clip) => {
let maxTime = appState.global.loopEndTime || 0;
// áudio (segundos)
(appState.audio.clips || []).forEach((clip) => {
const endTime =
(clip.startTimeInSeconds || 0) + (clip.durationInSeconds || 0);
if (endTime > maxTime) maxTime = endTime;
});
const containerWidth = existingTrackContainer.offsetWidth;
// basslines (ticks -> steps -> segundos)
const TICKS_PER_STEP = 12; // você já usa 12 na renderização do bassline
const secondsPerStep = getSecondsPerStep();
if (appState.pattern?.tracks) {
appState.pattern.tracks.forEach((t) => {
if (t.type !== "bassline" || !Array.isArray(t.playlist_clips)) return;
t.playlist_clips.forEach((c) => {
const endTicks = (c.pos || 0) + (c.len || 0);
const endSteps = endTicks / TICKS_PER_STEP;
const endTimeSec = endSteps * secondsPerStep;
if (endTimeSec > maxTime) maxTime = endTimeSec;
});
});
}
const containerWidth =
tracksParent.clientWidth || existingTrackContainer.offsetWidth;
const contentWidth = maxTime * pixelsPerSecond;
const totalWidth = Math.max(contentWidth, containerWidth, 2000);
// não encolhe se já tiver sido expandido antes
const previousWidth = appState.audio.timelineWidthPx || 0;
const totalWidth = Math.max(contentWidth, containerWidth, previousWidth, 2000);
appState.audio.timelineWidthPx = totalWidth;
ruler.style.width = `${totalWidth}px`;
const zoomFactor = ZOOM_LEVELS[appState.global.zoomLevelIndex];
const beatsPerBar = getBeatsPerBar();
const stepWidthPx = PIXELS_PER_STEP * zoomFactor;
@ -461,14 +489,61 @@ export function renderAudioEditor() {
});
// Sync Scroll
function appendRulerMarkers(rulerEl, oldWidth, newWidth, barWidthPx) {
if (!rulerEl || barWidthPx <= 0) return;
const loopEl = rulerEl.querySelector("#loop-region");
const startBar = Math.floor(oldWidth / barWidthPx) + 1;
const endBar = Math.ceil(newWidth / barWidthPx);
for (let i = startBar; i <= endBar; i++) {
const marker = document.createElement("div");
marker.className = "ruler-marker";
marker.textContent = i;
marker.style.left = `${(i - 1) * barWidthPx}px`;
// mantém loop por cima/ordem estável
rulerEl.insertBefore(marker, loopEl || null);
}
}
function applyTimelineWidth(widthPx) {
appState.audio.timelineWidthPx = widthPx;
const r = tracksParent.querySelector(".timeline-ruler");
if (r) r.style.width = `${widthPx}px`;
tracksParent
.querySelectorAll(".spectrogram-view-grid")
.forEach((g) => (g.style.width = `${widthPx}px`));
}
newTrackContainer.addEventListener("scroll", () => {
const scrollPos = newTrackContainer.scrollLeft;
const mainRuler = document.querySelector(".timeline-ruler");
// sync ruler
const mainRuler = tracksParent.querySelector(".timeline-ruler");
if (mainRuler && mainRuler.scrollLeft !== scrollPos) {
mainRuler.scrollLeft = scrollPos;
}
// expansão "infinita"
const threshold = 300;
const rightEdge = scrollPos + newTrackContainer.clientWidth;
const currentWidth = appState.audio.timelineWidthPx || totalWidth;
if (rightEdge > currentWidth - threshold) {
const newWidth = Math.ceil(currentWidth * 1.5);
// aplica widths
applyTimelineWidth(newWidth);
// adiciona mais marcadores na régua (sem re-render geral)
const rulerEl = tracksParent.querySelector(".timeline-ruler");
appendRulerMarkers(rulerEl, currentWidth, newWidth, barWidthPx);
}
});
// Event Listener Principal (mousedown)
newTrackContainer.addEventListener("mousedown", (e) => {
document.getElementById("timeline-context-menu").style.display = "none";