From 95723d1f26cfcd33184cc27c223695c77d15422a Mon Sep 17 00:00:00 2001 From: JotaChina Date: Fri, 29 Aug 2025 18:58:56 -0300 Subject: [PATCH] =?UTF-8?q?Arrumando=20barra=20de=20navega=C3=A7=C3=A3o=20?= =?UTF-8?q?das=20patterns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/creations/file.js | 17 +-------------- assets/js/creations/ui.js | 42 ++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/assets/js/creations/file.js b/assets/js/creations/file.js index c6f3ff3..e31e345 100644 --- a/assets/js/creations/file.js +++ b/assets/js/creations/file.js @@ -67,14 +67,9 @@ export async function parseMmpContent(xmlString) { const totalSteps = getTotalSteps(); const newSteps = new Array(totalSteps).fill(false); - // ================================================================== - // (CORREÇÃO DEFINITIVA) - // 1. Simplificamos o cálculo: cada step de 1/16 vale 12 ticks. const ticksPerStep = 12; - // 2. Buscamos TODAS as notas da trilha, não importa em qual pattern elas estejam. trackNode.querySelectorAll("note").forEach((noteNode) => { - // ================================================================== const pos = parseInt(noteNode.getAttribute("pos"), 10); const stepIndex = Math.round(pos / ticksPerStep); if (stepIndex < totalSteps) { @@ -205,21 +200,11 @@ function modifyAndSaveExistingMmp() { function createTrackXml(track) { if (!track.samplePath) return ""; const totalSteps = track.steps.length || getTotalSteps(); - const ticksPerStep = 12; // Valor fixo de 12 ticks por step de 1/16 + const ticksPerStep = 12; const lmmsVolume = Math.round(track.volume * 100); const lmmsPan = Math.round(track.pan * 100); const sampleSrc = track.samplePath.replace("src/samples/", ""); - const notesXml = track.steps - .map((isActive, index) => { - if (isActive) { - const notePos = Math.round(index * ticksPerStep); - return ``; - } - return ""; - }) - .join("\n "); - // Cria um pattern para cada compasso (16 steps) let patternsXml = ''; const stepsPerBar = 16; const numBars = Math.ceil(totalSteps / stepsPerBar); diff --git a/assets/js/creations/ui.js b/assets/js/creations/ui.js index 8fdfdef..a490d56 100644 --- a/assets/js/creations/ui.js +++ b/assets/js/creations/ui.js @@ -13,7 +13,7 @@ import { loadProjectFromServer } from "./file.js"; // Variável para armazenar o mapa de samples (nome do arquivo -> caminho completo) let samplePathMap = {}; -// Função para exportar o mapa de samples para outros módulos +// Função para exportar o mapa de samples, que estava faltando export function getSamplePathMap() { return samplePathMap; } @@ -60,7 +60,7 @@ export function renderApp() { PAN -
+
`; trackLane.addEventListener("dragover", (e) => { @@ -93,13 +93,24 @@ export function renderApp() { } export function redrawSequencer() { - const beatsPerBar = - parseInt(document.getElementById("compasso-a-input").value, 10) || 4; + const beatsPerBar = parseInt(document.getElementById("compasso-a-input").value, 10) || 4; + const noteValue = parseInt(document.getElementById("compasso-b-input").value, 10) || 4; + const subdivisions = Math.round(16 / noteValue); + const stepsPerBar = beatsPerBar * subdivisions; const totalSteps = getTotalSteps(); - document.querySelectorAll(".step-sequencer").forEach((container) => { - const parentTrackElement = container.closest(".track-lane"); + + document.querySelectorAll(".step-sequencer-wrapper").forEach((wrapper) => { + let sequencerContainer = wrapper.querySelector(".step-sequencer"); + if (!sequencerContainer) { + sequencerContainer = document.createElement("div"); + sequencerContainer.className = "step-sequencer"; + wrapper.appendChild(sequencerContainer); + } + + const parentTrackElement = wrapper.closest(".track-lane"); const trackId = parentTrackElement.dataset.trackId; const trackData = appState.tracks.find((t) => t.id == trackId); + if (trackData && trackData.steps.length !== totalSteps) { const newStepsState = new Array(totalSteps).fill(false); for (let i = 0; i < Math.min(trackData.steps.length, totalSteps); i++) { @@ -107,10 +118,12 @@ export function redrawSequencer() { } trackData.steps = newStepsState; } - container.innerHTML = ""; + + sequencerContainer.innerHTML = ""; for (let i = 0; i < totalSteps; i++) { const stepWrapper = document.createElement("div"); stepWrapper.className = "step-wrapper"; + const stepElement = document.createElement("div"); stepElement.className = "step"; if (trackData && trackData.steps[i] === true) { @@ -123,27 +136,29 @@ export function redrawSequencer() { playSample(trackData.samplePath, trackData.id); } }); + const groupIndex = Math.floor(i / beatsPerBar); if (groupIndex % 2 === 0) { stepElement.classList.add("step-dark"); } - if (i > 0 && i % beatsPerBar === 0) { + + if (i > 0 && i % stepsPerBar === 0) { const marker = document.createElement("div"); marker.className = "step-marker"; - marker.textContent = i; + marker.textContent = Math.floor(i / stepsPerBar) + 1; stepWrapper.appendChild(marker); } + stepWrapper.appendChild(stepElement); - container.appendChild(stepWrapper); + sequencerContainer.appendChild(stepWrapper); } }); } -// LÓGICA DE INTERAÇÃO DOS KNOBS function addKnobInteraction(knobElement) { const controlType = knobElement.dataset.control; knobElement.addEventListener("mousedown", (e) => { - if (e.button === 1) { // Middle mouse button + if (e.button === 1) { e.preventDefault(); const trackId = knobElement.dataset.trackId; const defaultValue = controlType === "volume" ? 0.8 : 0.0; @@ -156,7 +171,7 @@ function addKnobInteraction(knobElement) { } }); knobElement.addEventListener("mousedown", (e) => { - if (e.button !== 0) return; // Apenas botão esquerdo + if (e.button !== 0) return; e.preventDefault(); const trackId = knobElement.dataset.trackId; const track = appState.tracks.find((t) => t.id == trackId); @@ -249,7 +264,6 @@ export function highlightStep(stepIndex, isActive) { }); } -// LÓGICA DA SIDEBAR E MODAL export async function loadAndRenderSampleBrowser() { const browserContent = document.getElementById("browser-content"); try {