melhorando a leitura de projetos no mmpCreator
Deploy / Deploy (push) Successful in 2m7s
Details
Deploy / Deploy (push) Successful in 2m7s
Details
This commit is contained in:
parent
51b408909e
commit
9c7f62ada4
|
|
@ -318,11 +318,21 @@ body.sidebar-hidden .sample-browser { width: 0; min-width: 0; border-right: none
|
||||||
}
|
}
|
||||||
/* CORREÇÃO CSS: Adicionado para garantir layout correto */
|
/* CORREÇÃO CSS: Adicionado para garantir layout correto */
|
||||||
.audio-tracks-wrapper {
|
.audio-tracks-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
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; }
|
#audio-track-container { flex-grow: 1; overflow: auto; }
|
||||||
|
|
|
||||||
|
|
@ -57,19 +57,47 @@ export function renderAudioEditor() {
|
||||||
|
|
||||||
const pixelsPerSecond = getPixelsPerSecond();
|
const pixelsPerSecond = getPixelsPerSecond();
|
||||||
|
|
||||||
let maxTime = appState.global.loopEndTime;
|
let maxTime = appState.global.loopEndTime || 0;
|
||||||
appState.audio.clips.forEach((clip) => {
|
|
||||||
|
// áudio (segundos)
|
||||||
|
(appState.audio.clips || []).forEach((clip) => {
|
||||||
const endTime =
|
const endTime =
|
||||||
(clip.startTimeInSeconds || 0) + (clip.durationInSeconds || 0);
|
(clip.startTimeInSeconds || 0) + (clip.durationInSeconds || 0);
|
||||||
if (endTime > maxTime) maxTime = endTime;
|
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 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`;
|
ruler.style.width = `${totalWidth}px`;
|
||||||
|
|
||||||
|
|
||||||
const zoomFactor = ZOOM_LEVELS[appState.global.zoomLevelIndex];
|
const zoomFactor = ZOOM_LEVELS[appState.global.zoomLevelIndex];
|
||||||
const beatsPerBar = getBeatsPerBar();
|
const beatsPerBar = getBeatsPerBar();
|
||||||
const stepWidthPx = PIXELS_PER_STEP * zoomFactor;
|
const stepWidthPx = PIXELS_PER_STEP * zoomFactor;
|
||||||
|
|
@ -461,14 +489,61 @@ export function renderAudioEditor() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sync Scroll
|
// 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", () => {
|
newTrackContainer.addEventListener("scroll", () => {
|
||||||
const scrollPos = newTrackContainer.scrollLeft;
|
const scrollPos = newTrackContainer.scrollLeft;
|
||||||
const mainRuler = document.querySelector(".timeline-ruler");
|
|
||||||
|
// sync ruler
|
||||||
|
const mainRuler = tracksParent.querySelector(".timeline-ruler");
|
||||||
if (mainRuler && mainRuler.scrollLeft !== scrollPos) {
|
if (mainRuler && mainRuler.scrollLeft !== scrollPos) {
|
||||||
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)
|
// Event Listener Principal (mousedown)
|
||||||
newTrackContainer.addEventListener("mousedown", (e) => {
|
newTrackContainer.addEventListener("mousedown", (e) => {
|
||||||
document.getElementById("timeline-context-menu").style.display = "none";
|
document.getElementById("timeline-context-menu").style.display = "none";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue