@onjmin/dtm 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1104,6 +1104,9 @@ var ICONS = {
1104
1104
  settings: {
1105
1105
  d: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065zM15 12a3 3 0 11-6 0 3 3 0 016 0z",
1106
1106
  stroke: true
1107
+ },
1108
+ info: {
1109
+ d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"
1107
1110
  }
1108
1111
  };
1109
1112
  var icon = (name, size = 20) => {
@@ -1220,13 +1223,23 @@ var buildUI = (target, options) => {
1220
1223
  </div>
1221
1224
  <div class="dtm-row dtm-hidden" data-dtm="midi-track-selection"></div>
1222
1225
  <div class="dtm-row">
1223
- <span class="dtm-label">MML</span>
1226
+ <div style="display: inline-flex; flex-direction: column; align-items: center; gap: 4px; justify-content: center; min-width: 48px;">
1227
+ <span class="dtm-label" style="line-height: 1;">MML</span>
1228
+ <button class="dtm-infobtn" data-dtm="mml-info" title="MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC">${icon("info", 12)}</button>
1229
+ </div>
1224
1230
  <textarea class="dtm-textarea dtm-grow" data-dtm="mml-input" placeholder="MML\u3092\u5165\u529B"></textarea>
1225
1231
  <button class="dtm-btn dtm-btn--primary" data-dtm="mml-load">\u8AAD\u8FBC</button>
1226
1232
  </div>
1233
+ </div>
1234
+ </details>
1235
+
1236
+ <details class="dtm-panel">
1237
+ <summary>\u30DE\u30AF\u30ED</summary>
1238
+ <div class="dtm-panel-body">
1227
1239
  <div class="dtm-row">
1228
1240
  <span class="dtm-label">\u5168\u4F53\u30B7\u30D5\u30C8</span>
1229
1241
  <select class="dtm-select" data-dtm="shift-select">
1242
+ <option value="-192">-1\u5C0F\u7BC0</option>
1230
1243
  <option value="-96">-2\u5206</option>
1231
1244
  <option value="-48">-4\u5206</option>
1232
1245
  <option value="-24">-8\u5206</option>
@@ -1235,15 +1248,10 @@ var buildUI = (target, options) => {
1235
1248
  <option value="24">+8\u5206</option>
1236
1249
  <option value="48">+4\u5206</option>
1237
1250
  <option value="96">+2\u5206</option>
1251
+ <option value="192">+1\u5C0F\u7BC0</option>
1238
1252
  </select>
1239
1253
  <button class="dtm-btn dtm-btn--primary" data-dtm="shift-apply">\u9069\u7528</button>
1240
1254
  </div>
1241
- </div>
1242
- </details>
1243
-
1244
- <details class="dtm-panel">
1245
- <summary>\u30DE\u30AF\u30ED</summary>
1246
- <div class="dtm-panel-body">
1247
1255
  <div class="dtm-row">
1248
1256
  <button class="dtm-btn dtm-btn--danger" data-dtm="macro-clear">\u5168\u6D88\u53BB</button>
1249
1257
  <button class="dtm-btn dtm-btn--accent" data-dtm="macro-random">\u30E9\u30F3\u30C0\u30E0\u914D\u7F6E</button>
@@ -1293,6 +1301,17 @@ var buildUI = (target, options) => {
1293
1301
  </div>
1294
1302
  </div>
1295
1303
  </details>
1304
+
1305
+ <!-- \u2550\u2550\u2550\u2550 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2550\u2550\u2550\u2550 -->
1306
+ <div class="dtm-modal-overlay" data-dtm="modal-overlay" hidden>
1307
+ <div class="dtm-win dtm-modal">
1308
+ <div class="dtm-modal-header">
1309
+ <span class="dtm-modal-title" data-dtm="modal-title"></span>
1310
+ <button class="dtm-modal-close" data-dtm="modal-close">&times;</button>
1311
+ </div>
1312
+ <div class="dtm-modal-body" data-dtm="modal-body"></div>
1313
+ </div>
1314
+ </div>
1296
1315
  </div>`;
1297
1316
  const root = q(target, '[data-dtm="root"]');
1298
1317
  const sel = (name) => q(root, `[data-dtm="${name}"]`);
@@ -1352,7 +1371,12 @@ var buildUI = (target, options) => {
1352
1371
  outputMini: sel("output-mini"),
1353
1372
  copyFullBtn: sel("copy-full"),
1354
1373
  copyMiniBtn: sel("copy-mini"),
1355
- overlay: sel("overlay")
1374
+ overlay: sel("overlay"),
1375
+ mmlInfoBtn: sel("mml-info"),
1376
+ modalOverlay: sel("modal-overlay"),
1377
+ modalTitle: sel("modal-title"),
1378
+ modalBody: sel("modal-body"),
1379
+ modalClose: sel("modal-close")
1356
1380
  };
1357
1381
  };
1358
1382
 
@@ -2772,7 +2796,7 @@ var analyzeMidiTracks = (midi) => {
2772
2796
  const validNotes = notes.filter((n) => n.end !== void 0);
2773
2797
  result.push({
2774
2798
  index: i,
2775
- name: `Ch${i}`,
2799
+ name: `Ch${i + 1}`,
2776
2800
  noteCount: validNotes.length,
2777
2801
  selected: validNotes.length > 0
2778
2802
  });
@@ -4755,6 +4779,128 @@ var DAW_CSS = `
4755
4779
  @keyframes dtm-blink { 0%,100%{opacity:1} 50%{opacity:0} }
4756
4780
  .dtm-blink { animation: dtm-blink 1s steps(1) infinite; }
4757
4781
 
4782
+ /* \u2500\u2500\u2500 \u30A4\u30F3\u30D5\u30A9\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */
4783
+ .dtm-infobtn {
4784
+ display: inline-flex;
4785
+ align-items: center;
4786
+ justify-content: center;
4787
+ width: 20px;
4788
+ height: 20px;
4789
+ flex: 0 0 auto;
4790
+ border: 2px solid var(--dtm-border2);
4791
+ background: var(--dtm-surface);
4792
+ color: var(--dtm-muted);
4793
+ cursor: pointer;
4794
+ box-shadow: 1px 1px 0 var(--c-black);
4795
+ padding: 0;
4796
+ margin: 0;
4797
+ }
4798
+ .dtm-infobtn:hover {
4799
+ color: var(--dtm-primary);
4800
+ border-color: var(--dtm-primary);
4801
+ }
4802
+ .dtm-infobtn:active {
4803
+ transform: translate(1px, 1px);
4804
+ box-shadow: none;
4805
+ }
4806
+
4807
+ /* \u2500\u2500\u2500 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2500\u2500\u2500 */
4808
+ .dtm-modal-overlay {
4809
+ position: fixed;
4810
+ inset: 0;
4811
+ z-index: 10000;
4812
+ background: rgba(0, 0, 0, 0.7);
4813
+ display: flex;
4814
+ align-items: center;
4815
+ justify-content: center;
4816
+ padding: 16px;
4817
+ backdrop-filter: blur(2px);
4818
+ }
4819
+ .dtm-modal-overlay[hidden] {
4820
+ display: none !important;
4821
+ }
4822
+ .dtm-modal {
4823
+ max-width: 500px;
4824
+ width: 100%;
4825
+ max-height: 80vh;
4826
+ display: flex;
4827
+ flex-direction: column;
4828
+ background: var(--dtm-surface);
4829
+ border: 2px solid var(--c-black);
4830
+ box-shadow:
4831
+ inset 0 0 0 2px var(--c-black),
4832
+ 0 0 0 2px var(--dtm-primary),
4833
+ 4px 4px 0 var(--c-black);
4834
+ overflow: hidden;
4835
+ }
4836
+ .dtm-modal-header {
4837
+ display: flex;
4838
+ align-items: center;
4839
+ justify-content: space-between;
4840
+ background: var(--dtm-deep);
4841
+ padding: 8px 12px;
4842
+ border-bottom: 2px solid var(--c-black);
4843
+ }
4844
+ .dtm-modal-title {
4845
+ font-family: var(--dtm-font);
4846
+ font-size: 14px;
4847
+ color: var(--dtm-gold);
4848
+ font-weight: bold;
4849
+ }
4850
+ .dtm-modal-close {
4851
+ background: transparent;
4852
+ border: none;
4853
+ color: var(--dtm-text);
4854
+ font-size: 20px;
4855
+ cursor: pointer;
4856
+ padding: 0;
4857
+ line-height: 1;
4858
+ }
4859
+ .dtm-modal-close:hover {
4860
+ color: var(--dtm-danger);
4861
+ }
4862
+ .dtm-modal-body {
4863
+ padding: 12px;
4864
+ overflow-y: auto;
4865
+ font-size: 13px;
4866
+ line-height: 1.6;
4867
+ }
4868
+ .dtm-modal-body h4 {
4869
+ margin: 12px 0 6px 0;
4870
+ color: var(--dtm-primary);
4871
+ font-size: 13px;
4872
+ }
4873
+ .dtm-modal-body h4:first-child {
4874
+ margin-top: 0;
4875
+ }
4876
+ .dtm-modal-body p {
4877
+ margin: 0 0 8px 0;
4878
+ }
4879
+ .dtm-modal-body ul {
4880
+ margin: 0 0 8px 0;
4881
+ padding-left: 16px;
4882
+ }
4883
+ .dtm-modal-body li {
4884
+ margin-bottom: 4px;
4885
+ }
4886
+ .dtm-modal-body code {
4887
+ background: var(--dtm-deep);
4888
+ color: var(--dtm-accent);
4889
+ padding: 1px 4px;
4890
+ font-family: var(--dtm-font);
4891
+ font-size: 12px;
4892
+ }
4893
+ .dtm-modal-body pre {
4894
+ background: var(--dtm-deep);
4895
+ color: var(--dtm-success);
4896
+ padding: 8px;
4897
+ border: 1px solid var(--dtm-border2);
4898
+ margin: 6px 0;
4899
+ overflow-x: auto;
4900
+ font-family: var(--dtm-font);
4901
+ font-size: 12px;
4902
+ }
4903
+
4758
4904
  .dtm-hidden { display: none !important; }
4759
4905
  .dtm-grow { flex: 1 1 auto; }
4760
4906
  .dtm-lyric-icon {
@@ -5024,6 +5170,85 @@ var VOICE_IMAGES = {
5024
5170
  };
5025
5171
 
5026
5172
  // src/daw.ts
5173
+ var CHORD_INFO_HTML = `
5174
+ <div class="dtm-modal-body-content">
5175
+ <h4>1. \u57FA\u672C\u306E\u66F8\u304D\u65B9</h4>
5176
+ <p>\u30B3\u30FC\u30C9\u540D\uFF08\u548C\u97F3\u8A18\u53F7\uFF09\u3092\u7E26\u7DDA <code>|</code>\u3001\u30B9\u30DA\u30FC\u30B9\u3001\u307E\u305F\u306F\u30AB\u30F3\u30DE\u3067\u533A\u5207\u3063\u3066\u5165\u529B\u3057\u307E\u3059\u3002\u7E26\u7DDA\u3067\u533A\u5207\u308B\u30681\u5C0F\u7BC0\u3054\u3068\u306E\u914D\u7F6E\u306B\u306A\u308A\u307E\u3059\u3002</p>
5177
+ <pre>\u4F8B: C | G | Am | F</pre>
5178
+
5179
+ <h4>2. 1\u5C0F\u7BC0\u306B\u8907\u6570\u30B3\u30FC\u30C9\u3092\u5165\u308C\u308B</h4>
5180
+ <p>\u5C0F\u7BC0\u306E\u533A\u5207\u308A\uFF08\u7E26\u7DDA <code>|</code>\uFF09\u306E\u4E2D\u306B\u3001\u30B9\u30DA\u30FC\u30B9\u533A\u5207\u308A\u3067\u30B3\u30FC\u30C9\u3092\u4E26\u3079\u307E\u3059\u3002\u7B49\u9593\u9694\u306B\u914D\u7F6E\u3055\u308C\u307E\u3059\u3002</p>
5181
+ <pre>\u4F8B: C G | Am F</pre>
5182
+ <p style="margin-top:4px;"><small>\uFF081\u5C0F\u7BC0\u76EE\uFF1A\u524D\u534AC\u30FB\u5F8C\u534AG\u30012\u5C0F\u7BC0\u76EE\uFF1A\u524D\u534AAm\u30FB\u5F8C\u534AF\uFF09</small></p>
5183
+
5184
+ <h4>3. \u5BFE\u5FDC\u30B3\u30FC\u30C9\u540D</h4>
5185
+ <ul>
5186
+ <li>\u30E1\u30B8\u30E3\u30FC / \u30DE\u30A4\u30CA\u30FC: <code>C</code>, <code>Dm</code>, <code>Am</code> \u306A\u3069</li>
5187
+ <li>\u30BB\u30D6\u30F3\u30B9: <code>C7</code>, <code>Am7</code>, <code>FM7</code> \u306A\u3069</li>
5188
+ <li>\u305D\u306E\u4ED6: <code>Csus4</code>, <code>Cdim</code>, <code>Caug</code>, <code>Cadd9</code> \u306A\u3069</li>
5189
+ </ul>
5190
+
5191
+ <h4>4. \u6F14\u594F\u30D1\u30BF\u30FC\u30F3</h4>
5192
+ <ul>
5193
+ <li><strong>\u30D6\u30ED\u30C3\u30AF</strong>: \u548C\u97F3\u306E\u69CB\u6210\u97F3\u3092\u3059\u3079\u3066\u540C\u6642\u306B\u4F38\u3070\u3057\u3066\u6F14\u594F\u3057\u307E\u3059\u3002</li>
5194
+ <li><strong>\u30A2\u30EB\u30DA\u30B8\u30AA</strong>: \u548C\u97F3\u306E\u69CB\u6210\u97F3\u3092\u4F4E\u3044\u9806\u306B\u5206\u6563\u3057\u3066\u6F14\u594F\u3057\u307E\u3059\u3002</li>
5195
+ <li><strong>\u30A2\u30EB\u30DA\u30B8\u30AA\uFF08\u30B8\u30E3\u30E9\u30FC\u30F3\uFF09</strong>: \u7D20\u65E9\u304F\u30A2\u30EB\u30DA\u30B8\u30AA\u3092\u9CF4\u3089\u3057\u307E\u3059\u3002</li>
5196
+ <li><strong>\u88CF\u6253\u3061</strong>: \u5404\u62CD\u306E\u88CF\uFF088\u5206\u88CF\uFF09\u306E\u30BF\u30A4\u30DF\u30F3\u30B0\u3067\u30B3\u30FC\u30C9\u3092\u523B\u307F\u307E\u3059\u3002</li>
5197
+ <li><strong>\u30E4\u30C4\u30E1\u7A74</strong>: \u30EA\u30BA\u30DF\u30AB\u30EB\u306A\u30D4\u30B3\u30D4\u30B3\u30B2\u30FC\u30E0\u98A8\u306E\u4F34\u594F\u30D1\u30BF\u30FC\u30F3\u3067\u3059\u3002</li>
5198
+ <li><strong>\u4EA4\u4E92\u594F</strong>: \u30EB\u30FC\u30C8\u97F3\uFF08\u4F4E\u97F3\uFF09\u3068\u30B3\u30FC\u30C9\u69CB\u6210\u97F3\uFF08\u9AD8\u97F3\uFF09\u3092\u4EA4\u4E92\u306B\u523B\u307F\u307E\u3059\u3002</li>
5199
+ </ul>
5200
+ </div>
5201
+ `;
5202
+ var MML_INFO_HTML = `
5203
+ <div class="dtm-modal-body-content">
5204
+ <h4>1. \u97F3\u7B26\u3068\u4F11\u7B26</h4>
5205
+ <p><code>c</code>(\u30C9) <code>d</code>(\u30EC) <code>e</code>(\u30DF) <code>f</code>(\u30D5\u30A1) <code>g</code>(\u30BD) <code>a</code>(\u30E9) <code>b</code>(\u30B7) \u306E\u30A2\u30EB\u30D5\u30A1\u30D9\u30C3\u30C8\u3067\u8868\u3057\u307E\u3059\u3002</p>
5206
+ <ul>
5207
+ <li>\u534A\u97F3\u4E0A\u3052\u308B: <code>c#</code> \u307E\u305F\u306F <code>c+</code></li>
5208
+ <li>\u534A\u97F3\u4E0B\u3052\u308B: <code>d-</code></li>
5209
+ <li>\u4F11\u7B26: <code>r</code></li>
5210
+ </ul>
5211
+
5212
+ <h4>2. \u97F3\u306E\u9577\u3055</h4>
5213
+ <p>\u97F3\u540D\u3084\u4F11\u7B26\u306E\u5F8C\u306B\u6570\u5024\u3067\u6307\u5B9A\u3057\u307E\u3059\uFF08\u4F8B: <code>4</code> = 4\u5206\u97F3\u7B26, <code>8</code> = 8\u5206\u97F3\u7B26, <code>16</code> = 16\u5206\u97F3\u7B26\uFF09\u3002</p>
5214
+ <ul>
5215
+ <li><code>c4</code> : 4\u5206\u97F3\u7B26\u306E\u30C9</li>
5216
+ <li><code>r8</code> : 8\u5206\u4F11\u7B26</li>
5217
+ <li><code>c4.</code> : \u4ED8\u70B94\u5206\u97F3\u7B26\u306E\u30C9\uFF08\u9577\u3055\u30921.5\u500D\u306B\uFF09</li>
5218
+ <li>\u6570\u5024\u3092\u7701\u7565\u3059\u308B\u3068\u3001<code>l</code> \u30B3\u30DE\u30F3\u30C9\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u30C7\u30D5\u30A9\u30EB\u30C8\u9577\uFF08\u901A\u5E3816\u5206\uFF09\u306B\u306A\u308A\u307E\u3059\u3002</li>
5219
+ </ul>
5220
+
5221
+ <h4>3. \u30AA\u30AF\u30BF\u30FC\u30D6\uFF08\u97F3\u306E\u9AD8\u3055\uFF09</h4>
5222
+ <ul>
5223
+ <li><code>o4</code>, <code>o5</code> : \u9AD8\u3055\u3092\u76F4\u63A5\u6307\u5B9A\uFF08\u3075\u3064\u3046\u306F o4 \u304B o5\uFF09</li>
5224
+ <li><code>&gt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u308B</li>
5225
+ <li><code>&lt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0B\u3052\u308B</li>
5226
+ </ul>
5227
+
5228
+ <h4>4. \u30C6\u30F3\u30DD</h4>
5229
+ <ul>
5230
+ <li><code>t120</code> : \u66F2\u306E\u901F\u3055\u3092BPM120\u306B\u6307\u5B9A\u3002\u203B\u30E1\u30ED\u30C7\u30A3\uFF08@0\uFF09\u306E\u30C6\u30F3\u30DD\u6307\u5B9A\u304C\u66F2\u5168\u4F53\u306B\u53CD\u6620\u3055\u308C\u307E\u3059\u3002</li>
5231
+ </ul>
5232
+
5233
+ <h4>5. \u548C\u97F3</h4>
5234
+ <p>\u97F3\u7B26\u3092 <code>[</code> \u3068 <code>]</code> \u3067\u56F2\u3080\u3068\u540C\u6642\u306B\u767A\u97F3\u3057\u307E\u3059\u3002</p>
5235
+ <pre>\u4F8B: [ceg]4 \uFF08\u30C9\u30FB\u30DF\u30FB\u30BD\u30924\u5206\u97F3\u7B26\u3067\u540C\u6642\u306B\u767A\u97F3\uFF09</pre>
5236
+
5237
+ <h4>6. \u30C8\u30E9\u30C3\u30AF\u306E\u533A\u5207\u308A</h4>
5238
+ <p><code>;</code> \u307E\u305F\u306F <code>@0</code>\u301C<code>@3</code> \u3067\u30C8\u30E9\u30C3\u30AF\u3092\u5207\u308A\u66FF\u3048\u307E\u3059\u3002</p>
5239
+ <ul>
5240
+ <li><code>@0</code>: \u30E1\u30ED\u30C7\u30A3</li>
5241
+ <li><code>@1</code>: \u30B5\u30D6\u30E1\u30ED</li>
5242
+ <li><code>@2</code>: \u30D9\u30FC\u30B9</li>
5243
+ <li><code>@3</code>: \u4F34\u594F</li>
5244
+ </ul>
5245
+
5246
+ <h4>7. \u6B4C\u58F0\u30FB\u6B4C\u8A5E\u5165\u529B</h4>
5247
+ <p><code>@@&lt;\u30C8\u30E9\u30C3\u30AF\u756A\u53F7&gt; &lt;\u97F3\u6E90\u540D&gt; &lt;\u6B4C\u8A5E&gt;</code> \u306E\u5F62\u5F0F\u3067\u3001\u97F3\u7B26\u3068\u540C\u671F\u3059\u308B\u6B4C\u8A5E\u3092\u5165\u529B\u3067\u304D\u307E\u3059\u3002</p>
5248
+ <pre>\u4F8B: @@0 klatt \u3061\u3087\u3046\u3061\u3087\u3046\u306A\u306E\u306F\u306B\u3068\u307E\u308C</pre>
5249
+ <p style="margin-top:4px;"><small>\uFF08\u97F3\u6E90\u540D\u306F <code>klatt</code> \u3084 <code>roze</code>, <code>teto</code> \u306A\u3069\u306E\u97F3\u58F0\u30E2\u30C7\u30EB\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\uFF09</small></p>
5250
+ </div>
5251
+ `;
5027
5252
  var BASE_STEP_WIDTH = 0.5;
5028
5253
  var BASE_KEY_HEIGHT = 15;
5029
5254
  var TRACKS_SIMPLE = [
@@ -5276,6 +5501,7 @@ var mountDAW = (target, options = {}) => {
5276
5501
  return map;
5277
5502
  };
5278
5503
  const getActive = () => trackStates.find((t) => t.config.id === activeTrackId) ?? trackStates[0];
5504
+ let showModal;
5279
5505
  const getMaxNoteStep = () => {
5280
5506
  let maxStep = renderConfig.stepsPerBar * 4;
5281
5507
  for (const t of trackStates) {
@@ -5968,11 +6194,13 @@ var mountDAW = (target, options = {}) => {
5968
6194
  active.core.setVolume(active.volume);
5969
6195
  volLabel.textContent = String(active.volume);
5970
6196
  });
5971
- const lyricDiv = document.createElement("div");
5972
- lyricDiv.className = "dtm-row";
5973
- lyricDiv.style.flexDirection = "column";
5974
- lyricDiv.style.alignItems = "stretch";
5975
- lyricDiv.innerHTML = `
6197
+ const isAdvanced = trackStates.length > TRACKS_SIMPLE.length;
6198
+ if (isAdvanced || active.config.id !== "chord") {
6199
+ const lyricDiv = document.createElement("div");
6200
+ lyricDiv.className = "dtm-row";
6201
+ lyricDiv.style.flexDirection = "column";
6202
+ lyricDiv.style.alignItems = "stretch";
6203
+ lyricDiv.innerHTML = `
5976
6204
  <div class="dtm-row">
5977
6205
  <span class="dtm-label">\u266A \u6B4C\u8A5E</span>
5978
6206
  <select class="dtm-select" data-dtm="lyric-model" aria-label="\u6B4C\u5531\u30E2\u30C7\u30EB"></select>
@@ -6004,144 +6232,134 @@ var mountDAW = (target, options = {}) => {
6004
6232
  </div>
6005
6233
  <textarea class="dtm-textarea" data-dtm="lyric-input" rows="2" placeholder="\u3072\u3089\u304C\u306A\u30FB\u30AB\u30BF\u30AB\u30CA\u3067\u6B4C\u8A5E\uFF08\u4F8B: \u3069\u308C\u307F\u3075\u3041\u305D\u3089\u3057\u3069\uFF09"></textarea>
6006
6234
  </div>`;
6007
- refs.trackBody.appendChild(lyricDiv);
6008
- const lyricModelSel = lyricDiv.querySelector(
6009
- '[data-dtm="lyric-model"]'
6010
- );
6011
- const lyricOctaveSel = lyricDiv.querySelector(
6012
- '[data-dtm="lyric-octave"]'
6013
- );
6014
- const lyricIcon = lyricDiv.querySelector(
6015
- '[data-dtm="lyric-icon"]'
6016
- );
6017
- const lyricBody = lyricDiv.querySelector(
6018
- '[data-dtm="lyric-body"]'
6019
- );
6020
- const lyricInput = lyricDiv.querySelector(
6021
- '[data-dtm="lyric-input"]'
6022
- );
6023
- const lyricCount = lyricDiv.querySelector(
6024
- '[data-dtm="lyric-count"]'
6025
- );
6026
- const lyricVol = lyricDiv.querySelector(
6027
- '[data-dtm="lyric-vol"]'
6028
- );
6029
- const lyricVolLabel = lyricDiv.querySelector(
6030
- '[data-dtm="lyric-vol-label"]'
6031
- );
6032
- const lyricPan = lyricDiv.querySelector(
6033
- '[data-dtm="lyric-pan"]'
6034
- );
6035
- const lyricPanLabel = lyricDiv.querySelector(
6036
- '[data-dtm="lyric-pan-label"]'
6037
- );
6038
- const lyricTerms = lyricDiv.querySelector(
6039
- '[data-dtm="lyric-terms"]'
6040
- );
6041
- const lyricTermsLink = lyricDiv.querySelector(
6042
- '[data-dtm="lyric-terms-link"]'
6043
- );
6044
- const fmtPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
6045
- const addOpt = (value, label) => {
6046
- const o = document.createElement("option");
6047
- o.value = value;
6048
- o.textContent = label;
6049
- lyricModelSel.appendChild(o);
6050
- };
6051
- addOpt("", "\u306A\u3057");
6052
- for (const m of LYRIC_MODELS) addOpt(m, lyricModelLabel(m));
6053
- if (active.lyricModel && !LYRIC_MODELS.includes(active.lyricModel)) {
6054
- addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
6055
- }
6056
- lyricModelSel.value = active.lyricModel;
6057
- lyricOctaveSel.value = String(active.vocalOctave);
6058
- lyricInput.value = active.lyrics;
6059
- lyricVol.value = String(active.vocalVolume);
6060
- lyricVolLabel.textContent = String(active.vocalVolume);
6061
- lyricPan.value = String(active.vocalPan);
6062
- lyricPanLabel.textContent = fmtPan(active.vocalPan);
6063
- const updateLyricCount = () => {
6064
- const n = normalizeLyrics(lyricInput.value).length;
6065
- lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
6066
- };
6067
- const syncLyricTerms = () => {
6068
- const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6069
- if (url) {
6070
- const label = lyricModelLabel(active.lyricModel);
6071
- lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
6072
- lyricTermsLink.href = url;
6073
- lyricTerms.classList.remove("dtm-hidden");
6074
- } else {
6075
- lyricTerms.classList.add("dtm-hidden");
6076
- }
6077
- };
6078
- const syncLyricIcon = () => {
6079
- const imgKey = active.lyricModel ? VOICE_IMAGE_KEY[active.lyricModel.toLowerCase()] : void 0;
6080
- const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
6081
- if (src) {
6082
- lyricIcon.src = src;
6083
- lyricIcon.classList.remove("dtm-hidden");
6084
- } else {
6085
- lyricIcon.removeAttribute("src");
6086
- lyricIcon.classList.add("dtm-hidden");
6235
+ refs.trackBody.appendChild(lyricDiv);
6236
+ const lyricModelSel = lyricDiv.querySelector(
6237
+ '[data-dtm="lyric-model"]'
6238
+ );
6239
+ const lyricOctaveSel = lyricDiv.querySelector(
6240
+ '[data-dtm="lyric-octave"]'
6241
+ );
6242
+ const lyricIcon = lyricDiv.querySelector(
6243
+ '[data-dtm="lyric-icon"]'
6244
+ );
6245
+ const lyricBody = lyricDiv.querySelector(
6246
+ '[data-dtm="lyric-body"]'
6247
+ );
6248
+ const lyricInput = lyricDiv.querySelector(
6249
+ '[data-dtm="lyric-input"]'
6250
+ );
6251
+ const lyricCount = lyricDiv.querySelector(
6252
+ '[data-dtm="lyric-count"]'
6253
+ );
6254
+ const lyricVol = lyricDiv.querySelector(
6255
+ '[data-dtm="lyric-vol"]'
6256
+ );
6257
+ const lyricVolLabel = lyricDiv.querySelector(
6258
+ '[data-dtm="lyric-vol-label"]'
6259
+ );
6260
+ const lyricPan = lyricDiv.querySelector(
6261
+ '[data-dtm="lyric-pan"]'
6262
+ );
6263
+ const lyricPanLabel = lyricDiv.querySelector(
6264
+ '[data-dtm="lyric-pan-label"]'
6265
+ );
6266
+ const lyricTerms = lyricDiv.querySelector(
6267
+ '[data-dtm="lyric-terms"]'
6268
+ );
6269
+ const lyricTermsLink = lyricDiv.querySelector(
6270
+ '[data-dtm="lyric-terms-link"]'
6271
+ );
6272
+ const fmtPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
6273
+ const addOpt = (value, label) => {
6274
+ const o = document.createElement("option");
6275
+ o.value = value;
6276
+ o.textContent = label;
6277
+ lyricModelSel.appendChild(o);
6278
+ };
6279
+ addOpt("", "\u306A\u3057");
6280
+ for (const m of LYRIC_MODELS) addOpt(m, lyricModelLabel(m));
6281
+ if (active.lyricModel && !LYRIC_MODELS.includes(active.lyricModel)) {
6282
+ addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
6087
6283
  }
6088
- };
6089
- const syncLyricVisibility = () => {
6090
- lyricBody.style.display = active.lyricModel ? "" : "none";
6091
- lyricOctaveSel.style.display = active.lyricModel ? "" : "none";
6092
- updateLyricCount();
6093
- syncLyricTerms();
6094
- syncLyricIcon();
6095
- };
6096
- syncLyricVisibility();
6097
- lyricModelSel.addEventListener("change", () => {
6098
- active.lyricModel = lyricModelSel.value;
6099
- syncLyricVisibility();
6100
- });
6101
- lyricOctaveSel.addEventListener("change", () => {
6102
- active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
6103
- });
6104
- lyricInput.addEventListener("input", () => {
6105
- active.lyrics = lyricInput.value;
6106
- updateLyricCount();
6107
- });
6108
- lyricVol.addEventListener("input", () => {
6109
- active.vocalVolume = Number.parseInt(lyricVol.value, 10);
6110
- lyricVolLabel.textContent = lyricVol.value;
6111
- });
6112
- lyricPan.addEventListener("input", () => {
6113
- active.vocalPan = Number.parseInt(lyricPan.value, 10);
6284
+ lyricModelSel.value = active.lyricModel;
6285
+ lyricOctaveSel.value = String(active.vocalOctave);
6286
+ lyricInput.value = active.lyrics;
6287
+ lyricVol.value = String(active.vocalVolume);
6288
+ lyricVolLabel.textContent = String(active.vocalVolume);
6289
+ lyricPan.value = String(active.vocalPan);
6114
6290
  lyricPanLabel.textContent = fmtPan(active.vocalPan);
6115
- });
6116
- lyricPanLabel.style.cursor = "pointer";
6117
- lyricPanLabel.title = "\u30BF\u30C3\u30D7\u3067\u4E2D\u592E(C)\u3078";
6118
- lyricPanLabel.addEventListener("click", () => {
6119
- active.vocalPan = 64;
6120
- lyricPan.value = "64";
6121
- lyricPanLabel.textContent = fmtPan(64);
6122
- });
6291
+ const updateLyricCount = () => {
6292
+ const n = normalizeLyrics(lyricInput.value).length;
6293
+ lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
6294
+ };
6295
+ const syncLyricTerms = () => {
6296
+ const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6297
+ if (url) {
6298
+ const label = lyricModelLabel(active.lyricModel);
6299
+ lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
6300
+ lyricTermsLink.href = url;
6301
+ lyricTerms.classList.remove("dtm-hidden");
6302
+ } else {
6303
+ lyricTerms.classList.add("dtm-hidden");
6304
+ }
6305
+ };
6306
+ const syncLyricIcon = () => {
6307
+ const imgKey = active.lyricModel ? VOICE_IMAGE_KEY[active.lyricModel.toLowerCase()] : void 0;
6308
+ const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
6309
+ if (src) {
6310
+ lyricIcon.src = src;
6311
+ lyricIcon.classList.remove("dtm-hidden");
6312
+ } else {
6313
+ lyricIcon.removeAttribute("src");
6314
+ lyricIcon.classList.add("dtm-hidden");
6315
+ }
6316
+ };
6317
+ const syncLyricVisibility = () => {
6318
+ lyricBody.style.display = active.lyricModel ? "" : "none";
6319
+ lyricOctaveSel.style.display = active.lyricModel ? "" : "none";
6320
+ updateLyricCount();
6321
+ syncLyricTerms();
6322
+ syncLyricIcon();
6323
+ };
6324
+ syncLyricVisibility();
6325
+ lyricModelSel.addEventListener("change", () => {
6326
+ active.lyricModel = lyricModelSel.value;
6327
+ syncLyricVisibility();
6328
+ });
6329
+ lyricOctaveSel.addEventListener("change", () => {
6330
+ active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
6331
+ });
6332
+ lyricInput.addEventListener("input", () => {
6333
+ active.lyrics = lyricInput.value;
6334
+ updateLyricCount();
6335
+ });
6336
+ lyricVol.addEventListener("input", () => {
6337
+ active.vocalVolume = Number.parseInt(lyricVol.value, 10);
6338
+ lyricVolLabel.textContent = lyricVol.value;
6339
+ });
6340
+ lyricPan.addEventListener("input", () => {
6341
+ active.vocalPan = Number.parseInt(lyricPan.value, 10);
6342
+ lyricPanLabel.textContent = fmtPan(active.vocalPan);
6343
+ });
6344
+ lyricPanLabel.style.cursor = "pointer";
6345
+ lyricPanLabel.title = "\u30BF\u30C3\u30D7\u3067\u4E2D\u592E(C)\u3078";
6346
+ lyricPanLabel.addEventListener("click", () => {
6347
+ active.vocalPan = 64;
6348
+ lyricPan.value = "64";
6349
+ lyricPanLabel.textContent = fmtPan(64);
6350
+ });
6351
+ }
6123
6352
  if (active.config.id === "chord" && showChord) {
6124
6353
  const div = document.createElement("div");
6125
6354
  div.className = "dtm-row";
6126
6355
  div.style.flexDirection = "column";
6127
6356
  div.style.alignItems = "stretch";
6128
- const roots = [
6129
- "C",
6130
- "C#",
6131
- "D",
6132
- "D#",
6133
- "E",
6134
- "F",
6135
- "F#",
6136
- "G",
6137
- "G#",
6138
- "A",
6139
- "A#",
6140
- "B"
6141
- ];
6142
6357
  div.innerHTML = `
6143
- <div class="dtm-row">
6144
- <span class="dtm-label">\u548C\u97F3</span>
6358
+ <div class="dtm-row" style="justify-content: space-between; align-items: center;">
6359
+ <div style="display: inline-flex; align-items: center; gap: 6px;">
6360
+ <span class="dtm-label">\u548C\u97F3</span>
6361
+ <button class="dtm-infobtn" data-dtm="chord-info" title="\u30B3\u30FC\u30C9\u9032\u884C\u306E\u66F8\u304D\u65B9\u89E3\u8AAC">${icon("info", 12)}</button>
6362
+ </div>
6145
6363
  <select class="dtm-select" data-dtm="chord-pattern">
6146
6364
  <option value="block">\u30D6\u30ED\u30C3\u30AF</option>
6147
6365
  <option value="arpeggio">\u30A2\u30EB\u30DA\u30B8\u30AA</option>
@@ -6150,32 +6368,28 @@ var mountDAW = (target, options = {}) => {
6150
6368
  <option value="yatsume">\u30E4\u30C4\u30E1\u7A74</option>
6151
6369
  <option value="alternating">\u4EA4\u4E92\u594F</option>
6152
6370
  </select>
6153
- <select class="dtm-select" data-dtm="chord-root">
6154
- ${roots.map((r, i) => `<option value="${i}">${r}</option>`).join("")}
6155
- </select>
6156
- <button class="dtm-btn dtm-btn--primary" data-dtm="chord-apply">\u9069\u7528</button>
6157
6371
  </div>
6158
- <textarea class="dtm-textarea" data-dtm="chord-input" placeholder="\u4F8B: C|G|Am|Em|F|C|F|G">${active.savedChordInput}</textarea>`;
6372
+ <div class="dtm-row">
6373
+ <textarea class="dtm-textarea dtm-grow" data-dtm="chord-input" placeholder="\u4F8B: C|G|Am|Em|F|C|F|G">${active.savedChordInput}</textarea>
6374
+ <button class="dtm-btn dtm-btn--primary" data-dtm="chord-apply">\u9069\u7528</button>
6375
+ </div>`;
6159
6376
  refs.trackBody.appendChild(div);
6160
6377
  const patternSel = div.querySelector(
6161
6378
  '[data-dtm="chord-pattern"]'
6162
6379
  );
6163
- const rootSel = div.querySelector(
6164
- '[data-dtm="chord-root"]'
6165
- );
6166
6380
  const input = div.querySelector(
6167
6381
  '[data-dtm="chord-input"]'
6168
6382
  );
6169
6383
  patternSel.value = active.savedChordPattern;
6170
- rootSel.value = String(active.savedChordRoot);
6171
6384
  const save = () => {
6172
6385
  active.savedChordInput = input.value;
6173
6386
  active.savedChordPattern = patternSel.value;
6174
- active.savedChordRoot = Number.parseInt(rootSel.value, 10);
6175
6387
  };
6176
6388
  patternSel.addEventListener("change", save);
6177
- rootSel.addEventListener("change", save);
6178
6389
  input.addEventListener("input", save);
6390
+ div.querySelector('[data-dtm="chord-info"]').addEventListener("click", () => {
6391
+ showModal("\u30B3\u30FC\u30C9\u9032\u884C\u306E\u81EA\u52D5\u5165\u529B\u89E3\u8AAC", CHORD_INFO_HTML);
6392
+ });
6179
6393
  div.querySelector('[data-dtm="chord-apply"]').addEventListener("click", () => {
6180
6394
  save();
6181
6395
  applyChord();
@@ -6613,6 +6827,22 @@ var mountDAW = (target, options = {}) => {
6613
6827
  "click",
6614
6828
  () => overlayDuring(() => loadMML(refs.mmlInput.value))
6615
6829
  );
6830
+ showModal = (title, bodyHTML) => {
6831
+ refs.modalTitle.textContent = title;
6832
+ refs.modalBody.innerHTML = bodyHTML;
6833
+ refs.modalOverlay.removeAttribute("hidden");
6834
+ };
6835
+ refs.modalClose.addEventListener("click", () => {
6836
+ refs.modalOverlay.setAttribute("hidden", "");
6837
+ });
6838
+ refs.modalOverlay.addEventListener("click", (e) => {
6839
+ if (e.target === refs.modalOverlay) {
6840
+ refs.modalOverlay.setAttribute("hidden", "");
6841
+ }
6842
+ });
6843
+ refs.mmlInfoBtn.addEventListener("click", () => {
6844
+ showModal("MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC", MML_INFO_HTML);
6845
+ });
6616
6846
  refs.shiftApplyBtn.addEventListener(
6617
6847
  "click",
6618
6848
  () => overlayDuring(() => {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "onjmin",
3
3
  "license": "MIT",
4
4
  "name": "@onjmin/dtm",
5
- "version": "0.1.11",
5
+ "version": "0.1.12",
6
6
  "description": "MMLを中間言語に用いた、モバイルファーストなDAW / ピアノロール打ち込みコンポーネント",
7
7
  "homepage": "https://onjmin.github.io/dtm",
8
8
  "repository": {