@onjmin/dtm 0.1.75 → 0.1.77
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/README.md +3 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +147 -116
- package/dist/index.mjs +147 -116
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4836,6 +4836,7 @@ var DAW_CSS = `
|
|
|
4836
4836
|
gap: 8px;
|
|
4837
4837
|
}
|
|
4838
4838
|
.dtm-player-seek {
|
|
4839
|
+
--fill: 0%;
|
|
4839
4840
|
flex: 1 1 auto;
|
|
4840
4841
|
min-width: 0;
|
|
4841
4842
|
height: 12px;
|
|
@@ -4846,9 +4847,14 @@ var DAW_CSS = `
|
|
|
4846
4847
|
appearance: none;
|
|
4847
4848
|
}
|
|
4848
4849
|
.dtm-player-seek:disabled { cursor: default; opacity: 0.4; }
|
|
4850
|
+
/* \u518D\u751F\u6E08\u307F\u533A\u9593\u3092YouTube\u98A8\u306B\u8272\u5857\u308A\u3059\u308B\uFF08--fill \u306F\u518D\u751F\u4F4D\u7F6E\u306B\u5FDC\u3058\u3066JS\u304B\u3089\u8A2D\u5B9A\uFF09 */
|
|
4849
4851
|
.dtm-player-seek::-webkit-slider-runnable-track {
|
|
4850
4852
|
height: 6px;
|
|
4851
|
-
background:
|
|
4853
|
+
background: linear-gradient(
|
|
4854
|
+
to right,
|
|
4855
|
+
var(--dtm-primary) var(--fill),
|
|
4856
|
+
var(--dtm-border2) var(--fill)
|
|
4857
|
+
);
|
|
4852
4858
|
border: 2px solid var(--c-black);
|
|
4853
4859
|
}
|
|
4854
4860
|
.dtm-player-seek::-moz-range-track {
|
|
@@ -4856,6 +4862,12 @@ var DAW_CSS = `
|
|
|
4856
4862
|
background: var(--dtm-border2);
|
|
4857
4863
|
border: 2px solid var(--c-black);
|
|
4858
4864
|
}
|
|
4865
|
+
.dtm-player-seek::-moz-range-progress {
|
|
4866
|
+
height: 6px;
|
|
4867
|
+
background: var(--dtm-primary);
|
|
4868
|
+
border: 2px solid var(--c-black);
|
|
4869
|
+
border-right: none;
|
|
4870
|
+
}
|
|
4859
4871
|
.dtm-player-seek::-webkit-slider-thumb {
|
|
4860
4872
|
-webkit-appearance: none;
|
|
4861
4873
|
width: 12px;
|
|
@@ -5153,18 +5165,19 @@ var DAW_CSS = `
|
|
|
5153
5165
|
}
|
|
5154
5166
|
|
|
5155
5167
|
/* \u2500\u2500\u2500 \u30B3\u30FC\u30C9\u9032\u884C\u30D7\u30EC\u30A4\u30E4\u30FC \u2500\u2500\u2500 */
|
|
5168
|
+
/* MML\u518D\u751F\u5C02\u7528\u30D7\u30EC\u30A4\u30E4\u30FC\uFF08.dtm-player\uFF09\u3068\u67A0\u30C7\u30B6\u30A4\u30F3\u3092\u63C3\u3048\u308B */
|
|
5156
5169
|
.dtm-chord-player {
|
|
5170
|
+
display: flex;
|
|
5171
|
+
flex-direction: column;
|
|
5172
|
+
gap: var(--dtm-gap);
|
|
5173
|
+
padding: var(--dtm-gap);
|
|
5157
5174
|
font-family: var(--dtm-font);
|
|
5158
5175
|
font-size: 13px;
|
|
5159
5176
|
letter-spacing: .06em;
|
|
5160
5177
|
color: var(--dtm-text);
|
|
5161
|
-
background: var(--dtm-
|
|
5162
|
-
border: 2px solid var(--
|
|
5163
|
-
box-shadow:
|
|
5164
|
-
inset 0 0 0 2px var(--c-black),
|
|
5165
|
-
0 0 0 2px var(--dtm-border),
|
|
5166
|
-
4px 4px 0 var(--c-black);
|
|
5167
|
-
overflow: hidden;
|
|
5178
|
+
background: var(--dtm-deep);
|
|
5179
|
+
border: 2px solid var(--dtm-border2);
|
|
5180
|
+
box-shadow: 4px 4px 0 var(--c-black);
|
|
5168
5181
|
image-rendering: pixelated;
|
|
5169
5182
|
-webkit-font-smoothing: none;
|
|
5170
5183
|
}
|
|
@@ -5172,14 +5185,12 @@ var DAW_CSS = `
|
|
|
5172
5185
|
.dtm-chord-player *::before,
|
|
5173
5186
|
.dtm-chord-player *::after { box-sizing: border-box; }
|
|
5174
5187
|
|
|
5175
|
-
/* \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC */
|
|
5188
|
+
/* \u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30D0\u30FC \u2014 MML\u518D\u751F\u5C02\u7528\u30D7\u30EC\u30A4\u30E4\u30FC\u306E .dtm-player-head \u3068\u63C3\u3048\u308B */
|
|
5176
5189
|
.dtm-cp-ctrl {
|
|
5177
5190
|
display: flex;
|
|
5178
5191
|
align-items: center;
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
background: var(--dtm-deep);
|
|
5182
|
-
border-bottom: 2px solid var(--c-black);
|
|
5192
|
+
flex-wrap: wrap;
|
|
5193
|
+
gap: 8px;
|
|
5183
5194
|
}
|
|
5184
5195
|
|
|
5185
5196
|
/* \u30EB\u30FC\u30D7\u5207\u66FF\u30DC\u30BF\u30F3 */
|
|
@@ -5204,38 +5215,13 @@ var DAW_CSS = `
|
|
|
5204
5215
|
box-shadow: 2px 2px 0 var(--c-black);
|
|
5205
5216
|
}
|
|
5206
5217
|
|
|
5207
|
-
/* \u30E1\u30BF\u60C5\u5831 (BPM
|
|
5218
|
+
/* \u30E1\u30BF\u60C5\u5831 (BPM) */
|
|
5208
5219
|
.dtm-cp-meta {
|
|
5209
5220
|
font-size: 11px;
|
|
5210
5221
|
text-transform: uppercase;
|
|
5211
5222
|
letter-spacing: .12em;
|
|
5212
5223
|
color: var(--dtm-muted);
|
|
5213
5224
|
}
|
|
5214
|
-
.dtm-cp-time {
|
|
5215
|
-
margin-left: auto;
|
|
5216
|
-
font-size: 11px;
|
|
5217
|
-
font-family: var(--dtm-font);
|
|
5218
|
-
color: var(--dtm-muted);
|
|
5219
|
-
letter-spacing: .1em;
|
|
5220
|
-
}
|
|
5221
|
-
|
|
5222
|
-
/* \u30D7\u30ED\u30B0\u30EC\u30B9\u30D0\u30FC \u2014 \u30C9\u30C3\u30C8\u7D75\u98A8\u306E\u30BB\u30B0\u30E1\u30F3\u30C8\u5857\u308A\u3002\u30AF\u30EA\u30C3\u30AF\u3067\u30B7\u30FC\u30AF */
|
|
5223
|
-
.dtm-cp-progress {
|
|
5224
|
-
height: 14px;
|
|
5225
|
-
background: var(--dtm-deep);
|
|
5226
|
-
border-bottom: 2px solid var(--c-black);
|
|
5227
|
-
cursor: pointer;
|
|
5228
|
-
}
|
|
5229
|
-
.dtm-cp-progress-fill {
|
|
5230
|
-
height: 100%;
|
|
5231
|
-
width: 0%;
|
|
5232
|
-
background: repeating-linear-gradient(
|
|
5233
|
-
90deg,
|
|
5234
|
-
var(--dtm-primary) 0, var(--dtm-primary) 6px,
|
|
5235
|
-
var(--c-navy) 6px, var(--c-navy) 8px
|
|
5236
|
-
);
|
|
5237
|
-
}
|
|
5238
|
-
.dtm-cp-progress-fill--on { border-right: 2px solid var(--c-white); }
|
|
5239
5225
|
|
|
5240
5226
|
/* \u30B9\u30AF\u30ED\u30FC\u30EB\u30A8\u30EA\u30A2 */
|
|
5241
5227
|
.dtm-cp-scroll {
|
|
@@ -6173,6 +6159,12 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6173
6159
|
timeEl.textContent = "0:00 / 0:00";
|
|
6174
6160
|
seekRow.append(seekInput, timeEl);
|
|
6175
6161
|
root.appendChild(seekRow);
|
|
6162
|
+
const syncSeekFill = () => {
|
|
6163
|
+
const max = Number(seekInput.max) || 1;
|
|
6164
|
+
const pct = Number(seekInput.value) / max * 100;
|
|
6165
|
+
seekInput.style.setProperty("--fill", `${pct}%`);
|
|
6166
|
+
};
|
|
6167
|
+
syncSeekFill();
|
|
6176
6168
|
const formatTime = (step) => {
|
|
6177
6169
|
const totalSec = Math.max(0, step * secondsPerStep);
|
|
6178
6170
|
const m = Math.floor(totalSec / 60);
|
|
@@ -6409,6 +6401,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6409
6401
|
if (!isSeeking) {
|
|
6410
6402
|
seekInput.value = String(Math.min(maxStep, Math.max(0, intStep)));
|
|
6411
6403
|
updateTimeLabel(intStep);
|
|
6404
|
+
syncSeekFill();
|
|
6412
6405
|
}
|
|
6413
6406
|
const chordName = stepChords[intStep] ?? "";
|
|
6414
6407
|
if (chordEl.textContent !== chordName) {
|
|
@@ -6436,6 +6429,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6436
6429
|
chordEl.textContent = "";
|
|
6437
6430
|
seekInput.value = "0";
|
|
6438
6431
|
updateTimeLabel(0);
|
|
6432
|
+
syncSeekFill();
|
|
6439
6433
|
for (const view of laneViews) {
|
|
6440
6434
|
for (const t of view.tokens) t.el.classList.remove("is-active");
|
|
6441
6435
|
view.lane.scrollLeft = 0;
|
|
@@ -6626,6 +6620,7 @@ var mountMmlPlayer = (target, mml, options = {}) => {
|
|
|
6626
6620
|
});
|
|
6627
6621
|
seekInput.addEventListener("input", () => {
|
|
6628
6622
|
renderPlayhead(Number(seekInput.value));
|
|
6623
|
+
syncSeekFill();
|
|
6629
6624
|
});
|
|
6630
6625
|
seekInput.addEventListener("change", () => {
|
|
6631
6626
|
isSeeking = false;
|
|
@@ -6986,6 +6981,13 @@ var parseToneMeta = (chords) => {
|
|
|
6986
6981
|
var parseMetronomeMeta = (chords) => {
|
|
6987
6982
|
return !/^#\s*metronome\s*=\s*off\s*$/im.test(chords);
|
|
6988
6983
|
};
|
|
6984
|
+
var parseBpmMeta = (chords) => {
|
|
6985
|
+
const m = chords.match(/^#\s*bpm\s*=\s*(\d+)\s*$/im);
|
|
6986
|
+
if (!m) return null;
|
|
6987
|
+
const val = Number.parseInt(m[1], 10);
|
|
6988
|
+
if (Number.isNaN(val)) return null;
|
|
6989
|
+
return Math.max(40, Math.min(240, val));
|
|
6990
|
+
};
|
|
6989
6991
|
var _nameToKeyCache = null;
|
|
6990
6992
|
var getNameToKey = async () => {
|
|
6991
6993
|
if (!_nameToKeyCache) _nameToKeyCache = await buildNameToKeyMapping();
|
|
@@ -7148,8 +7150,9 @@ var buildDisplayLines = (chords, eventsCount) => {
|
|
|
7148
7150
|
var mountChordPlayer = (target, chords, options = {}) => {
|
|
7149
7151
|
const doc = target.ownerDocument;
|
|
7150
7152
|
injectStyles(doc);
|
|
7151
|
-
let bpm = options.bpm ?? 120;
|
|
7153
|
+
let bpm = options.bpm ?? parseBpmMeta(chords) ?? 120;
|
|
7152
7154
|
let activeIndex = -1;
|
|
7155
|
+
let isSeeking = false;
|
|
7153
7156
|
let activePlayback = null;
|
|
7154
7157
|
let isPlaying = false;
|
|
7155
7158
|
let masterVolume = options.volume ?? 80;
|
|
@@ -7206,8 +7209,8 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7206
7209
|
const setPlayBtnStyle = (playing) => {
|
|
7207
7210
|
if (playing) {
|
|
7208
7211
|
playBtn.classList.add("dtm-play--stop");
|
|
7209
|
-
playBtn.innerHTML = icon("
|
|
7210
|
-
playBtn.title = "
|
|
7212
|
+
playBtn.innerHTML = icon("pause", 14);
|
|
7213
|
+
playBtn.title = "PAUSE";
|
|
7211
7214
|
} else {
|
|
7212
7215
|
playBtn.classList.remove("dtm-play--stop");
|
|
7213
7216
|
playBtn.innerHTML = icon("play", 14);
|
|
@@ -7284,17 +7287,9 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7284
7287
|
{ key: "guitar", label: "Guitar", emoji: "\u{1F3B8}" },
|
|
7285
7288
|
{ key: "strings", label: "Strings", emoji: "\u{1F3BB}" }
|
|
7286
7289
|
];
|
|
7287
|
-
const instrGroup = doc.createElement("
|
|
7288
|
-
instrGroup.className = "dtm-cp-instr-
|
|
7289
|
-
|
|
7290
|
-
const updateInstrButtons = () => {
|
|
7291
|
-
for (const { key } of INSTRUMENT_DEFS) {
|
|
7292
|
-
instrBtns.get(key)?.classList.toggle(
|
|
7293
|
-
"dtm-cp-instr-btn--active",
|
|
7294
|
-
key === activeInstrumentKey
|
|
7295
|
-
);
|
|
7296
|
-
}
|
|
7297
|
-
};
|
|
7290
|
+
const instrGroup = doc.createElement("select");
|
|
7291
|
+
instrGroup.className = "dtm-cp-instr-select";
|
|
7292
|
+
instrGroup.title = "\u697D\u5668";
|
|
7298
7293
|
const switchInstrument = (key) => {
|
|
7299
7294
|
if (activeInstrumentKey === key) return;
|
|
7300
7295
|
activeInstrumentKey = key;
|
|
@@ -7305,34 +7300,61 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7305
7300
|
if (ctx) loadWafFont(ctx, activeGmName);
|
|
7306
7301
|
}
|
|
7307
7302
|
};
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
instrGroup.appendChild(
|
|
7316
|
-
instrBtns.set(key, btn);
|
|
7303
|
+
const updateInstrButtons = () => {
|
|
7304
|
+
instrGroup.value = activeInstrumentKey;
|
|
7305
|
+
};
|
|
7306
|
+
for (const { key, label } of INSTRUMENT_DEFS) {
|
|
7307
|
+
const opt = doc.createElement("option");
|
|
7308
|
+
opt.value = key;
|
|
7309
|
+
opt.textContent = label;
|
|
7310
|
+
instrGroup.appendChild(opt);
|
|
7317
7311
|
}
|
|
7312
|
+
instrGroup.addEventListener("change", () => {
|
|
7313
|
+
const key = instrGroup.value;
|
|
7314
|
+
switchInstrument(key);
|
|
7315
|
+
});
|
|
7318
7316
|
updateInstrButtons();
|
|
7319
|
-
|
|
7320
|
-
|
|
7317
|
+
ctrlBar.appendChild(playBtn);
|
|
7318
|
+
ctrlBar.appendChild(loopBtn);
|
|
7319
|
+
ctrlBar.appendChild(metroBtn);
|
|
7320
|
+
ctrlBar.appendChild(bpmGroup);
|
|
7321
|
+
ctrlBar.appendChild(instrGroup);
|
|
7322
|
+
const seekRow = doc.createElement("div");
|
|
7323
|
+
seekRow.className = "dtm-player-seek-row";
|
|
7324
|
+
const seekInput = doc.createElement("input");
|
|
7325
|
+
seekInput.type = "range";
|
|
7326
|
+
seekInput.className = "dtm-player-seek";
|
|
7327
|
+
seekInput.min = "0";
|
|
7328
|
+
seekInput.max = String(Math.max(0.01, totalSec));
|
|
7329
|
+
seekInput.step = "0.01";
|
|
7330
|
+
seekInput.value = "0";
|
|
7331
|
+
seekInput.disabled = chordEvents.length === 0;
|
|
7332
|
+
const timeEl = doc.createElement("span");
|
|
7333
|
+
timeEl.className = "dtm-player-time";
|
|
7334
|
+
timeEl.textContent = "0:00 / 0:00";
|
|
7335
|
+
seekRow.append(seekInput, timeEl);
|
|
7321
7336
|
const formatTime = (sec) => {
|
|
7322
7337
|
const m = Math.floor(sec / 60);
|
|
7323
7338
|
const s = Math.floor(sec % 60);
|
|
7324
7339
|
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
7325
7340
|
};
|
|
7326
7341
|
const updateTimeDisplay = (currentSec) => {
|
|
7327
|
-
|
|
7342
|
+
timeEl.textContent = `${formatTime(currentSec)} / ${formatTime(totalSec)}`;
|
|
7328
7343
|
};
|
|
7329
7344
|
updateTimeDisplay(0);
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7345
|
+
const syncSeekFill = () => {
|
|
7346
|
+
const max = Number(seekInput.max) || 1;
|
|
7347
|
+
const pct = Number(seekInput.value) / max * 100;
|
|
7348
|
+
seekInput.style.setProperty("--fill", `${pct}%`);
|
|
7349
|
+
};
|
|
7350
|
+
syncSeekFill();
|
|
7351
|
+
const updateSeekUI = (sec) => {
|
|
7352
|
+
updateTimeDisplay(sec);
|
|
7353
|
+
if (!isSeeking) {
|
|
7354
|
+
seekInput.value = String(Math.max(0, Math.min(totalSec, sec)));
|
|
7355
|
+
syncSeekFill();
|
|
7356
|
+
}
|
|
7357
|
+
};
|
|
7336
7358
|
const menuContainer = doc.createElement("div");
|
|
7337
7359
|
menuContainer.className = "dtm-player-more-container";
|
|
7338
7360
|
const moreBtn = doc.createElement("button");
|
|
@@ -7364,6 +7386,7 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7364
7386
|
menuContainer.appendChild(menuDropdown);
|
|
7365
7387
|
ctrlBar.appendChild(menuContainer);
|
|
7366
7388
|
container.appendChild(ctrlBar);
|
|
7389
|
+
container.appendChild(seekRow);
|
|
7367
7390
|
const toggleMenu = (show) => {
|
|
7368
7391
|
const visible = show !== void 0 ? show : menuDropdown.style.display === "none";
|
|
7369
7392
|
menuDropdown.style.display = visible ? "flex" : "none";
|
|
@@ -7611,7 +7634,9 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7611
7634
|
secondsPerBeat = 60 / bpm;
|
|
7612
7635
|
totalSec = chordEvents.length > 0 ? chordEvents[chordEvents.length - 1].when + chordEvents[chordEvents.length - 1].duration : 0;
|
|
7613
7636
|
bpmInput.value = String(bpm);
|
|
7614
|
-
|
|
7637
|
+
seekInput.max = String(Math.max(0.01, totalSec));
|
|
7638
|
+
seekInput.disabled = chordEvents.length === 0;
|
|
7639
|
+
updateSeekUI(isPlaying ? playOffsetSec : 0);
|
|
7615
7640
|
if (isPlaying) seekTo(Math.max(0, activeIndex));
|
|
7616
7641
|
};
|
|
7617
7642
|
const changeBpm = (delta) => {
|
|
@@ -7658,18 +7683,6 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7658
7683
|
if (gmName) loadWafFont(ctx, gmName);
|
|
7659
7684
|
}
|
|
7660
7685
|
};
|
|
7661
|
-
const progress = doc.createElement("div");
|
|
7662
|
-
progress.className = "dtm-cp-progress";
|
|
7663
|
-
progress.title = "\u30AF\u30EA\u30C3\u30AF\u3067\u30B7\u30FC\u30AF";
|
|
7664
|
-
const progressFill = doc.createElement("div");
|
|
7665
|
-
progressFill.className = "dtm-cp-progress-fill";
|
|
7666
|
-
progress.appendChild(progressFill);
|
|
7667
|
-
container.appendChild(progress);
|
|
7668
|
-
const setProgress = (ratio) => {
|
|
7669
|
-
const clamped = Math.max(0, Math.min(1, ratio));
|
|
7670
|
-
progressFill.style.width = `${clamped * 100}%`;
|
|
7671
|
-
progressFill.classList.toggle("dtm-cp-progress-fill--on", clamped > 0);
|
|
7672
|
-
};
|
|
7673
7686
|
const scrollArea = doc.createElement("div");
|
|
7674
7687
|
scrollArea.className = "dtm-cp-scroll";
|
|
7675
7688
|
const chordSpans = [];
|
|
@@ -7903,8 +7916,7 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7903
7916
|
const currentSec = playOffsetSec + rel;
|
|
7904
7917
|
currentPlaySec = currentSec;
|
|
7905
7918
|
updateActiveIndex(getActiveIndexBySec(currentSec));
|
|
7906
|
-
|
|
7907
|
-
setProgress(totalSec > 0 ? currentSec / totalSec : 0);
|
|
7919
|
+
updateSeekUI(Math.min(currentSec, totalSec));
|
|
7908
7920
|
},
|
|
7909
7921
|
onStop: () => {
|
|
7910
7922
|
handlePlaybackStop();
|
|
@@ -7928,8 +7940,7 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7928
7940
|
isPlaying = true;
|
|
7929
7941
|
setPlayBtnStyle(true);
|
|
7930
7942
|
updateActiveIndex(startIdx);
|
|
7931
|
-
|
|
7932
|
-
setProgress(totalSec > 0 ? playOffsetSec / totalSec : 0);
|
|
7943
|
+
updateSeekUI(playOffsetSec);
|
|
7933
7944
|
playInternal(startIdx, ctx, cutGain);
|
|
7934
7945
|
};
|
|
7935
7946
|
const myAbortId = ++loadAbortId;
|
|
@@ -7956,13 +7967,19 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7956
7967
|
}
|
|
7957
7968
|
play(idx);
|
|
7958
7969
|
};
|
|
7959
|
-
|
|
7970
|
+
seekInput.addEventListener("pointerdown", () => {
|
|
7971
|
+
isSeeking = true;
|
|
7972
|
+
});
|
|
7973
|
+
seekInput.addEventListener("input", () => {
|
|
7974
|
+
updateTimeDisplay(Number(seekInput.value));
|
|
7975
|
+
syncSeekFill();
|
|
7976
|
+
});
|
|
7977
|
+
seekInput.addEventListener("change", () => {
|
|
7978
|
+
isSeeking = false;
|
|
7960
7979
|
if (totalSec <= 0) return;
|
|
7961
|
-
const
|
|
7962
|
-
if (rect.width <= 0) return;
|
|
7963
|
-
const sec = (ev.clientX - rect.left) / rect.width * totalSec;
|
|
7980
|
+
const sec = Number(seekInput.value);
|
|
7964
7981
|
const idx = getActiveIndexBySec(sec);
|
|
7965
|
-
seekTo(idx >= 0 ? idx : 0);
|
|
7982
|
+
seekTo(idx >= 0 ? idx : Math.max(0, chordEvents.length - 1));
|
|
7966
7983
|
});
|
|
7967
7984
|
const stop = () => {
|
|
7968
7985
|
if (isLoading) {
|
|
@@ -7982,15 +7999,30 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
7982
7999
|
isPlaying = false;
|
|
7983
8000
|
setPlayBtnStyle(false);
|
|
7984
8001
|
updateActiveIndex(-1);
|
|
7985
|
-
|
|
7986
|
-
|
|
8002
|
+
updateSeekUI(0);
|
|
8003
|
+
options.onStop?.();
|
|
8004
|
+
};
|
|
8005
|
+
const pause = () => {
|
|
8006
|
+
if (isLoading) {
|
|
8007
|
+
++loadAbortId;
|
|
8008
|
+
setLoadingUI(false);
|
|
8009
|
+
killSound();
|
|
8010
|
+
return;
|
|
8011
|
+
}
|
|
8012
|
+
if (!isPlaying) return;
|
|
8013
|
+
activePlayback?.destroy();
|
|
8014
|
+
activePlayback = null;
|
|
8015
|
+
stopMetronome();
|
|
8016
|
+
killSound();
|
|
8017
|
+
isPlaying = false;
|
|
8018
|
+
setPlayBtnStyle(false);
|
|
7987
8019
|
options.onStop?.();
|
|
7988
8020
|
};
|
|
7989
8021
|
playBtn.addEventListener("click", () => {
|
|
7990
8022
|
if (isPlaying) {
|
|
7991
|
-
|
|
8023
|
+
pause();
|
|
7992
8024
|
} else {
|
|
7993
|
-
play();
|
|
8025
|
+
play(Math.max(0, activeIndex));
|
|
7994
8026
|
}
|
|
7995
8027
|
});
|
|
7996
8028
|
const toggleMetronome = () => {
|
|
@@ -8052,32 +8084,31 @@ var mountChordPlayer = (target, chords, options = {}) => {
|
|
|
8052
8084
|
animation: dtm-cp-spin 0.7s linear infinite;
|
|
8053
8085
|
vertical-align: middle;
|
|
8054
8086
|
}
|
|
8055
|
-
/* \
|
|
8056
|
-
.dtm-cp-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
border: 1px solid rgba(255,255,255,0.15);
|
|
8060
|
-
border-radius: 4px;
|
|
8061
|
-
overflow: hidden;
|
|
8087
|
+
/* \u30B3\u30FC\u30C9\u9032\u884C\u30D7\u30EC\u30A4\u30E4\u30FC\u306EPLAY\u30DC\u30BF\u30F3\u306F\u901A\u5E38\u306EDAW\u3088\u308A\u5C0F\u3055\u3081\u3067\u3088\u3044 */
|
|
8088
|
+
.dtm-cp-ctrl .dtm-play {
|
|
8089
|
+
width: 24px;
|
|
8090
|
+
height: 24px;
|
|
8062
8091
|
}
|
|
8063
|
-
|
|
8092
|
+
/* \u697D\u5668\u9078\u629E\u30D7\u30EB\u30C0\u30A6\u30F3\uFF08\u7701\u30B9\u30DA\u30FC\u30B9\u3067\u30B9\u30DE\u30DB\u3067\u3082\u96A0\u308C\u306A\u3044\uFF09 */
|
|
8093
|
+
.dtm-cp-instr-select {
|
|
8064
8094
|
background: rgba(255,255,255,0.06);
|
|
8065
|
-
border:
|
|
8066
|
-
|
|
8095
|
+
border: 1px solid rgba(255,255,255,0.15);
|
|
8096
|
+
border-radius: 4px;
|
|
8097
|
+
color: rgba(255,255,255,0.85);
|
|
8067
8098
|
font-size: 11px;
|
|
8068
|
-
|
|
8099
|
+
font-family: inherit;
|
|
8100
|
+
padding: 2px 4px;
|
|
8069
8101
|
cursor: pointer;
|
|
8070
|
-
|
|
8071
|
-
|
|
8102
|
+
max-width: 62px;
|
|
8103
|
+
flex-shrink: 1;
|
|
8104
|
+
min-width: 0;
|
|
8072
8105
|
}
|
|
8073
|
-
.dtm-cp-instr-
|
|
8106
|
+
.dtm-cp-instr-select:hover {
|
|
8074
8107
|
background: rgba(255,255,255,0.14);
|
|
8075
|
-
color: rgba(255,255,255,0.85);
|
|
8076
8108
|
}
|
|
8077
|
-
.dtm-cp-instr-
|
|
8078
|
-
background:
|
|
8079
|
-
color: #
|
|
8080
|
-
font-weight: bold;
|
|
8109
|
+
.dtm-cp-instr-select option {
|
|
8110
|
+
background: #1a1a2e;
|
|
8111
|
+
color: #fff;
|
|
8081
8112
|
}
|
|
8082
8113
|
/* BPM widget styles */
|
|
8083
8114
|
.dtm-cp-bpm-group {
|