merge upstream

This commit is contained in:
Xiaolvjun 2026-01-19 23:38:20 +08:00
commit 2792202ac5
10 changed files with 994 additions and 706 deletions

BIN
images/moreoneshothold.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -35,7 +35,8 @@
};
</script>
<script type="module">
import "/script/rdview.js";
import "./script/rdview.js";
import {render} from "./script/rdtkview_render.js";
function escapeHtml(unsafe) {
return unsafe
@ -48,29 +49,32 @@
loadRDView();
const originalCodeRenderer = $docsify.markdown
?.renderer?.code;
function codeblockRender(code, lang) {
if (lang.trim().startsWith("rdview")) {
return RDViewRender(lang, code);
}
// else if (lang.trim().startsWith("rdtkview")) {
// const args = lang.slice(8).trim().split(" ");
// const width = parseInt(args[0]) || 8;
// const height = parseInt(args[1]) || 4;
// const scale = parseFloat(args[2]) || 2.0;
// const result = render(code, width, height, scale);
// result.toString = () => result;
// return result;
// }
return originalCodeRenderer
? originalCodeRenderer(code, lang)
: `<pre data-lang="${lang}"><code>${
escapeHtml(code)
}</code></pre>`;
}
$docsify = {
...$docsify,
...{
markdown: {
renderer: {
code: function (code, lang) {if (
lang.trim().startsWith(
"rdview",
)
) {
return RDViewRender(
lang,
code,
);
}
return originalCodeRenderer
? originalCodeRenderer(
code,
lang,
)
: `<pre data-lang="${lang}"><code>${
escapeHtml(code)
}</code></pre>`;
code: (code, lang) => {
return codeblockRender(code, lang);
},
image: function (src, title, alt) {
return `<div class="image-tip"><img class="medium-zoom-image" src="${src}" alt="${alt}">${
@ -103,7 +107,7 @@
<script src="/script/zoom-image.min.js"></script>
<script src="/script/search.min.js"></script>
<script src="/script/emoji.min.js"></script>
<script src="/script/docsify-copy-code.min.js"></script>
<!-- <script src="/script/docsify-copy-code.min.js"></script> -->
<script src="/script/switchLightDarkMode.js"></script>
<script src="/script/otto.js"></script>
<script src="/script/custommethod-search.js"></script>

View File

@ -22,6 +22,8 @@ g 1 1 5 4 #0ff{
---
完整功能支持请前往[此处](https://view.obugs.cn)。
<div class="rdview2"><div class="canvas"></div><div class="editor"><div class="number"></div><textarea class="area" spellcheck="false" placeholder="Enter code here">
{ "bar": 1, "beat": 1, "y": 0, "type": "MoveRoom", "if": "1d0", "roomPosition": [50, 50], "scale": [70, 100], "angle": 20, "pivot": [0, 0], "duration": 1, "ease": "Linear" },
{ "bar": 1, "beat": 1, "y": 6, "type": "AddOneshotBeat", "pulseType": "Triangle", "tick": 2, "subdivisions": 2, "subdivSound": true },
@ -29,62 +31,62 @@ g 1 1 5 4 #0ff{
{ "bar": 1, "beat": 2, "y": 1, "type": "ReorderRooms", "order": [1, 3, 2, 0] },
{ "bar": 1, "beat": 2, "y": 5, "type": "SetSpeed", "speed": 1, "duration": 0, "ease": "Linear" },
{ "bar": 1, "beat": 3, "y": 3, "type": "AddOneshotBeat", "pulseType": "Wave", "tick": 2 },
{ "bar": 1, "beat": 4, "y": 4, "type": "AddOneshotBeat", "pulseType": "Wave", "freezeBurnMode": "Burnshot", "interval": 2, "tick": 1 },
{ "bar": 1, "beat": 5, "y": 1, "type": "SetBeatsPerMinute", "if": "~3d0", "beatsPerMinute": 100 },
{ "bar": 1, "beat": 5, "y": 2, "type": "SetBackgroundColor", "rooms": [0], "backgroundType": "Color", "color": "FFFFFFFF", "filter": "NearestNeighbor" },
{ "bar": 1, "beat": 5, "y": 5, "type": "SetGameSound", "soundType": "SmallMistake", "filename": "" },
{ "bar": 1, "beat": 5, "y": 6, "type": "SetHeartExplodeInterval", "intervalType": "GatherAndCeil", "interval": 1 },
{ "bar": 1, "beat": 4, "y": 4, "type": "AddOneshotBeat", "pulseType": "Wave", "freezeBurnMode": "Burnshot", "interval": 2, "tick": 1 },
{ "bar": 1, "beat": 5, "y": 2, "type": "SetBackgroundColor", "rooms": [0], "backgroundType": "Color", "color": "FFFFFFFF", "filter": "NearestNeighbor" },
{ "bar": 1, "beat": 7, "y": 0, "type": "AddClassicBeat", "tag": "1", "tick": 0.5, "hold": 1, "swing": 0.5, "setXs": "NoChange" },
{ "bar": 1, "beat": 7, "y": 6, "type": "AddOneshotBeat", "pulseType": "Wave", "freezeBurnMode": "Freezeshot", "interval": 2, "tick": 1, "delay": 0.5, "skipshot": true },
{ "bar": 1, "beat": 8, "y": 4, "type": "SetCountingSound", "voiceSource": "JyiCount", "enabled": true, "volume": 100, "subdivOffset": 0.5 },
{ "bar": 1, "beat": 8, "y": 1, "type": "SetVisible", "visible": true },
{ "bar": 1, "beat": 8, "y": 2, "type": "ShowStatusSign", "if": "1d0", "text": "RhythmBase.View!", "duration": 5, "useBeats": true, "narrate": true },
{ "bar": 1, "beat": 8, "y": 3, "type": "Tint", "border": "Glow", "borderColor": "FF0000FF", "tint": true, "tintColor": "001BFFFF", "opacity": 100, "duration": 3, "ease": "Linear" },
{ "bar": 1, "beat": 8, "y": 4, "type": "SetCountingSound", "voiceSource": "JyiCount", "enabled": true, "volume": 100, "subdivOffset": 0.5 },
{ "bar": 1, "beat": 8, "y": 5, "type": "TextExplosion", "rooms": [0], "text": "Explosion", "color": "000000", "mode": "OneColor", "direction": "Left", "speed": 100, "ease": "Linear" },
{ "bar": 2, "beat": 2, "y": 5, "type": "SayReadyGetSetGo", "tag": "1", "rooms": [4], "phraseToSay": "JustSayRea", "voiceSource": "Nurse", "tick": 1, "volume": 100 },
{ "bar": 2, "beat": 3, "y": 4, "type": "SetOneshotWave", "waveType": "BoomAndRush", "height": 100, "width": 100 },
{ "bar": 2, "beat": 3, "y": 1, "type": "Move", "position": [50, 50], "duration": 1, "ease": "Linear" },
{ "bar": 2, "beat": 3, "y": 3, "type": "PlayAnimation", "expression": "neutral" },
{ "bar": 2, "beat": 3, "y": 2, "type": "NewWindowDance", "tab": "Windows", "preset": "Move", "position": [50, 50], "reference": "Center", "easingDuration": 1, "ease": "Linear" },
{ "bar": 2, "beat": 3, "y": 3, "type": "PlayAnimation", "expression": "neutral" },
{ "bar": 2, "beat": 3, "y": 4, "type": "SetOneshotWave", "waveType": "BoomAndRush", "height": 100, "width": 100 },
{ "bar": 2, "beat": 5, "y": 0, "type": "BassDrop", "if": "1&~2d0", "rooms": [0], "strength": "High" },
{ "bar": 2, "beat": 5, "y": 1, "type": "ShowDialogue", "rooms": [4], "text": "Samurai_Happy: SAMURAI!", "speed": 1, "panelSide": "Bottom", "portraitSide": "Left", "playTextSounds": true },
{ "bar": 2, "beat": 5, "y": 2, "type": "FloatingText", "rooms": [0], "id": 0, "text": "等/呀/等/得/好/心/慌……", "times": "", "color": "00F4FFFF", "outlineColor": "0011FFFF", "textPosition": [50, 50], "font": "Default", "size": 8, "angle": 0, "showChildren": true, "fadeOutRate": 3, "mode": "FadeOut", "anchor": "MiddleCenter", "narrate": true, "narrationCategory": "Subtitles" },
{ "bar": 2, "beat": 6, "y": 3, "type": "SetRoomPerspective", "cornerPositions": [[0, 0], [100, 0], [0, 100], [100, 100]], "duration": 1, "ease": "Linear" },
{ "bar": 2, "beat": 6, "y": 4, "type": "SetPlayStyle", "PlayStyle": "Normal", "NextBar": 1, "Relative": true },
{ "bar": 2, "beat": 7, "y": 5, "type": "SetCrotchetsPerBar", "crotchetsPerBar": 7, "visualBeatMultiplier": 1 },
{ "bar": 2, "beat": 7, "y": 6, "type": "SetHandOwner", "rooms": [0], "hand": "Right", "character": "Player" },
{ "bar": 2, "beat": 8, "y": 3, "type": "SetBeatSound", "row": 0, "sound": {"filename": "Shaker"} },
{ "bar": 2, "beat": 8, "y": 4, "type": "TintRows", "if" : "1&~2d1", "rooms": [0], "border": "Outline", "borderColor": "2BFF00FF", "tint": true, "tintColor": "007E0EFF", "opacity": 100, "duration": 0, "ease": "Linear", "effect": "None" },
{ "bar": 3, "beat": 1, "y": 2, "type": "PulseCamera", "rooms": [0], "strength": 1, "count": 1, "frequency": 1 },
{ "bar": 3, "beat": 1, "y": 1, "type": "ShowHands", "rooms": [0], "hand": "Right", "action": "Show", "extent": "Full", "forceRaise": true, "align": false, "instant": false },
{ "bar": 3, "beat": 1, "y": 0, "type": "MoveCamera", "rooms": [0], "cameraPosition": [50, 50], "duration": 1, "ease": "Linear" },
{ "bar": 2, "beat": 7, "y": 5, "type": "SetCrotchetsPerBar", "crotchetsPerBar": 7, "visualBeatMultiplier": 1 },
{ "bar": 2, "beat": 6, "y": 3, "type": "SetRoomPerspective", "cornerPositions": [[0, 0], [100, 0], [0, 100], [100, 100]], "duration": 1, "ease": "Linear" },
{ "bar": 3, "beat": 1, "y": 1, "type": "ShowHands", "rooms": [0], "hand": "Right", "action": "Show", "extent": "Full", "forceRaise": true, "align": false, "instant": false },
{ "bar": 3, "beat": 1, "y": 2, "type": "PulseCamera", "rooms": [0], "strength": 1, "count": 1, "frequency": 1 },
{ "bar": 3, "beat": 3, "y": 2, "type": "SayReadyGetSetGo", "if": "1d0", "rooms": [4], "phraseToSay": "SayGetSetOne", "voiceSource": "Nurse", "tick": 1, "volume": 100 },
{ "bar": 3, "beat": 3, "y": 6, "type": "FlipScreen", "rooms": [0], "flipX": false, "flipY": true },
{ "bar": 3, "beat": 4, "y": 6, "type": "InvertColors", "rooms": [0], "enable": true },
{ "bar": 3, "beat": 6, "y": 6, "type": "SayReadyGetSetGo", "rooms": [4], "phraseToSay": "JustSayAndStop", "voiceSource": "Nurse", "tick": 1, "volume": 100 },
{ "bar": 3, "beat": 5, "y": 3, "type": "DesktopColor", "endColor": "00ffff", "duration": 2, "ease": "Linear" },
{ "bar": 3, "beat": 6, "y": 6, "type": "SayReadyGetSetGo", "rooms": [4], "phraseToSay": "JustSayAndStop", "voiceSource": "Nurse", "tick": 1, "volume": 100 },
{ "bar": 3, "beat": 5, "y": -1, "type": "AdvanceText", "id": 0, "text": "text 字段不存在于原事件中,但是 RDView 提供了支持。" },
{ "bar": 3, "beat": 5.5, "y": -1, "type": "PulseFreeTimeBeat", "row": 0, "action": "Increment", "hold": 0 },
{ "bar": 3, "beat": 8, "y": 4, "type": "NarrateRowInfo", "row": 0, "infoType": "Connect", "soundOnly": false, "narrateSkipBeats": "On", "skipsUnstable": false, "customPlayer": "AutoDetect" },
{ "bar": 4, "beat": 1, "y": 2, "type": "PaintHands", "rooms": [0], "hands": "Right", "border": "Outline", "borderColor": "AFFF00FF", "tint": true, "tintColor": "4FAF00FF", "opacity": 100, "duration": 0 },
{ "bar": 3, "beat": 8, "y": 3, "type": "HideWindow", "show": false },
{ "bar": 3, "beat": 8, "y": 4, "type": "NarrateRowInfo", "row": 0, "infoType": "Connect", "soundOnly": false, "narrateSkipBeats": "On", "skipsUnstable": false, "customPlayer": "AutoDetect" },
{ "bar": 3, "beat": 8, "y": 5, "type": "Comment", "tab": "Actions", "text": "五彩斑斓的黑", "color": "8C00FF", "show": false },
{ "bar": 4, "beat": 1, "y": 6, "type": "SetWindowContent", "contentMode": "OnTop" },
{ "bar": 4, "beat": 2, "y": 4, "type": "PlaySong", "song": {"filename": "sndOrientalTechno"}, "bpm": 100, "loop": false },
{ "bar": 4, "beat": 1, "y": 2, "type": "PaintHands", "rooms": [0], "hands": "Right", "border": "Outline", "borderColor": "AFFF00FF", "tint": true, "tintColor": "4FAF00FF", "opacity": 100, "duration": 0 },
{ "bar": 4, "beat": 1, "y": 4, "type": "CallCustomMethod", "methodName": "", "executionTime": "OnBar", "sortOffset": 0 },
{ "bar": 4, "beat": 1, "y": 6, "type": "SetWindowContent", "contentMode": "OnTop" },
{ "bar": 4, "beat": 2, "y": 2, "type": "FadeRoom", "opacity": 100, "duration": 2, "ease": "Linear" },
{ "bar": 4, "beat": 2, "y": 4, "type": "PlaySong", "song": {"filename": "sndOrientalTechno"}, "bpm": 100, "loop": false },
{ "bar": 4, "beat": 2, "y": 6, "type": "SetRowXs", "pattern": "-x--x-", "syncoBeat": 3, "syncoSwing": 0, "syncoVolume": 70, "syncoPitch": 100, "syncoStyle": "Chirp", "syncoPlayModifierSound": true, "syncoPlayModifierOffSound": true },
{ "bar": 4, "beat": 3, "y": 3, "type": "ChangeCharacter", "row": 0, "character": "Samurai", "transition": "Instant" },
{ "bar": 4, "beat": 5, "y": 2, "type": "ShowRooms", "rooms": [1, 3], "heights": [0, 0, 0, 0], "transitionTime": 1, "ease": "InOutSine" },
{ "bar": 4, "beat": 6, "y": 6, "type": "RenameWindow", "action": "Set", "text": "Minecraft 1.21.1 NeoForge" },
{ "bar": 4, "beat": 7, "y": 2, "type": "SetVFXPreset", "rooms": [0], "preset": "Vignette", "enable": true },
{ "bar": 4, "beat": 7, "y": 4, "type": "SetTheme", "rooms": [0], "preset": "None", "skipPaintEffects": false },
{ "bar": 4, "beat": 7, "y": 3, "type": "PlaySound", "sound": {"filename": "Shaker"}, "customSoundType": "CueSound" },
{ "bar": 4, "beat": 7, "y": 4, "type": "SetTheme", "rooms": [0], "preset": "None", "skipPaintEffects": false },
{ "bar": 4, "beat": 7, "y": 5, "type": "SetRoomContentMode", "mode": "Center" },
{ "bar": 4, "beat": 8, "y": 6, "type": "TagAction", "Action": "Run", "Tag": "Nothing" },
{ "bar": 5, "beat": 1, "y": 2, "type": "PulseCamera", "rooms": [0], "strength": 1, "count": 1, "frequency": 1 },
{ "bar": 5, "beat": 1, "y": 3, "type": "SetClapSounds", "rowType": "Classic", "p1Sound": {"filename": "ClapHit"} },
{ "bar": 5, "beat": 1, "y": 4, "type": "ChangePlayersRows", "playerMode": "OneOrTwoPlayers", "players": ["NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange", "NoChange"], "cpuMarkers": ["Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto", "Otto"] },
{ "bar": 5, "beat": 1, "y": 2, "type": "PulseCamera", "rooms": [0], "strength": 1, "count": 1, "frequency": 1 },
{ "bar": 5, "beat": 1, "y": 5, "type": "ReadNarration", "text": "一名身穿红色盔甲的武士跟着音乐节拍点头。", "category": "Description" }
</textarea></div></div>

View File

@ -1,5 +1,8 @@
# 更新信息
#### 2026-01-16
- RDTKView(~~RDView2~~) 已完成部署
#### 2026-01-14
- 制作人员表增加了
- RDView 对正式版编辑器新特性的部分适配

View File

@ -10,7 +10,7 @@
第二个选项“**摇摆**”就是剧情模式里老奶奶那样的摇摆普通拍子可以使用拖动条来调节对照下方绿色竖线的移动可以很直观地看到摇摆效果。不过拖动滑条你只能得到一些倍数十分规整的摇摆拍子例如摇摆值为0.250.50.75等,如果你的音乐里真的有些更为不同寻常的摇摆幅度,那就要直接在框里填写数字了。
```rdview2 8 9
```rdtkview 8 9
{"beat": 2, "y": 1, "type": "AddClassicBeat", "row": 0, "tick": 1, "swing": 0.25, "hold": 0 },
{"beat": 2, "y": 2, "type": "AddClassicBeat", "row": 0, "tick": 1, "swing": 0.5, "hold": 0 },
{"beat": 2, "y": 3, "type": "AddClassicBeat", "row": 0, "tick": 1, "swing": 0.75, "hold": 0 },

View File

@ -338,6 +338,52 @@ g 0 -1 3 2 #0000[offset=0 1]{
};
```
## 长按单发拍
长按单发拍第一次出现在`7-1`
当听到`咻噗`的声音时,说明下一次击拍需要长按到下一个出拍点。
在修饰符中选中进度条符号就创建了一个长按单发拍,会多出`间隔``长按提示选项`选项。
![](../images/moreoneshothold.png)
对于长按单发拍,一共有四个关键的时间点:十字,出拍点(绿线),按拍点(黄线),长按(紫色格子)。
```rdtkview 5 3
{ "bar": 1, "beat": 3, "y": 2, "type": "AddOneshotBeat","interval": 2, "tick": 1, "hold": true },
```
- **十字**显示长按单发拍子的提示音。
- **绿线**代表单发拍会在此响一次。
- **黄线**表示长按的起始点,也就是说玩家应当从这里开始长按。
- **紫格**就是此次长按所需的时间。
- **绿线**与**黄线**之间的间隔就是`拍长`的时间。
- **十字**与**黄线**或者**绿线**与**紫格**末端之间的间隔就是`间隔`的时间。
`长按提示`有三个选项,分别是:自动、偏早、偏晚。
- 选择**偏早**时,`十字`的位置会在`绿线`之前。
- 选择**偏晚**时,`十字`不会显示,但提示音会与`绿线`重合。
- 选择**自动**时:
- 若**拍长**小于或等于1则像`偏早`一样,长按单发拍子的提示音会在`绿线`之前;
- 若**拍长**大于1则像`偏晚`一样,`十字`不会显示,但提示音会与`绿线`重合。
```rdtkview 5 5
{ "bar": 1, "beat": 3, "y": 2, "type": "AddOneshotBeat","interval": 2, "tick": 1, "hold": true },
{ "bar": 1, "beat": 3, "y": 3, "type": "AddOneshotBeat","interval": 2, "tick": 1, "hold": true },
{ "bar": 1, "beat": 3, "y": 4, "type": "AddOneshotBeat","interval": 2, "tick": 1, "hold": true }
```
若设计长按单发拍,还必须满足松手音效与提示音不可重叠
如果需要在长按单发拍上叠加多个拍子来凸显鼓点,可以将他们的按拍点放在同一位置。
```rdtkview 5 3
{ "bar": 1, "beat": 1.5, "y": 2, "tick": 2.5, "type": "AddOneshotBeat" },
{ "bar": 1, "beat": 2.5, "y": 2, "tick": 1.5, "type": "AddOneshotBeat" },
{ "bar": 1, "beat": 3, "y": 2, "type": "AddOneshotBeat","interval": 2, "tick": 1, "hold": true }
```
最后我们针对细分拍、冻结拍、灼热拍做一个技术总结:
```rdview 19 7

BIN
rdviewAssets/assets Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

79
script/rdtkview_render.js Normal file
View File

@ -0,0 +1,79 @@
import { createElementEvent } from "./rdtkview.js";
export function render(data, width, height, scale = 2.0) {
const canvas = document.createElement("div");
let objs = [];
try {
objs = JSON.parse(`[${data}]`);
canvas.innerHTML = "";
} catch (e) {
canvas.innerHTML =
`<div style="color: red; font-weight: bold;">JSON解析错误${e.message}</div>`;
return canvas;
}
const eventStyle = { "scale": scale, "showDuration": false };
const elems = [];
for (let obj of objs) {
const style = { ...eventStyle, enabled: obj.active ?? true };
const elem = createElementEvent(obj, style);
if (!elem) continue;
elem.eventStyle = style;
elem.style.position = "absolute";
elem.style.left = `${
((((obj.bar ?? 1) - 1) * 8) + (obj.beat ?? 1) - 1) * 14 *
scale
}px`;
elem.style.top = `${(obj.y ?? obj.row ?? 0) * 14 * scale}px`;
elem.addEventListener("mousedown", (event) => {
const eStyle = elem.eventStyle;
eStyle.active = true;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseover", (event) => {
const eStyle = elem.eventStyle;
eStyle.hover = true;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseout", (event) => {
const eStyle = elem.eventStyle;
eStyle.hover = false;
eStyle.active = false;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseup", (event) => {
const eStyle = elem.eventStyle;
eStyle.active = false;
elem.onStateChange(eStyle);
});
elems.push(elem);
}
canvas.style.position = "relative";
canvas.style.width = `${width * 14 * scale}px`;
canvas.style.height = `${height * 14 * scale}px`;
elems.forEach((elem) => {
canvas.appendChild(elem);
});
return canvas;
}
window.$docsify.plugins = [].concat(window.$docsify.plugins, (hook) => {
hook.doneEach(() => {
const pres = document.querySelectorAll("pre");
pres.forEach((codeBlock) => {
const lang = codeBlock.getAttribute("data-lang") || "";
if (lang.startsWith("rdtkview")) {
const code = codeBlock.querySelector("code").innerText || "";
const args = lang.slice(8).trim().split(" ");
const width = parseInt(args[0]) || 8;
const height = parseInt(args[1]) || 4;
const scale = parseFloat(args[2]) || 2.0;
const result = render(code, width, height, scale);
const parent = document.createElement("div");
parent.style.width = 100 + "%";
parent.style.display = "flex";
parent.style.justifyContent = "center";
parent.appendChild(result);
codeBlock.replaceWith(parent);
}
});
});
});

View File

@ -1,4 +1,4 @@
import { createElementEvent } from "./View.js";
import { createElementEvent } from "./rdtkview.js";
let curx = 0;
let cury = 0;
@ -322,52 +322,58 @@ function rdview2() {
}
const eventStyle = { "scale": 2.0, "showDuration": false };
let maxy = 0;
const elemPromises = [];
for (let obj of objs) {
const style = { ...eventStyle, enabled: obj.active ?? true };
const elem = createElementEvent(obj, style);
elem.eventStyle = style;
elem.style.position = "absolute";
elem.style.left = `${
((((obj.bar ?? 1) - 1) * 8) + (obj.beat ?? 1) - 1) * 14 *
eventStyle.scale
}px`;
elem.style.top = `${
(obj.y ?? obj.row ?? 0) * 14 * eventStyle.scale
}px`;
if (
((obj.y ?? obj.row ?? 0) * 14 * eventStyle.scale) +
elem.offsetHeight > maxy
) {
maxy = ((obj.y ?? obj.row ?? 0) * 14 * eventStyle.scale) +
elem.offsetHeight;
}
elem.addEventListener("mousedown", (event) => {
const eStyle = elem.eventStyle;
eStyle.active = true;
elem.onStateChange(eStyle);
const elem = createElementEvent(obj, style).then((elem) => {
elem.eventStyle = style;
elem.style.position = "absolute";
elem.style.left = `${
((((obj.bar ?? 1) - 1) * 8) + (obj.beat ?? 1) - 1) * 14 *
eventStyle.scale
}px`;
elem.style.top = `${
(obj.y ?? obj.row ?? 0) * 14 * eventStyle.scale
}px`;
if (
((obj.y ?? obj.row ?? 0) * 14 * eventStyle.scale) +
elem.offsetHeight > maxy
) {
maxy = ((obj.y ?? obj.row ?? 0) * 14 * eventStyle.scale) +
elem.offsetHeight;
}
elem.addEventListener("mousedown", (event) => {
const eStyle = elem.eventStyle;
eStyle.active = true;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseover", (event) => {
const eStyle = elem.eventStyle;
eStyle.hover = true;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseout", (event) => {
const eStyle = elem.eventStyle;
eStyle.hover = false;
eStyle.active = false;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseup", (event) => {
const eStyle = elem.eventStyle;
eStyle.active = false;
elem.onStateChange(eStyle);
});
return elem;
});
elem.addEventListener("mouseover", (event) => {
const eStyle = elem.eventStyle;
eStyle.hover = true;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseout", (event) => {
const eStyle = elem.eventStyle;
eStyle.hover = false;
eStyle.active = false;
elem.onStateChange(eStyle);
});
elem.addEventListener("mouseup", (event) => {
const eStyle = elem.eventStyle;
eStyle.active = false;
elem.onStateChange(eStyle);
});
rdcanvas.style.position = "relative";
rdcanvas.style.height = `${maxy + 4 * 14 * eventStyle.scale}px`;
if (elem) {
rdcanvas.appendChild(elem);
}
elemPromises.push(elem);
}
Promise.all(elemPromises).then((elems) => {
elems.forEach((elem) => {
rdcanvas.appendChild(elem);
});
});
rdcanvas.style.position = "relative";
rdcanvas.style.height = `${maxy + 4 * 14 * eventStyle.scale}px`;
}
initCanvas();
initLineNumbers();