mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-15 03:23:22 +08:00
JS脚本:AutoYuanQin、AEscoffier_chef【更新】 (#2975)
* update AutoYuanQin * update AEscoffier_chef
This commit is contained in:
@@ -242,7 +242,8 @@
|
||||
if (string.length <= 6) {
|
||||
return string; // 如果字符串长度是6位或以下,原形返回
|
||||
} else {
|
||||
return string.substring(0, 5) + '..'; // 如果字符串长度超过6位,保留前5位并加上'..'
|
||||
// return string.substring(0, 5) + '..'; // 如果字符串长度超过6位,保留前5位并加上'..'
|
||||
return string.substring(0, 5); // 如果字符串长度超过6位,保留前5位
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "一只爱可菲",
|
||||
"version": "2.3.1",
|
||||
"version": "2.3.2",
|
||||
"bgi_version": "0.55.0",
|
||||
"description": "专精料理制作的爱可菲(自动烹饪及解锁、特殊料理、食材加工)[内置料理数据已更新至月之四]\n自动烹饪:烹饪精度自定义、一键全解锁、分类选择料理、自动处理食材不足等异常\n特殊料理:支持根据概率计算产出、支持全部的特殊料理\n食材加工:食材持有量检测、可自选制作鱼肉的配方、可选等待加工完成或跳过、矿石加速",
|
||||
"tags": [
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
1. 点击运行开始播放音乐
|
||||
- tips:
|
||||
- `AutoYuanQin/assets/tutorial_file`文件夹下的制谱软件(`五线谱制谱器.html`)为早期制谱用软件
|
||||
- 现在有更自动化的`AutoYuanQin/tools/MIDI翻谱器.html`提供自动的MIDI文件转*AutoYuanQin*格式的乐谱
|
||||
- 现在有更自动化的`AutoYuanQin/tools/MIDI制谱器.html`提供自动的MIDI文件转*AutoYuanQin*格式的乐谱
|
||||
- `AutoYuanQin/assets/tutorial_file`目录下有文档供曲谱制作人阅读
|
||||
- 本文档下文会详细说明一个标准格式的曲谱.json文件格式, 包括各个字段的解释以及曲谱内容的格式要求
|
||||
- 将你制作的曲谱的JSON文件置于正确的路径运行脚本时会自动重置settings并退出脚本
|
||||
@@ -17,15 +17,15 @@
|
||||
1. 联系BetterGI v7(1029539994)群主帮你更新到仓库
|
||||
1. 发送邮件到*hijiwos@hotmail.com*并说明, 你的谱子将会在一段时间内更新到仓库
|
||||
|
||||
## MIDI翻谱器 <a id="MIDI翻谱器"></a>
|
||||
1. 翻谱器位于`AutoYuanQin/tools/MIDI翻谱器.html`,请使用浏览器打开
|
||||
## MIDI制谱器 <a id="MIDI制谱器"></a>
|
||||
1. 翻谱器位于`AutoYuanQin/tools/MIDI制谱器.html`,请使用浏览器打开
|
||||
1. 点击选择文件, 将你想要转换的MIDI文件放入, 网页将自动开启转换
|
||||
1. 完成转换后点击"导出Json"后可将文件转移至`AutoYuanQin/assets/score_file`目录下使用
|
||||
1. **请不要在不了解文件结构的情况下手动修改JSON文件中的信息**
|
||||
|
||||
## 五线谱翻谱器
|
||||
1. 五线谱翻谱器位于`AutoYuanQin/assets/tutorial_file/五线谱制谱器.html`,请使用浏览器打开
|
||||
1. 请确保你有一定的识谱能力, 否则本文建议使用[MIDI翻谱器](#MIDI翻谱器)
|
||||
1. 请确保你有一定的识谱能力, 否则本文建议使用[MIDI制谱器](#MIDI制谱器)
|
||||
1. 使用步骤如下
|
||||
1. 确定音域(共有三种音域可选[左中右共三个], 每个音域为一对红蓝大写字符[21个])
|
||||
1. 选择音符:点击左上角图片中的对应`大写字母`或`@`, 点击多个音符实现和弦
|
||||
@@ -41,6 +41,11 @@
|
||||
1. 读取乐谱
|
||||
如果您写了一半, 打算下次在写, 可以使用导出曲谱功能保存曲谱, 下次要写的时候点击按钮```读取乐谱JSON```, 选择上次导出的文件即可
|
||||
|
||||
## 简谱制谱器
|
||||
1. 简谱制谱器位于`AutoYuanQin/assets/tutorial_file/简谱制谱器.html`,请使用浏览器打开
|
||||
1. 请确保你有一定的识谱能力, 否则本文建议使用[MIDI制谱器](#MIDI制谱器)
|
||||
1. 使用步骤在制谱器内有写,类似于五线谱翻谱器
|
||||
|
||||
## 曲谱制作解答
|
||||
1. `/assets/tutorial_file/五线谱注解.png` 包含了五线谱(高音区和低音区)对应的3组键盘键位(相邻的红蓝大写字母为一组, 每组音域为三个八度)
|
||||
1. 有不懂的地方请在 `/assets/tutorial_file/example.json` 内找, 这个谱子内包含了该脚本的五线谱相关的所有功能
|
||||
@@ -76,7 +81,7 @@
|
||||
|
||||
`description`: **可选键值** 可以随意填写关于该曲谱的描述信息
|
||||
|
||||
`type`: **必要键值** 决定曲谱的解析方式, 合法的值有`yuanqin`(默认值, [五线谱翻谱器](#五线谱翻谱器)) `midi`([MIDI翻谱器](#MIDI翻谱器)) `keyboard`(你在网上看到的琴谱格式与此相似)
|
||||
`type`: **必要键值** 决定曲谱的解析方式, 合法的值有`yuanqin`(默认值, [五线谱翻谱器](#五线谱翻谱器)) `midi`([MIDI制谱器](#MIDI制谱器)) `keyboard`(你在网上看到的琴谱格式与此相似)
|
||||
|
||||
`bpm`: **必要键值** 曲谱的BPM (Beats Per Minute)
|
||||
|
||||
@@ -244,6 +249,14 @@ notes 字段中包含的是乐谱内容音符**必须**使用**大写字母**,
|
||||
## 更新日志
|
||||
由于更新日志于3.0开始记录, 往期更新内容应该都在git的记录中, 不过我懒得翻了
|
||||
|
||||
- ver 3.3.0
|
||||
1. 更新了MIDI制谱器
|
||||
- 可自选MIDI通道(支持多通道合并),并且支持MIDI试听功能
|
||||
- 自动八度修正(可选)
|
||||
- 支持选择乐器,自定义曲谱元信息
|
||||
- 支持预览JSON文件和下载
|
||||
1. 新增了简谱制谱器(底层逻辑与五线谱制谱器相同,仅配图不同)
|
||||
|
||||
- ver 3.2.5
|
||||
1. 更新了两首单曲《可不可以》- 风物之诗琴、《唯一》- 风物之诗琴
|
||||
|
||||
@@ -282,7 +295,7 @@ notes 字段中包含的是乐谱内容音符**必须**使用**大写字母**,
|
||||
1. 初步完成了以上函数与原项目代码的适配
|
||||
1. 制谱软件从assets中转移至脚本根路径的./tools文件夹下
|
||||
1. 五线谱制谱软件的文件夹名称改为StaffMaker
|
||||
1. MIDI翻谱器从五线谱制谱器路径中移出
|
||||
1. MIDI制谱器从五线谱制谱器路径中移出
|
||||
1. 修改manifest.name为"原琴-音乐转换·自动演奏"
|
||||
1. 修改settings.json, 使其更易被理解
|
||||
1. 增加作者
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
1066
repo/js/AutoYuanQin/assets/tutorial_file/MIDI制谱器.html
Normal file
1066
repo/js/AutoYuanQin/assets/tutorial_file/MIDI制谱器.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -281,6 +281,7 @@
|
||||
<option value="悠可琴">悠可琴</option>
|
||||
<option value="「余音」">「余音」</option>
|
||||
<option value="跃律琴">跃律琴</option>
|
||||
<option value="谐律键琴">谐律键琴</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- 第二行 -->
|
||||
|
||||
656
repo/js/AutoYuanQin/assets/tutorial_file/简谱制谱器.html
Normal file
656
repo/js/AutoYuanQin/assets/tutorial_file/简谱制谱器.html
Normal file
@@ -0,0 +1,656 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="version" content="1.1">
|
||||
<title>BGI原琴制谱器</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
min-height: 100vh; /* 确保包括缓冲区域的最小高度 */
|
||||
}
|
||||
/* 页面容器 */
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#top-section {
|
||||
display: flex;
|
||||
min-height: 100vh; /* 占满可见页面高度 */
|
||||
margin-bottom: 100px; /* 给菜单栏留出空间 */
|
||||
}
|
||||
/* 左侧图像区域 */
|
||||
/*
|
||||
#image-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
*/
|
||||
#image-section img {
|
||||
height: 100%; /* 自适应页面高度 */
|
||||
object-fit: contain; /* 保持比例缩放 */
|
||||
}
|
||||
/* 文本区域容器 */
|
||||
#code-wrapper {
|
||||
flex: 1;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
#code-area {
|
||||
width: 100%;
|
||||
height: 62.5%; /* 高度基于左侧图片 */
|
||||
border: none;
|
||||
padding: 10px;
|
||||
font-size: calc(0.6vw + 0.6vh);
|
||||
font-family: monospace;
|
||||
line-height: 1.5em;
|
||||
resize: none; /* 禁止调整大小 */
|
||||
overflow-y: auto; /* 内容超出时显示滚动条 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* 悬浮菜单栏 */
|
||||
#bottom-section {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: auto; /* 根据内容高度自适应 */
|
||||
padding: 10px;
|
||||
background-color: #e0e0e0;
|
||||
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column; /* 垂直排列 */
|
||||
justify-content: center;
|
||||
}
|
||||
.action-button {
|
||||
margin: calc(0.5vw + 0.5vh);
|
||||
padding: calc(0.5vw + 0.5vh) calc(1vw + 1vh);
|
||||
font-size: 16px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.action-button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.textarea {
|
||||
margin: 10px;
|
||||
padding: 10px 20px;
|
||||
font-size: calc(0.6vw + 0.6vh);
|
||||
color: black;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.input-text {
|
||||
width: calc(5vw + 5vh);
|
||||
height: calc(0.5vw + 0.5vh);
|
||||
margin: calc(0.5vw + 0.5vh);
|
||||
padding: calc(0.5vw + 0.5vh) calc(0.5vw + 0.5vh);
|
||||
font-size: calc(0.6vw + 0.6vh);
|
||||
color: black;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.input-text-bpm {
|
||||
width: calc(2vw + 2vh);
|
||||
height: calc(0.5vw + 0.5vh);
|
||||
margin: calc(0.5vw + 0.5vh);
|
||||
padding: calc(0.5vw + 0.5vh) calc(0.5vw + 0.5vh);
|
||||
font-size: calc(0.6vw + 0.6vh);
|
||||
color: black;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.input-text-descriptiont {
|
||||
width: calc(20vw + 20vh);
|
||||
height: calc(0.5vw + 0.5vh);
|
||||
margin: calc(0.5vw + 0.5vh);
|
||||
padding: calc(0.5vw + 0.5vh) calc(0.5vw + 0.5vh);
|
||||
font-size: calc(0.6vw + 0.6vh);
|
||||
color: black;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.dropdown {
|
||||
margin: calc(0.5vw + 0.5vh);
|
||||
padding: calc(0.5vw + 0.5vh) calc(0.5vw + 0.5vh);
|
||||
font-size: calc(0.6vw + 0.6vh);
|
||||
background-color: #FFFFFF;
|
||||
color: black;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.hotspot {
|
||||
margin: 10px auto;
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
background-color: #ffa500;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border-radius: calc(0.15625vw + 0.15625vw);
|
||||
}
|
||||
/* 缓冲区域 */
|
||||
#buffer {
|
||||
height: 100px; /* 缓冲区域高度(占位) */
|
||||
background-color: transparent;
|
||||
display: block;
|
||||
}
|
||||
/* 隐藏默认文件选择框 */
|
||||
#file_input {
|
||||
display: none;
|
||||
}
|
||||
/* 鼠标悬停效果 */
|
||||
.custom-file-label:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
/* 为文件名展示样式 */
|
||||
.file_name {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<!-- 顶部内容 -->
|
||||
<div id="top-section">
|
||||
<div id="image-section">
|
||||
<img src="简谱对照表.png" alt="左侧图片" width="1111" height="1111" usemap="#Map" style="display: block; max-width: 100%; height: auto;">
|
||||
<map name="Map">
|
||||
<area shape="rect" coords="24,48,79,108" onclick="add_key('@')">
|
||||
<area shape="rect" coords="101,112,156,172" onclick="add_key('Q')">
|
||||
<area shape="rect" coords="149,112,204,172" onclick="add_key('W')">
|
||||
<area shape="rect" coords="201,112,256,172" onclick="add_key('E')">
|
||||
<area shape="rect" coords="253,112,308,172" onclick="add_key('R')">
|
||||
<area shape="rect" coords="305,112,360,172" onclick="add_key('T')">
|
||||
<area shape="rect" coords="357,112,412,172" onclick="add_key('Y')">
|
||||
<area shape="rect" coords="409,112,464,172" onclick="add_key('U')">
|
||||
<area shape="rect" coords="101,242,156,302" onclick="add_key('A')">
|
||||
<area shape="rect" coords="149,242,204,302" onclick="add_key('S')">
|
||||
<area shape="rect" coords="201,242,256,302" onclick="add_key('D')">
|
||||
<area shape="rect" coords="253,242,308,302" onclick="add_key('F')">
|
||||
<area shape="rect" coords="305,242,360,302" onclick="add_key('G')">
|
||||
<area shape="rect" coords="357,242,412,302" onclick="add_key('H')">
|
||||
<area shape="rect" coords="409,242,464,302" onclick="add_key('J')">
|
||||
<area shape="rect" coords="101,372,156,432" onclick="add_key('Z')">
|
||||
<area shape="rect" coords="149,372,204,432" onclick="add_key('X')">
|
||||
<area shape="rect" coords="201,372,256,432" onclick="add_key('C')">
|
||||
<area shape="rect" coords="253,372,308,432" onclick="add_key('V')">
|
||||
<area shape="rect" coords="305,372,360,432" onclick="add_key('B')">
|
||||
<area shape="rect" coords="357,372,412,432" onclick="add_key('N')">
|
||||
<area shape="rect" coords="409,372,464,432" onclick="add_key('M')">
|
||||
<area shape="rect" coords="595,48,650,108" onclick="add_key('@')">
|
||||
<area shape="rect" coords="672,112,727,172" onclick="add_key('Q')">
|
||||
<area shape="rect" coords="720,112,775,172" onclick="add_key('W')">
|
||||
<area shape="rect" coords="772,112,827,172" onclick="add_key('E')">
|
||||
<area shape="rect" coords="824,112,879,172" onclick="add_key('R')">
|
||||
<area shape="rect" coords="876,112,931,172" onclick="add_key('T')">
|
||||
<area shape="rect" coords="928,112,983,172" onclick="add_key('Y')">
|
||||
<area shape="rect" coords="980,112,1035,172" onclick="add_key('U')">
|
||||
<area shape="rect" coords="672,242,727,302" onclick="add_key('A')">
|
||||
<area shape="rect" coords="720,242,775,302" onclick="add_key('S')">
|
||||
<area shape="rect" coords="772,242,827,302" onclick="add_key('D')">
|
||||
<area shape="rect" coords="824,242,879,302" onclick="add_key('F')">
|
||||
<area shape="rect" coords="876,242,931,302" onclick="add_key('G')">
|
||||
<area shape="rect" coords="928,242,983,302" onclick="add_key('H')">
|
||||
<area shape="rect" coords="980,242,1035,302" onclick="add_key('J')">
|
||||
<area shape="rect" coords="672,372,727,432" onclick="add_key('Z')">
|
||||
<area shape="rect" coords="720,372,775,432" onclick="add_key('X')">
|
||||
<area shape="rect" coords="772,372,827,432" onclick="add_key('C')">
|
||||
<area shape="rect" coords="824,372,879,432" onclick="add_key('V')">
|
||||
<area shape="rect" coords="876,372,931,432" onclick="add_key('B')">
|
||||
<area shape="rect" coords="928,372,983,432" onclick="add_key('N')">
|
||||
<area shape="rect" coords="980,372,1035,432" onclick="add_key('M')">
|
||||
<area shape="rect" coords="24,508,79,568" onclick="add_key('@')">
|
||||
<area shape="rect" coords="101,572,156,632" onclick="add_key('Q')">
|
||||
<area shape="rect" coords="149,572,204,632" onclick="add_key('W')">
|
||||
<area shape="rect" coords="201,572,256,632" onclick="add_key('E')">
|
||||
<area shape="rect" coords="253,572,308,632" onclick="add_key('R')">
|
||||
<area shape="rect" coords="305,572,360,632" onclick="add_key('T')">
|
||||
<area shape="rect" coords="357,572,412,632" onclick="add_key('Y')">
|
||||
<area shape="rect" coords="409,572,464,632" onclick="add_key('U')">
|
||||
<area shape="rect" coords="101,702,156,762" onclick="add_key('A')">
|
||||
<area shape="rect" coords="149,702,204,762" onclick="add_key('S')">
|
||||
<area shape="rect" coords="201,702,256,762" onclick="add_key('D')">
|
||||
<area shape="rect" coords="253,702,308,762" onclick="add_key('F')">
|
||||
<area shape="rect" coords="305,702,360,762" onclick="add_key('G')">
|
||||
<area shape="rect" coords="357,702,412,762" onclick="add_key('H')">
|
||||
<area shape="rect" coords="409,702,464,762" onclick="add_key('J')">
|
||||
<area shape="rect" coords="101,832,156,892" onclick="add_key('Z')">
|
||||
<area shape="rect" coords="149,832,204,892" onclick="add_key('X')">
|
||||
<area shape="rect" coords="201,832,256,892" onclick="add_key('C')">
|
||||
<area shape="rect" coords="253,832,308,892" onclick="add_key('V')">
|
||||
<area shape="rect" coords="305,832,360,892" onclick="add_key('B')">
|
||||
<area shape="rect" coords="357,832,412,892" onclick="add_key('N')">
|
||||
<area shape="rect" coords="409,832,464,892" onclick="add_key('M')">
|
||||
</map>
|
||||
</div>
|
||||
<div id="code-wrapper">
|
||||
<textarea id="code-area" placeholder="自动生成代码..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 缓冲区域 -->
|
||||
<div id="buffer"></div>
|
||||
|
||||
<!-- 悬浮菜单栏 -->
|
||||
<div id="bottom-section">
|
||||
<!-- 第一行 -->
|
||||
<div class="row">
|
||||
<label for="score_name" class="textarea">曲名:</label>
|
||||
<input type="text" id="score_name" name="score_name" class="input-text" placeholder="输入歌曲名称...">
|
||||
<label for="score_author" class="textarea">录谱人:</label>
|
||||
<input type="text" id="score_author" name="score_author" class="input-text" placeholder="输入翻谱人名称...">
|
||||
<label for="score_bpm" class="textarea">BPM:</label>
|
||||
<input type="number" id="score_bpm" name="score_bpm" min="1" max="1000" value="1" class="input-text-bpm">
|
||||
<label for="time_signature" class="textarea">拍号: </label>
|
||||
<select id="time_signature" class="dropdown">
|
||||
<option value="1/4">1/4</option>
|
||||
<option value="2/4">3/4</option>
|
||||
<option value="3/4">3/4</option>
|
||||
<option value="4/4">4/4</option>
|
||||
<option value="5/4">5/4</option>
|
||||
<option value="3/8">3/8</option>
|
||||
<option value="4/8">4/8</option>
|
||||
<option value="6/8">6/8</option>
|
||||
<option value="9/8">9/8</option>
|
||||
<option value="2/2">2/2</option>
|
||||
<option value="3/2">3/2</option>
|
||||
</select>
|
||||
<label for="score_composer" class="textarea">曲师:</label>
|
||||
<input type="text" id="score_composer" name="score_composer" class="input-text" placeholder="曲师...">
|
||||
<label for="score_arranger" class="textarea">谱师:</label>
|
||||
<input type="text" id="score_arranger" name="score_arranger" class="input-text" placeholder="谱师...">
|
||||
<label for="score_instrument" class="textarea">乐器: </label>
|
||||
<select id="score_instrument" class="dropdown">
|
||||
<option value="风物之诗琴">风物之诗琴</option>
|
||||
<option value="老旧的诗琴">老旧的诗琴</option>
|
||||
<option value="镜花之琴">镜花之琴</option>
|
||||
<option value="荒泷·盛世豪鼓">荒泷·盛世豪鼓</option>
|
||||
<option value="绮筵之鼓">绮筵之鼓</option>
|
||||
<option value="晚风圆号">晚风圆号</option>
|
||||
<option value="聚聚鼓">聚聚鼓</option>
|
||||
<option value="悠可琴">悠可琴</option>
|
||||
<option value="「余音」">「余音」</option>
|
||||
<option value="跃律琴">跃律琴</option>
|
||||
<option value="谐律键琴">谐律键琴</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- 第二行 -->
|
||||
<div class="row">
|
||||
<label for="dropdown_type" class="textarea">音符类型: </label>
|
||||
<select id="dropdown_type" class="dropdown">
|
||||
<option value="none">普通</option>
|
||||
<option value="*">附点音符</option>
|
||||
<option value=".">连音</option>
|
||||
<option value="$">连音(末尾)</option>
|
||||
<option value="#">装饰音·倚音</option>
|
||||
</select>
|
||||
<label for="dropdown_all" class="textarea" style="display: none;" id="dropdown_all_text">连音总时值: </label>
|
||||
<select id="dropdown_all" class="dropdown" style="display: none;">
|
||||
<option value="0.25">4个全音符</option>
|
||||
<option value="0.375">3个全音符</option>
|
||||
<option value="0.5">2个全音符</option>
|
||||
<option value="1">全音符</option>
|
||||
<option value="2">二分音符</option>
|
||||
<option value="4">四分音符</option>
|
||||
<option value="8">八分音符</option>
|
||||
<option value="16">十六分音符</option>
|
||||
<option value="32">三十二分音符</option>
|
||||
<option value="64">六十四分音符</option>
|
||||
</select>
|
||||
<label for="score_description" class="textarea">描述:</label>
|
||||
<input type="text" id="score_description" name="score_description" class="input-text-descriptiont" placeholder="在这里填写描述(例如简谱的网址)...">
|
||||
</div>
|
||||
<!-- 第三行 -->
|
||||
<div class="row">
|
||||
<label for="dropdown_long" class="textarea" id="dropdown_long_text">音符时值: </label>
|
||||
<select id="dropdown_long" class="dropdown">
|
||||
<option value="1">全音符</option>
|
||||
<option value="2">二分音符</option>
|
||||
<option value="4">四分音符</option>
|
||||
<option value="8">八分音符</option>
|
||||
<option value="16">十六分音符</option>
|
||||
<option value="32">三十二分音符</option>
|
||||
<option value="64">六十四分音符</option>
|
||||
</select>
|
||||
<button class="action-button" onclick="new_bar()">分节</button>
|
||||
<button class="action-button" onclick="new_line()">换行</button>
|
||||
<button class="action-button" onclick="btn_confirm()">确定(完善音符)</button>
|
||||
<button class="action-button" onclick="btn_output()">导出乐谱JSON</button>
|
||||
<input type="file" id="file_input">
|
||||
<button for="file_input" class="action-button" id="read_button">读取乐谱JSON</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("keydown", function(event) {
|
||||
if (event.key === "Enter") {
|
||||
const activeElement = document.activeElement;
|
||||
const codeArea = document.getElementById("code-area");
|
||||
|
||||
/*如果焦点不在 #code-area 上*/
|
||||
if (activeElement !== codeArea) {
|
||||
event.preventDefault(); /*阻止默认行为*/
|
||||
btn_confirm();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
/*设置页面底部缓冲区高度与悬浮菜单栏的高度相同*/
|
||||
var bottomSection = document.getElementById('bottom-section');
|
||||
var buffer = document.getElementById('buffer');
|
||||
buffer.style.height = bottomSection.offsetHeight + 'px';
|
||||
|
||||
var dropdownType = document.getElementById('dropdown_type');
|
||||
var dropdownAllText = document.getElementById('dropdown_all_text');
|
||||
var dropdownAll = document.getElementById('dropdown_all');
|
||||
var dropdownLong = document.getElementById('dropdown_long_text');
|
||||
|
||||
const fileInput = document.getElementById('file_input');
|
||||
const readButton = document.getElementById('read_button');
|
||||
const textArea = document.getElementById("code-area");
|
||||
|
||||
// 代码文本框自动滚动到底部
|
||||
textArea.addEventListener("input", () => {
|
||||
textArea.scrollTop = textArea.scrollHeight;
|
||||
});
|
||||
|
||||
|
||||
/*设置连音时值下拉菜单的可见性和音符时值文本*/
|
||||
dropdownType.addEventListener('change', function() {
|
||||
if (dropdownType.value === "." || dropdownType.value === "$") { // 显示连音总时值
|
||||
dropdownAll.style.display = 'inline-block';
|
||||
dropdownAllText.style.display = 'inline-block';
|
||||
dropdownLong.textContent = "连音中当前音符时值: ";
|
||||
} else {
|
||||
dropdownAll.style.display = 'none'; // 隐藏
|
||||
dropdownAllText.style.display = 'none';
|
||||
dropdownLong.textContent = "音符时值: ";
|
||||
// // 重置音符类型下拉菜单为默认选项
|
||||
// dropdownAll.selectedIndex = 0;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/*点击“读取JSON文件”按钮时触发*/
|
||||
readButton.addEventListener('click', () => {
|
||||
fileInput.value = ""; // 清空上一次选择的文件
|
||||
fileInput.click(); // 模拟点击文件选择框
|
||||
});
|
||||
|
||||
/*文件选择完成后触发*/
|
||||
fileInput.addEventListener('change', () => {
|
||||
const file = fileInput.files[0];
|
||||
if (file) {
|
||||
btn_read(); // 在选择文件后调用读取方法
|
||||
} else {
|
||||
alert("文件选择出错!"); // 理论上不会执行
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/*点击图片添加音符*/
|
||||
function add_key(key) {
|
||||
const regex_note = /(^|(?<=\])|(?<=\n))[^][^\n]*(?=\[\])/g; // 匹配空音符A[]或(AD)[]
|
||||
const codeArea = document.getElementById('code-area');
|
||||
const textArea = document.getElementById('code-area'); // 用于滚动
|
||||
let content = codeArea.value;
|
||||
let matches = content.match(regex_note);
|
||||
if (matches !== null && matches.length > 1) { // 异常操作检测(可能用不到)
|
||||
alert(`存在的未完成的音符数大于一个,无法添加新的音符(目前存在的所有未完成音符数: ${matches.length})`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (content.endsWith("[]")) { // 添加为和弦
|
||||
if (content[content.length - 3] === ")") { // 已是和弦
|
||||
const left_index = content.lastIndexOf("(");
|
||||
const right_index = content.lastIndexOf(")");
|
||||
|
||||
const string_mid = content.substring(left_index, right_index);
|
||||
if (string_mid.includes(key)) { // 重复音不添加
|
||||
return null;
|
||||
}
|
||||
content = `${content.substring(0, left_index)}${string_mid}${key}${content.substring(right_index)}`;
|
||||
} else { // 仍为单音
|
||||
const ori_key_index = content.lastIndexOf("[") - 1;
|
||||
if (content[ori_key_index] === key) { // 重复音不添加
|
||||
return null;
|
||||
}
|
||||
content = `${content.substring(0, ori_key_index)}(${content[ori_key_index]}${key})[]`;
|
||||
}
|
||||
codeArea.value = content;
|
||||
} else { // 添加新的音
|
||||
content += key + "[]";
|
||||
codeArea.value = content;
|
||||
}
|
||||
// 滚动到底部
|
||||
textArea.scrollTop = textArea.scrollHeight;
|
||||
}
|
||||
|
||||
/*点击按钮添加分节标志*/
|
||||
function new_bar() {
|
||||
const regex_note = /(^|(?<=\])|(?<=\n))[^][^\n]*(?=\[\])/g; // 匹配空音符A[]或(AD)[]
|
||||
const codeArea = document.getElementById('code-area');
|
||||
const textArea = document.getElementById('code-area'); // 用于滚动
|
||||
let content = codeArea.value;
|
||||
if (regex_note.test(content)) {
|
||||
alert(`存在未完成的音符!`);
|
||||
return null;
|
||||
} else if (content.endsWith("\n") || content.endsWith("|")) {
|
||||
alert("小节内容不能为空!");
|
||||
return null;
|
||||
}
|
||||
content += "|\n";
|
||||
codeArea.value = content;
|
||||
// 滚动到底部
|
||||
textArea.scrollTop = textArea.scrollHeight;
|
||||
|
||||
}
|
||||
|
||||
/*点击按钮添加换行标志*/
|
||||
function new_line() {
|
||||
const regex_note = /(^|(?<=\])|(?<=\n))[^][^\n]*(?=\[\])/g; // 匹配空音符A[]或(AD)[]
|
||||
const codeArea = document.getElementById('code-area');
|
||||
const textArea = document.getElementById('code-area'); // 用于滚动
|
||||
let content = codeArea.value;
|
||||
if (regex_note.test(content)) {
|
||||
alert(`存在未完成的音符!`);
|
||||
return null;
|
||||
} else if (content.endsWith("\n")) {
|
||||
alert("行的内容不能为空!\n如果已经添加了分节标志,请手动删除分节标志");
|
||||
return null;
|
||||
}
|
||||
content += "|\n\n";
|
||||
codeArea.value = content;
|
||||
// 滚动到底部
|
||||
codeArea.scrollTop = textArea.scrollHeight;
|
||||
}
|
||||
|
||||
/*根据所选完善音符*/
|
||||
function btn_confirm() {
|
||||
const codeArea = document.getElementById('code-area');
|
||||
let content = codeArea.value;
|
||||
if (!content.endsWith("[]")) {
|
||||
alert("未检测到空音符,请先添加音符!");
|
||||
return null;
|
||||
}
|
||||
const dropdownType = document.getElementById('dropdown_type');
|
||||
const score_type = dropdownType.value;
|
||||
const dropdownLong = document.getElementById('dropdown_long');
|
||||
const dropdownAll = document.getElementById('dropdown_all');
|
||||
const regex_detail = /(?<=\[)[\s\S]*?(?=\])/g // 匹配 [] test
|
||||
|
||||
if (score_type === "none") { // 普通音符
|
||||
content = `${content.slice(0, -2)}[${dropdownLong.value}]`;
|
||||
} else if (score_type === ".") { // 连音(默认使用3)
|
||||
content = `${content.slice(0, -2)}[${dropdownAll.value}-${dropdownLong.value}.3]`;
|
||||
} else if (score_type === "$") { // 连音(末尾)
|
||||
content = `${content.slice(0, -2)}[${dropdownAll.value}-${dropdownLong.value}.$]`;
|
||||
} else { // 附点音符或装饰音·倚音
|
||||
content = `${content.slice(0, -2)}[${dropdownLong.value}-${dropdownType.value}]`;
|
||||
}
|
||||
codeArea.value = content;
|
||||
|
||||
}
|
||||
|
||||
/*导出乐谱文件*/
|
||||
function btn_output() {
|
||||
const score_name = document.getElementById("score_name").value;
|
||||
const score_author = document.getElementById("score_author").value;
|
||||
|
||||
if (score_name === "" || score_author === "") {
|
||||
alert("导出前请填写曲谱名和录谱人!");
|
||||
return null;
|
||||
}
|
||||
let score_instrument = document.getElementById("score_instrument").value;
|
||||
let score_description = document.getElementById("score_description").value;
|
||||
const score_bpm = document.getElementById("score_bpm").value;
|
||||
const time_signature = document.getElementById("time_signature").value;
|
||||
let score_composer = document.getElementById("score_composer").value;
|
||||
let score_arranger = document.getElementById("score_arranger").value;
|
||||
score_description = typeof(score_description) === "undefined" ? "无": score_description;
|
||||
score_composer = typeof(score_composer) === "undefined" ? "无": score_composer;
|
||||
score_arranger = typeof(score_arranger) === "undefined" ? "无": score_arranger;
|
||||
const notes = document.getElementById("code-area").value;
|
||||
|
||||
const json_content = `{
|
||||
"name": "${score_name}",
|
||||
"author": "${score_author}",
|
||||
"instrument": "${score_instrument}",
|
||||
"description": "${score_description}",
|
||||
"bpm": "${score_bpm}",
|
||||
"time_signature": "${time_signature}",
|
||||
"composer": "${score_composer}",
|
||||
"arranger": "${score_arranger}",
|
||||
"notes": "${notes.replace(/\n/g, "\\n")}"
|
||||
}`;
|
||||
// 创建Blob对象
|
||||
const blob = new Blob([json_content], { type: 'application/json' });
|
||||
// 创建下载链接
|
||||
const url = URL.createObjectURL(blob);
|
||||
// 动态创建隐藏的<a>元素
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `${score_name}.json`; // 文件名
|
||||
a.style.display = 'none';
|
||||
|
||||
// 模拟点击触发下载
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
// 释放URL对象
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
/*读取乐谱文件*/
|
||||
function btn_read() {
|
||||
const codeArea = document.getElementById('code-area');
|
||||
const scoreName = document.getElementById('score_name');
|
||||
const scoreAuthor = document.getElementById('score_author');
|
||||
const scoreInstrument = document.getElementById('score_instrument');
|
||||
const scoreBpm = document.getElementById('score_bpm');
|
||||
const timeSignature = document.getElementById('time_signature');
|
||||
const scoreComposer = document.getElementById('score_composer');
|
||||
const scoreArranger = document.getElementById('score_arranger');
|
||||
const scoreDescription = document.getElementById('score_description');
|
||||
|
||||
const fileInput = document.getElementById('file_input');
|
||||
const file = fileInput.files[0]; // 获取选中的文件
|
||||
if (!file) {
|
||||
alert('请先选择一个文件!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用 FileReader 读取文件内容
|
||||
const reader = new FileReader();
|
||||
|
||||
// 文件读取成功的回调函数
|
||||
reader.onload = function(event) {
|
||||
const content = event.target.result; // 文件内容
|
||||
const content_msg = get_music_msg(content); // 解析后的文件内容
|
||||
// 将本地乐谱文件载入HTML
|
||||
scoreName.value = content_msg["name"];
|
||||
scoreAuthor.value = content_msg["author"];
|
||||
scoreInstrument.value = content_msg["instrument"];
|
||||
scoreBpm.value = content_msg["bpm"];
|
||||
timeSignature.value = content_msg["time_signature"];
|
||||
scoreComposer.value = content_msg["composer"];
|
||||
scoreArranger.value = content_msg["arranger"];
|
||||
scoreDescription.value = content_msg["description"];
|
||||
codeArea.value = content_msg["notes"]; // notes
|
||||
};
|
||||
|
||||
// 以文本形式读取文件
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 解析一个乐谱文件
|
||||
*
|
||||
* @param file_text {string} 乐曲文件内容
|
||||
* @returns
|
||||
*/
|
||||
function get_music_msg(file_text) {
|
||||
|
||||
let music_msg_dic = {};
|
||||
|
||||
// 正则表达式,用于匹配如下内容
|
||||
let regex_name = /(?<="name": ")[\s\S]*?(?=")/
|
||||
let regex_author = /(?<="author": ")[\s\S]*?(?=")/
|
||||
let regex_instrument = /(?<="instrument": ")[\s\S]*?(?=")/
|
||||
let regex_description = /(?<="description": ")[\s\S]*?(?=")/
|
||||
let regex_bpm = /(?<="bpm": ")[\s\S]*?(?=")/
|
||||
let regex_time_signature = /(?<="time_signature": ")[\s\S]*?(?=")/
|
||||
let regex_composer = /(?<="composer": ")[\s\S]*?(?=")/
|
||||
let regex_arranger = /(?<="arranger": ")[\s\S]*?(?=")/
|
||||
let regex_notes = /(?<="notes": ")[\s\S]*?(?=")/
|
||||
|
||||
let regex_blank_1 = /[\\\\n]{1}/g
|
||||
let regex_blank_2 = /[\\\\n]{2}/g
|
||||
try {
|
||||
// 歌曲名
|
||||
music_msg_dic["name"] = file_text.match(regex_name)[0];
|
||||
// 录谱人
|
||||
music_msg_dic["author"] = file_text.match(regex_author)[0];
|
||||
// 乐器
|
||||
music_msg_dic["instrument"] = file_text.match(regex_instrument)[0];
|
||||
// 描述
|
||||
music_msg_dic["description"] = file_text.match(regex_description)[0];
|
||||
// 歌曲BPM
|
||||
music_msg_dic["bpm"] = file_text.match(regex_bpm)[0];
|
||||
// 拍号
|
||||
music_msg_dic["time_signature"] = file_text.match(regex_time_signature)[0];
|
||||
// 曲师
|
||||
music_msg_dic["composer"] = file_text.match(regex_composer)[0];
|
||||
// 谱师
|
||||
music_msg_dic["arranger"] = file_text.match(regex_arranger)[0];
|
||||
// 曲谱内容(删除换行符)
|
||||
music_msg_dic["notes"] = file_text.match(regex_notes)[0].replace(regex_blank_2, "\n").replace(regex_blank_1, "");
|
||||
|
||||
} catch(error) {
|
||||
alert(`曲谱解析错误:${error}\n请检查曲谱文件格式是否正确`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return music_msg_dic;
|
||||
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
repo/js/AutoYuanQin/assets/tutorial_file/简谱对照表.png
Normal file
BIN
repo/js/AutoYuanQin/assets/tutorial_file/简谱对照表.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
@@ -614,14 +614,17 @@
|
||||
|
||||
}
|
||||
// 如果是midi转换的乐谱
|
||||
if (Object.keys(sheet_list[0]).length === 3) {
|
||||
for (let i = 0; i < sheet_list.length; i++) {
|
||||
log.info(`时长:${sheet_list[i]["time"]}`)
|
||||
await sleep(Math.round(sheet_list[i]["time"]));
|
||||
if (sheet_list[i]["type"] === "on") {
|
||||
keyDown(sheet_list[i]["note"]);
|
||||
if (typeof(sheet_list) === "string") {
|
||||
let play_sheet = sheet_list.split("|");
|
||||
for (let i = 0; i < play_sheet.length; i++) {
|
||||
let current_note = play_sheet[i].split("_");
|
||||
log.info(`${play_sheet[i]}`);
|
||||
await sleep(Math.round(current_note[2]));
|
||||
if (current_note[1] === "@") continue;
|
||||
if (current_note[0] === "D") {
|
||||
keyDown(current_note[1]);
|
||||
} else {
|
||||
keyUp(sheet_list[i]["note"]);
|
||||
keyUp(current_note[1]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "原琴·乐曲转换、自动演奏",
|
||||
"version": "3.2.5",
|
||||
"version": "3.3.0",
|
||||
"bgi_version": "0.43.1",
|
||||
"description": "功能描述:功能及其强大的原琴脚本\n核心功能------------------------------>\n1.轻松实现根据五线谱翻版琴谱,支持单音、和弦\n2.曲谱支持录入BPM、拍号\n3.特殊音符支持休止符、浮点音符、(三/六)连音、(三/六)连音标记线、装饰音·倚音\n4.含有制谱器,方便制作曲谱\n注意事项------------------------------>\n1.使用前请装备原琴\n2.音域只有3个八度,受原琴音域限制,本脚本的上限取决于翻谱的大佬(卑微\n3.实际上装饰音·倚音的时长视为基础时值单位(比如拍号2/4的基础时值单位就是4分音符)的1/16\n4.制铺说明:曲谱JSON文件的notes必须保证为一行且不能包括空白符(换行符除外);小节之间用|隔开,|不是必要的,作用是方便曲谱维护\n---------------------------------------->\n作者:提瓦特钓鱼玳师\n脚本反馈邮箱:hijiwos@hotmail.com",
|
||||
"authors": [
|
||||
|
||||
@@ -41,7 +41,10 @@
|
||||
"0019.枫",
|
||||
"0020.大石碎胸口 ver. “一阵强劲的音乐”",
|
||||
"0021.ClockParadox_Drop2",
|
||||
"0022.DAMIDAMI"
|
||||
"0022.DAMIDAMI",
|
||||
"0023.喜欢你",
|
||||
"0024.可不可以 ",
|
||||
"0025.唯一"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user