plugin v1.0.1
Deploy / Deploy (push) Successful in 1m15s Details

This commit is contained in:
JotaChina 2025-11-23 14:36:24 -03:00
parent f80643b28b
commit 9d279d6bda
2 changed files with 400 additions and 415 deletions

View File

@ -1,7 +1,4 @@
/* =============================================== */
/* MMPCreator - Folha de Estilos Principal */
/* =============================================== */
/* MMPCreator - Folha de Estilos Principal */
:root {
--bg-body: #2d3035;
--bg-toolbar: #3b3f45;

View File

@ -70,425 +70,418 @@
</style>
</head>
<body>
<aside class="sample-browser">
<div class="browser-header">Navegador de Samples</div>
<div class="browser-content" id="browser-content"></div>
</aside>
<div class="studio-wrapper">
<aside class="sample-browser">
<div class="browser-header">Navegador de Samples</div>
<div class="browser-content" id="browser-content"></div>
</aside>
<button id="sidebar-toggle"><i class="fa-solid fa-caret-left"></i></button>
<div class="app-container">
<header class="global-toolbar">
<div class="control-group">
<i
class="fa-solid fa-file"
id="new-project-btn"
title="Novo Projeto"
></i>
<i
class="fa-solid fa-folder-open"
id="open-mmp-btn"
title="Abrir Projeto do Servidor"
></i>
<i
class="fa-solid fa-save"
id="save-mmp-btn"
title="Salvar Projeto (.mmp)"
></i>
<i
class="fa-solid fa-upload"
id="upload-sample-btn"
title="Carregar Sample do Computador"
></i>
</div>
<div class="divider"></div>
<div class="control-group">
<i
class="fa-solid fa-backward-step"
id="rewind-btn"
title="Voltar ao Início"
></i>
<i class="fa-solid fa-play" title="Play/Pause Global (Futuro)"></i>
<i class="fa-solid fa-stop" title="Stop Global (Futuro)"></i>
<button id="record-btn" class="transport-btn" title="Gravar">
<i class="fa-solid fa-circle-dot"></i>
</button>
</div>
<div class="divider"></div>
<div class="info-display-group">
<div class="info-display">
<div class="interactive-input-container">
<button class="adjust-btn" data-target="bpm" data-step="-1">
-
</button>
<input
type="text"
class="value-input"
id="bpm-input"
value="140"
data-min="20"
data-max="400"
/>
<button class="adjust-btn" data-target="bpm" data-step="1">
+
</button>
</div>
<div class="label">ANDAMENTO/BPM</div>
<button id="sidebar-toggle"><i class="fa-solid fa-caret-left"></i></button>
<div class="app-container">
<header class="global-toolbar">
<div class="control-group">
<i
class="fa-solid fa-file"
id="new-project-btn"
title="Novo Projeto"
></i>
<i
class="fa-solid fa-folder-open"
id="open-mmp-btn"
title="Abrir Projeto do Servidor"
></i>
<i
class="fa-solid fa-save"
id="save-mmp-btn"
title="Salvar Projeto (.mmp)"
></i>
<i
class="fa-solid fa-upload"
id="upload-sample-btn"
title="Carregar Sample do Computador"
></i>
</div>
<div class="divider"></div>
<div class="control-group">
<i
class="fa-solid fa-backward-step"
id="rewind-btn"
title="Voltar ao Início"
></i>
<i class="fa-solid fa-play" title="Play/Pause Global (Futuro)"></i>
<i class="fa-solid fa-stop" title="Stop Global (Futuro)"></i>
<button id="record-btn" class="transport-btn" title="Gravar">
<i class="fa-solid fa-circle-dot"></i>
</button>
</div>
<div class="divider"></div>
<div class="info-display-group">
<div class="info-display">
<div class="interactive-input-container">
<button class="adjust-btn" data-target="bpm" data-step="-1">
-
</button>
<input
type="text"
class="value-input"
id="bpm-input"
value="140"
data-min="20"
data-max="400"
/>
<button class="adjust-btn" data-target="bpm" data-step="1">
+
</button>
</div>
<div class="info-display">
<div class="interactive-input-container">
<button class="adjust-btn" data-target="bars" data-step="-1">
<div class="label">ANDAMENTO/BPM</div>
</div>
<div class="info-display">
<div class="interactive-input-container">
<button class="adjust-btn" data-target="bars" data-step="-1">
-
</button>
<input
type="text"
class="value-input"
id="bars-input"
value="1"
data-min="1"
data-max="64"
/>
<button class="adjust-btn" data-target="bars" data-step="1">
+
</button>
</div>
<div class="label">COMPASSOS</div>
</div>
<div class="info-display">
<div class="interactive-input-container">
<div class="compasso-group">
<button
class="adjust-btn"
data-target="compasso-a"
data-step="-1"
>
-
</button>
<input
type="text"
class="value-input"
id="bars-input"
value="1"
class="value-input compasso-input"
id="compasso-a-input"
value="4"
data-min="1"
data-max="64"
data-max="16"
/>
<button class="adjust-btn" data-target="bars" data-step="1">
<button
class="adjust-btn"
data-target="compasso-a"
data-step="1"
>
+
</button>
</div>
<div class="label">COMPASSOS</div>
</div>
<div class="info-display">
<div class="interactive-input-container">
<div class="compasso-group">
<button
class="adjust-btn"
data-target="compasso-a"
data-step="-1"
>
-
</button>
<input
type="text"
class="value-input compasso-input"
id="compasso-a-input"
value="4"
data-min="1"
data-max="16"
/>
<button
class="adjust-btn"
data-target="compasso-a"
data-step="1"
>
+
</button>
</div>
<span class="compasso-separator">/</span>
<div class="compasso-group">
<button
class="adjust-btn"
data-target="compasso-b"
data-step="-1"
>
-
</button>
<input
type="text"
class="value-input compasso-input"
id="compasso-b-input"
value="4"
data-min="1"
data-max="16"
/>
<button
class="adjust-btn"
data-target="compasso-b"
data-step="1"
>
+
</button>
</div>
<span class="compasso-separator">/</span>
<div class="compasso-group">
<button
class="adjust-btn"
data-target="compasso-b"
data-step="-1"
>
-
</button>
<input
type="text"
class="value-input compasso-input"
id="compasso-b-input"
value="4"
data-min="1"
data-max="16"
/>
<button
class="adjust-btn"
data-target="compasso-b"
data-step="1"
>
+
</button>
</div>
<div class="label">COMPASSO</div>
</div>
<div class="info-display">
<div
id="timer-display"
class="interactive-input-container"
style="font-size: 0.7rem; color: var(--text-dark)"
>
00:00:00
</div>
<div class="label">MIN:SEC:MSEC</div>
</div>
<div class="label">COMPASSO</div>
</div>
<div class="control-group">
<button id="metronome-btn" title="Metrônomo On/Off">Metrônomo</button>
<button
id="create-room-btn"
class="transport-btn"
title="Criar ou entrar em uma sala compartilhada"
<div class="info-display">
<div
id="timer-display"
class="interactive-input-container"
style="font-size: 0.7rem; color: var(--text-dark)"
>
<i class="fa-solid fa-users"></i>
<span style="margin-left: 8px">Criar Sala</span>
</button>
</div>
<div class="spacer"></div>
<div class="control-group master-controls">
<div class="knob-container">
<div class="knob" id="master-volume-knob">
<div class="knob-indicator"></div>
</div>
<span>VOL MASTER</span>
00:00:00
</div>
<div class="knob-container">
<div class="knob" id="master-pan-knob">
<div class="knob-indicator"></div>
</div>
<span>PAN MASTER</span>
<div class="label">MIN:SEC:MSEC</div>
</div>
</div>
<div class="control-group">
<button id="metronome-btn" title="Metrônomo On/Off">Metrônomo</button>
<button
id="create-room-btn"
class="transport-btn"
title="Criar ou entrar em uma sala compartilhada"
>
<i class="fa-solid fa-users"></i>
<span style="margin-left: 8px">Criar Sala</span>
</button>
</div>
<div class="spacer"></div>
<div class="control-group master-controls">
<div class="knob-container">
<div class="knob" id="master-volume-knob">
<div class="knob-indicator"></div>
</div>
<span>VOL MASTER</span>
</div>
<div class="knob-container">
<div class="knob" id="master-pan-knob">
<div class="knob-indicator"></div>
</div>
<span>PAN MASTER</span>
</div>
</div>
</header>
<main class="main-content">
<div class="beat-editor">
<div class="editor-header">
Mostrar/esconder Editor de Bases
<div class="window-controls">
<i class="fa-solid fa-minus"></i
><i class="fa-regular fa-square"></i
><i class="fa-solid fa-xmark"></i>
</div>
</div>
</header>
<div class="editor-toolbar">
<div class="playback-controls">
<i class="fa-solid fa-play" id="play-btn" title="Play/Pause"></i>
<i class="fa-solid fa-stop" id="stop-btn" title="Stop"></i>
</div>
<div class="pattern-manager">
<h2 id="beat-bassline-title"></h2>
<select
id="global-pattern-selector"
class="pattern-selector"
disabled
>
<option>Selecione uma faixa</option>
</select>
<button id="add-pattern-btn" class="pattern-btn">+</button>
<button id="remove-pattern-btn" class="pattern-btn">-</button>
<main class="main-content">
<div class="beat-editor">
<div class="editor-header">
Mostrar/esconder Editor de Bases
<div class="window-controls">
<i class="fa-solid fa-minus"></i
><i class="fa-regular fa-square"></i
><i class="fa-solid fa-xmark"></i>
<button
id="send-pattern-to-playlist-btn"
class="pattern-btn"
title="Enviar Pattern para a Playlist"
style="width: auto; padding: 0 8px; font-size: 0.9rem"
>
<i class="fa-solid fa-arrow-right-to-bracket"></i> Enviar
</button>
</div>
<div class="tool-icons">
<i class="fa-solid fa-table-cells"></i
><i class="fa-solid fa-bars-staggered"></i>
<i class="fa-solid fa-music" id="open-piano-roll-btn" title="Abrir Piano Roll"></i>
<i
class="fa-solid fa-wave-square"
id="bounce-pattern-btn"
title="Renderizar Pattern para Pista de Áudio"
></i>
<i
class="fa-solid fa-plus"
id="add-bar-btn"
title="Adicionar 1 Compasso"
></i>
</div>
<div id="timeline-context-menu">
<div id="copy-clip">Copiar</div>
<div id="cut-clip">Recortar</div>
<div id="paste-clip">Colar</div>
<div class="menu-divider"></div>
<div id="delete-clip" style="color: var(--accent-red)">
Excluir Clipe
</div>
</div>
<div class="editor-toolbar">
<div class="playback-controls">
<i class="fa-solid fa-play" id="play-btn" title="Play/Pause"></i>
<i class="fa-solid fa-stop" id="stop-btn" title="Stop"></i>
</div>
<div class="pattern-manager">
<h2 id="beat-bassline-title"></h2>
<select
id="global-pattern-selector"
class="pattern-selector"
disabled
>
<option>Selecione uma faixa</option>
</select>
<button id="add-pattern-btn" class="pattern-btn">+</button>
<button id="remove-pattern-btn" class="pattern-btn">-</button>
<button
id="send-pattern-to-playlist-btn"
class="pattern-btn"
title="Enviar Pattern para a Playlist"
style="width: auto; padding: 0 8px; font-size: 0.9rem"
>
<i class="fa-solid fa-arrow-right-to-bracket"></i> Enviar
</button>
</div>
<div class="tool-icons">
<i class="fa-solid fa-table-cells"></i
><i class="fa-solid fa-bars-staggered"></i>
<i class="fa-solid fa-music" id="open-piano-roll-btn" title="Abrir Piano Roll"></i>
<i
class="fa-solid fa-wave-square"
id="bounce-pattern-btn"
title="Renderizar Pattern para Pista de Áudio"
></i>
<i
class="fa-solid fa-plus"
id="add-bar-btn"
title="Adicionar 1 Compasso"
></i>
</div>
<div id="timeline-context-menu">
<div id="copy-clip">Copiar</div>
<div id="cut-clip">Recortar</div>
<div id="paste-clip">Colar</div>
<div class="menu-divider"></div>
<div id="delete-clip" style="color: var(--accent-red)">
Excluir Clipe
</div>
</div>
<div id="ruler-context-menu">
<div id="ruler-set-loop-start">Definir Início do Loop</div>
<div id="ruler-set-loop-end">Definir Fim do Loop</div>
</div>
<div class="zoom-controls">
<i class="fa-solid fa-minus" id="remove-instrument-btn"></i
><i class="fa-solid fa-plus" id="add-instrument-btn"></i>
</div>
<div id="ruler-context-menu">
<div id="ruler-set-loop-start">Definir Início do Loop</div>
<div id="ruler-set-loop-end">Definir Fim do Loop</div>
</div>
<div id="track-container"></div>
</div>
<div class="piano-roll-editor" id="piano-roll-editor" style="display: none;">
<div class="editor-header">
<span>Piano Roll - <span id="piano-roll-instrument-name">Instrumento 1</span></span>
<div class="window-controls">
<i class="fa-solid fa-xmark" id="close-piano-roll-btn"></i>
</div>
</div>
<div class="piano-roll-toolbar">
<div class="playback-controls">
<i class="fa-solid fa-pencil active" title="Draw Tool"></i>
<i class="fa-solid fa-eraser" title="Erase Tool"></i>
</div>
<div class="snap-controls">
<label>Snap:</label>
<select>
<option>1/4</option>
<option>1/8</option>
<option selected>1/16</option>
</select>
</div>
</div>
<div class="piano-roll-workspace">
<div class="piano-keys-container" id="piano-keys-container">
<canvas id="piano-keys-canvas"></canvas>
</div>
<div class="piano-grid-container" id="piano-grid-container">
<canvas id="piano-grid-canvas"></canvas>
</div>
<div class="zoom-controls">
<i class="fa-solid fa-minus" id="remove-instrument-btn"></i
><i class="fa-solid fa-plus" id="add-instrument-btn"></i>
</div>
</div>
<div id="track-container"></div>
</div>
<div class="piano-roll-editor" id="piano-roll-editor" style="display: none;">
<div class="editor-header">
<span>Piano Roll - <span id="piano-roll-instrument-name">Instrumento 1</span></span>
<div class="window-controls">
<i class="fa-solid fa-xmark" id="close-piano-roll-btn"></i>
</div>
</div>
<div class="audio-editor">
<div class="editor-header">
<span>Editor de Amostras de Áudio</span>
<div class="piano-roll-toolbar">
<div class="playback-controls">
<i class="fa-solid fa-pencil active" title="Draw Tool"></i>
<i class="fa-solid fa-eraser" title="Erase Tool"></i>
</div>
<div class="snap-controls">
<label>Snap:</label>
<select>
<option>1/4</option>
<option>1/8</option>
<option selected>1/16</option>
</select>
</div>
</div>
<div class="playback-controls">
<i
class="fa-solid fa-search-minus"
id="zoom-out-btn"
title="Zoom Out"
></i>
<i
class="fa-solid fa-search-plus"
id="zoom-in-btn"
title="Zoom In"
></i>
<i
class="fa-solid fa-scissors"
id="slice-tool-btn"
title="Ferramenta de Corte"
></i>
<div class="piano-roll-workspace">
<div class="piano-keys-container" id="piano-keys-container">
<canvas id="piano-keys-canvas"></canvas>
</div>
<i
class="fa-solid fa-arrows-left-right-to-line"
id="resize-tool-trim"
title="Modo de Redimensionamento (Aparar/Trimming)"
></i>
<i
class="fa-solid fa-arrows-left-right"
id="resize-tool-stretch"
title="Modo de Redimensionamento (Esticar/Time Stretch)"
></i>
<i
class="fa-solid fa-play"
id="audio-editor-play-btn"
title="Play/Pause"
></i>
<i
class="fa-solid fa-stop"
id="audio-editor-stop-btn"
title="Stop"
></i>
<i
class="fa-solid fa-repeat"
id="audio-editor-loop-btn"
title="Ativar/Desativar Loop"
></i>
<button
id="sync-mode-btn"
class="control-btn active"
title="Modo de Sincronia de Playback (Global/Local)"
>
Global
</button>
<i
class="fa-solid fa-plus"
id="add-audio-track-btn"
title="Adicionar Pista de Áudio"
></i>
</div>
<div class="piano-grid-container" id="piano-grid-container">
<canvas id="piano-grid-canvas"></canvas>
</div>
</div>
</div>
<div class="audio-editor">
<div class="editor-header">
<span>Editor de Amostras de Áudio</span>
<div class="playback-controls">
<i
class="fa-solid fa-search-minus"
id="zoom-out-btn"
title="Zoom Out"
></i>
<i
class="fa-solid fa-search-plus"
id="zoom-in-btn"
title="Zoom In"
></i>
<i
class="fa-solid fa-scissors"
id="slice-tool-btn"
title="Ferramenta de Corte"
></i>
<i
class="fa-solid fa-arrows-left-right-to-line"
id="resize-tool-trim"
title="Modo de Redimensionamento (Aparar/Trimming)"
></i>
<i
class="fa-solid fa-arrows-left-right"
id="resize-tool-stretch"
title="Modo de Redimensionamento (Esticar/Time Stretch)"
></i>
<i
class="fa-solid fa-play"
id="audio-editor-play-btn"
title="Play/Pause"
></i>
<i
class="fa-solid fa-stop"
id="audio-editor-stop-btn"
title="Stop"
></i>
<i
class="fa-solid fa-repeat"
id="audio-editor-loop-btn"
title="Ativar/Desativar Loop"
></i>
<button
id="sync-mode-btn"
class="control-btn active"
title="Modo de Sincronia de Playback (Global/Local)"
>
Global
</button>
<i
class="fa-solid fa-plus"
id="add-audio-track-btn"
title="Adicionar Pista de Áudio"
></i>
</div>
<div id="audio-track-container">
<div class="audio-track-lane">
<div class="track-info">
<div class="track-info-header">
<i class="fa-solid fa-gear"></i>
<span class="track-name">Pista de Áudio 1</span>
<div class="track-mute"></div>
</div>
<div class="track-controls">
<div class="knob-container">
<div class="knob" data-control="volume">
<div class="knob-indicator"></div>
</div>
<span>VOL</span>
</div>
<div class="knob-container">
<div class="knob" data-control="pan">
<div class="knob-indicator"></div>
</div>
<span>PAN</span>
</div>
</div>
</div>
<div id="audio-track-container">
<div class="audio-track-lane">
<div class="track-info">
<div class="track-info-header">
<i class="fa-solid fa-gear"></i>
<span class="track-name">Pista de Áudio 1</span>
<div class="track-mute"></div>
</div>
<div class="timeline-container">
<div class="spectrogram-view-grid" style="width: 4000px">
<div
class="timeline-clip"
style="left: 100px; width: 400px"
></div>
<div class="playhead"></div>
<div class="track-controls">
<div class="knob-container">
<div class="knob" data-control="volume">
<div class="knob-indicator"></div>
</div>
<span>VOL</span>
</div>
<div class="knob-container">
<div class="knob" data-control="pan">
<div class="knob-indicator"></div>
</div>
<span>PAN</span>
</div>
</div>
</div>
<div class="audio-track-lane">
<div class="track-info">
<div class="track-info-header">
<i class="fa-solid fa-gear"></i>
<span class="track-name">Pista de Áudio 2</span>
<div class="track-mute"></div>
</div>
<div class="track-controls">
<div class="knob-container">
<div class="knob" data-control="volume">
<div class="knob-indicator"></div>
</div>
<span>VOL</span>
</div>
<div class="knob-container">
<div class="knob" data-control="pan">
<div class="knob-indicator"></div>
</div>
<span>PAN</span>
</div>
</div>
</div>
<div class="timeline-container">
<div id="loop-region" class="loop-region">
<div class="spectrogram-view-grid" style="width: 4000px">
<div class="timeline-clip" style="left: 50px; width: 600px">
<div class="clip-name">jungle01.ogg</div>
</div>
</div>
</div>
<div class="timeline-container">
<div class="spectrogram-view-grid" style="width: 4000px">
<div
class="timeline-clip"
style="left: 100px; width: 400px"
></div>
<div class="playhead"></div>
</div>
</div>
</div>
<div class="audio-track-lane">
<div class="track-info">
<div class="track-info-header">
<i class="fa-solid fa-gear"></i>
<span class="track-name">Pista de Áudio 2</span>
<div class="track-mute"></div>
</div>
<div class="track-controls">
<div class="knob-container">
<div class="knob" data-control="volume">
<div class="knob-indicator"></div>
</div>
<span>VOL</span>
</div>
<div class="knob-container">
<div class="knob" data-control="pan">
<div class="knob-indicator"></div>
</div>
<span>PAN</span>
</div>
</div>
</div>
<div class="timeline-container">
<div id="loop-region" class="loop-region">
<div class="spectrogram-view-grid" style="width: 4000px">
<div class="timeline-clip" style="left: 50px; width: 600px">
<div class="clip-name">jungle01.ogg</div>
</div>
</div>
</div>
<div class="playhead"></div>
</div>
</div>
</div>
</main>
</div>
</div>
</main>
</div>
<input
type="file"
@ -536,19 +529,14 @@
// Variáveis de Controle
let currentTrackId = null;
// --- Configurações ---
const CONSTANTS = {
NOTE_HEIGHT: 20,
KEY_WIDTH: 60,
BEAT_WIDTH: 40, // Largura visual de 1 batida (Quarter Note)
TOTAL_KEYS: 84,
START_NOTE: 24,
// --- CORREÇÃO DE ESCALA ---
// O LMMS usa 192 ticks por batida (Quarter Note).
// Se nossa batida tem 40px de largura, a relação é:
TICKS_PER_PIXEL: 192 / 40 // = 4.8
};
const CONSTANTS = {
NOTE_HEIGHT: 20,
KEY_WIDTH: 60,
BEAT_WIDTH: 40,
TOTAL_KEYS: 84, // 7 oitavas
START_NOTE: 24, // C1
TICKS_PER_PIXEL: 0 // Calculado dinamicamente
};
const pianoRollEditor = document.getElementById('piano-roll-editor');
const keysCanvas = document.getElementById('piano-keys-canvas');
@ -584,26 +572,26 @@
// --- DESENHO E LÓGICA ---
function resizeCanvas() {
const totalHeight = CONSTANTS.TOTAL_KEYS * CONSTANTS.NOTE_HEIGHT;
const totalHeight = CONSTANTS.TOTAL_KEYS * CONSTANTS.NOTE_HEIGHT;
// 64 compassos * 192 ticks / (ticks por beat) * largura... simplificando:
// Vamos fixar uma largura grande por enquanto
const totalWidth = 3000;
// Calcula a largura total baseada nos compassos definidos no input
const barsCount = parseInt(document.getElementById('bars-input')?.value || 1);
// 1 Compasso = 4 Batidas. Largura = Batidas * Largura da Batida
const totalWidth = (barsCount * 4) * CONSTANTS.BEAT_WIDTH;
keysCanvas.width = CONSTANTS.KEY_WIDTH;
keysCanvas.height = totalHeight;
gridCanvas.width = totalWidth;
gridCanvas.height = totalHeight;
keysCanvas.width = CONSTANTS.KEY_WIDTH;
keysCanvas.height = totalHeight;
// Importante: Sincronizar a conversão de Pixel <-> Tick
// 1 Beat = 48 ticks (em 16th) ou 192 ticks por bar?
// No seu file.js: ticksPerStep = 12 (1/16).
// Então BEAT_WIDTH (40px) = 4 steps = 48 ticks.
CONSTANTS.TICKS_PER_PIXEL = 48 / CONSTANTS.BEAT_WIDTH;
gridCanvas.width = totalWidth; // Ajusta largura ao tamanho real da música
gridCanvas.height = totalHeight;
// REMOVA ESTA LINHA ANTIGA:
// CONSTANTS.TICKS_PER_PIXEL = 48 / CONSTANTS.BEAT_WIDTH;
drawKeys();
drawGrid();
drawNotes();
}
drawKeys();
drawGrid();
drawNotes();
}
function drawKeys() {
keysCtx.clearRect(0, 0, keysCanvas.width, keysCanvas.height);