Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsy4567 committed Oct 1, 2023
1 parent 3ee7559 commit 6854b7a
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 60 deletions.
8 changes: 8 additions & 0 deletions example/两只老虎.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
1 2 3 1 // 两只老虎
1 2 3 1 // 两只老虎
3 4 5 ~1 // 跑得快
3 4 5 ~1 // 跑得快
5 ~-0.1 6 5 ~-0.1 4 3 1 // 一直没有眼睛
5 ~-0.1 6 5 ~-0.1 4 3 1 // 一只没有尾巴
3 -5 1 ~1 // 真奇怪
3 -5 1 // 真奇怪
6 changes: 6 additions & 0 deletions example/小星星.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
1 1 5 5 6 6 5 // 一闪一闪亮晶晶
~1 4 4 3 3 2 2 1 // 满天都是小星星
~1 5 5 4 4 3 3 2 // 挂在天上放光明
~1 5 5 4 4 3 3 2 // 好像许多小眼睛
~1 1 1 5 5 6 6 5 // 一闪一闪亮晶晶
~1 4 4 3 3 2 2 1 // 满天都是小星星
4 changes: 4 additions & 0 deletions example/玛丽的小羊羔.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
3 2 1 2 3 3 3 //我有一只小羊羔
~1 2 2 2 //小羊羔
~1 3 5 5 //小羊羔
~1 3 2 1 2 3 3 3 1 2 2 3 2 1 //长着一身洁白绒毛洁白绒毛
6 changes: 6 additions & 0 deletions example/让风告诉你.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
3 2 ~-0.1 1 1 1 1 2 // 当你的天空突然
1 ~-0.1 2 ~-0.1 3 ~-0.1 4 ~-0.1 3 // 下起了大雨
2 ~-0.1 1 1 5 1 5 1 -6 -5 // 那是我在为你炸乌云
3 2 ~-0.1 1 1 1 1 2 // 当你的发丝微乱
1 ~-0.1 2 ~-0.1 3 ~-0.1 4 ~-0.1 3 // 有阵风吹过
2 ~-0.1 1 1 5 1 5 1 2 1 // 那是我在远处想念你
109 changes: 71 additions & 38 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
button[data-note] {
width: 36px;
}
input:invalid {
background-color: red;
}
</style>
</head>
<body>
Expand Down Expand Up @@ -96,18 +99,22 @@ <h1>ikun 专属乐器</h1>
<textarea
id="曲谱"
style="width: 100%; height: 114.514px"
placeholder="曲谱, 使用空格分隔, sleep:n 可以停顿演奏 n 个音符所需时长, 换行符及多个连续空格将被忽略"
placeholder="曲谱, 使用空格分隔, ~n 可以停顿演奏 n 个音符时长, 换行符及多个连续空格将被忽略"
></textarea>
<br />
<button id="演奏">演奏</button>
<button onclick="演奏.onclick(曲谱.value.substring(曲谱.selectionStart,曲谱.selectionEnd))">
演奏选中
</button>
<button id="停止">停止</button>
<br />
<button onclick="曲谱.value+=' '">空格</button>
<button onclick="曲谱.value+='\n sleep:' + sl.value">换行 + 停顿</button>
<button onclick="曲谱.value+='\n ~' + sl.value">换行 + 停顿</button>
<button onclick="曲谱.value=曲谱.value.substring(0, 曲谱.value.lastIndexOf(' '))">
删除
</button>
<button onclick="曲谱.value+=` sleep:${sl.value}`">sleep:</button>
<input id="sl" placeholder="n" value="1" min="0" step="0.5" type="number" />
<button onclick="曲谱.value+=` ~${sl.value}`">停顿 n 个音符时长:</button>
<input id="sl" placeholder="n" value="1" step="0.1" type="number" />
<label>
<input checked type="checkbox" id="编谱模式" />
记录音符
Expand Down Expand Up @@ -149,7 +156,16 @@ <h1>ikun 专属乐器</h1>
<br />
<span>Made with ♥ by <a href="https://github.com/dsy4567">dsy4567</a></span>
<script>
var audio = {};
const /** @type {HTMLInputElement} */ 曲谱 = document.getElementById("曲谱"),
/** @type {HTMLInputElement} */ 编谱模式 = document.getElementById("编谱模式"),
/** @type {HTMLButtonElement} */ 演奏 = document.getElementById("演奏"),
/** @type {HTMLInputElement} */ 停止 = document.getElementById("停止"),
/** @type {Record<string, HTMLAudioElement>} */ audio = {};
let timeouts = [],
selectionStart = 0,
selectionEnd = 0,
selectionDirection = "forward",
正在演奏 = false;
document.querySelectorAll("button[data-note]").forEach(async el => {
audio[el.dataset.note] = URL.createObjectURL(
await (await fetch(`audio/${el.dataset.note}.mp3`)).blob()
Expand All @@ -163,10 +179,46 @@ <h1>ikun 专属乐器</h1>
}
};
});
演奏.onclick = () => {
var n = 0,
演奏.onclick = 演奏选中 => {
if (正在演奏) return;
正在演奏 = true;
selectionStart = 曲谱.selectionStart;
selectionEnd = 曲谱.selectionEnd;
selectionDirection = 曲谱.selectionDirection;
曲谱.readOnly = true;
曲谱.focus();
let index = typeof 演奏选中 === "string" ? 曲谱.selectionStart : 0,
n = 0,
bgmUrl = "",
p = 曲谱.value;
/** @type {string} */ p = typeof 演奏选中 === "string" ? 演奏选中 : 曲谱.value;
曲谱.setSelectionRange(0, 0);
const f = () => {
p.replace(/(\n| +\/\/.+\n)/g, " ")
.replace(/ +/g, " ")
.split(" ")
.forEach(s => {
let sleep = 0;
if (s.startsWith("~")) {
sleep = +s.replace("~", "");
if (isNaN(sleep)) sleep = 1;
return (n += sleep);
}
timeouts.push(
setTimeout(() => {
new Audio(audio[s]).play();
const start = 曲谱.value.indexOf(s, index),
end = start + s.length;
曲谱.setSelectionRange(start, end);
index = end;
}, +timeout.value * n++)
);
});
timeouts.push(
setTimeout(() => {
停止.click(1);
}, +timeout.value * n)
);
};
if (p.startsWith("!bgm:")) {
let m = p.match(/\!bgm\:.+\n/);
bgmUrl = m[0].replace("!bgm:", "").replace("\n", "");
Expand All @@ -178,40 +230,21 @@ <h1>ikun 专属乐器</h1>
bgmUrl = "";
bgm.onloadedmetadata = () => {
bgm.play();
p.replace(/(\n| +\/\/.+\n)/g, " ")
.replace(/ +/g, " ")
.split(" ")
.forEach(s => {
let sleep = 0;
if (s.startsWith("sleep:")) {
sleep = +s.replace("sleep:", "");
if (isNaN(sleep)) sleep = 1;
return (n += sleep);
}
setTimeout(() => {
new Audio(audio[s]).play();
}, +timeout.value * n++);
});
f();
};
} else
p.replace(/(\n| +\/\/.+\n)/g, " ")
.replace(/ +/g, " ")
.split(" ")
.forEach(s => {
let sleep = 0;
if (s.startsWith("sleep:")) {
sleep = +s.replace("sleep:", "");
if (isNaN(sleep)) sleep = 1;
return (n += sleep);
}
setTimeout(() => {
new Audio(audio[s]).play();
}, +timeout.value * n++);
});
} else f();
};
停止.onclick = ct => {
if (ct !== 1) for (const t of timeouts) clearTimeout(t);
timeouts = [];
正在演奏 = false;
曲谱.readOnly = false;
曲谱.focus()
曲谱.setSelectionRange(selectionStart, selectionEnd, selectionDirection);
};
document.querySelectorAll("button[data-name]").forEach(el => {
el.onclick = () => {
fetch(`示例曲谱/${el.dataset.name}.txt`).then(async res => {
fetch(`example/${el.dataset.name}.txt`).then(async res => {
曲谱.value = await res.text();
});
};
Expand Down
8 changes: 0 additions & 8 deletions 示例曲谱/两只老虎.txt

This file was deleted.

6 changes: 0 additions & 6 deletions 示例曲谱/小星星.txt

This file was deleted.

4 changes: 0 additions & 4 deletions 示例曲谱/玛丽的小羊羔.txt

This file was deleted.

4 changes: 0 additions & 4 deletions 示例曲谱/让风告诉你.txt

This file was deleted.

0 comments on commit 6854b7a

Please sign in to comment.