feat: add more buttons

This commit is contained in:
Guanran Wang 2024-11-23 02:32:27 +08:00
parent ad23de2de0
commit 6577ce16f8
Signed by: nyancat
GPG key ID: 91F97D9ED12639CF
11 changed files with 106 additions and 33 deletions

View file

@ -14,12 +14,7 @@
<a href="https://git.ny4.dev/nyancat/chicken-box">
<img src="/cxk.webp" alt="鸡音盒" class="size-32" />
</a>
<div class="inline-flex rounded-lg shadow-sm">
<button type="button" class="chicken-button" id="chicken"></button>
<button type="button" class="chicken-button" id="you"></button>
<button type="button" class="chicken-button" id="so"></button>
<button type="button" class="chicken-button" id="beautiful"></button>
</div>
<div id="cxk-container"></div>
</div>
</body>
</html>

BIN
public/two/basketball.opus Normal file

Binary file not shown.

BIN
public/two/jump.opus Normal file

Binary file not shown.

BIN
public/two/rap.opus Normal file

Binary file not shown.

BIN
public/two/sing.opus Normal file

Binary file not shown.

View file

@ -1,3 +1,11 @@
type Button = {
id: string;
text: string;
key: string;
code: string;
file: string;
};
const audioCache: Record<string, AudioBuffer> = {};
const audioPlay = async (url: string) => {
@ -17,29 +25,93 @@ const audioPlay = async (url: string) => {
source.start();
};
const chicken = document.querySelector("#chicken")! as HTMLButtonElement;
const you = document.querySelector("#you")! as HTMLButtonElement;
const so = document.querySelector("#so")! as HTMLButtonElement;
const beautiful = document.querySelector("#beautiful")! as HTMLButtonElement;
const buttons: Button[][] = [
[
{
id: "chicken",
text: "鸡",
key: "1",
code: "Digit1",
file: "/one/chicken.opus",
},
{
id: "you",
text: "你",
key: "2",
code: "Digit2",
file: "/one/you.opus",
},
{
id: "so",
text: "太",
key: "3",
code: "Digit3",
file: "/one/so.opus",
},
{
id: "beautiful",
text: "美",
key: "4",
code: "Digit4",
file: "/one/beautiful.opus",
},
],
[
{
id: "sing",
text: "唱",
key: "Q",
code: "KeyQ",
file: "/two/sing.opus",
},
{
id: "jump",
text: "跳",
key: "W",
code: "KeyW",
file: "/two/jump.opus",
},
{
id: "rap",
text: "rap",
key: "E",
code: "KeyE",
file: "/two/rap.opus",
},
{
id: "basketball",
text: "篮球",
key: "R",
code: "KeyR",
file: "/two/basketball.opus",
},
],
];
chicken.onclick = () => audioPlay("/chicken.opus");
you.onclick = () => audioPlay("/you.opus");
so.onclick = () => audioPlay("/so.opus");
beautiful.onclick = () => audioPlay("/beautiful.opus");
buttons.forEach((row) => {
const container = document.querySelector(`#cxk-container`) as HTMLDivElement;
const buttonGroup = document.createElement("div");
document.onkeydown = function (e) {
switch (e.key) {
case "1":
audioPlay("/chicken.opus");
break;
case "2":
audioPlay("/you.opus");
break;
case "3":
audioPlay("/so.opus");
break;
case "4":
audioPlay("/beautiful.opus");
break;
container.appendChild(buttonGroup);
row.forEach(({ id, text, key, file }) => {
const button = document.createElement("button");
button.type = "button";
button.id = id;
button.textContent = text;
button.onclick = () => audioPlay(file);
const buttonKey = document.createElement("p");
buttonKey.textContent = key;
buttonGroup.appendChild(button);
button.appendChild(buttonKey);
});
});
document.onkeydown = (e) => {
const button = buttons.flat().find((b) => b.code === e.code);
if (button) {
audioPlay(button.file);
}
};

View file

@ -3,13 +3,19 @@
@tailwind utilities;
@layer components {
.chicken-button {
@apply relative py-3 px-4 inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-800;
counter-increment: index;
#cxk-container {
@apply flex flex-col gap-2;
}
.chicken-button:before {
#cxk-container > * {
@apply inline-flex rounded-lg shadow-sm;
}
#cxk-container > * > * {
@apply relative h-12 w-16 justify-center inline-flex items-center gap-x-2 -ms-px first:rounded-s-lg first:ms-0 last:rounded-e-lg text-sm font-medium focus:z-10 border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-800;
}
#cxk-container > * > * > * {
@apply absolute top-1 left-1 text-xs text-neutral-500;
content: counter(index);
}
}