From 9d14a88a98464f019c28d96318bc1d48acf5e1f7 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Fri, 12 Dec 2025 15:23:35 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E5=8F=96=E6=B6=88=E7=BE=A4=E5=8F=B7?= =?UTF-8?q?=E7=9A=84=E7=BC=A9=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/intro.md b/pages/intro.md index 9d80e03..3029cae 100644 --- a/pages/intro.md +++ b/pages/intro.md @@ -14,7 +14,7 @@ ## 联系我们
-我们的 QQ 1044116596

我们的 QQ 群号是: 1044116596

+我们的 QQ 1044116596

我们的 QQ 群号是: 1044116596

如果你有做谱相关的问题,或是对本教程有什么意见和建议,可以点击链接加入 QQ 群 [1044116596](https://qm.qq.com/q/giuo0RDv4Q) 告知我们。你也可以在群里上传谱面给我们试玩,群友们都会热心为你提供谱面优化建议。真诚欢迎各位做谱萌新和大佬的加入。 From a01042af6af63ff93cb8f25fd8960900a8e59a3d Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Fri, 12 Dec 2025 15:24:30 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E3=80=90=E5=AE=9E=E9=AA=8C=E3=80=91?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=20rdview2=20=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 212 ++++--- rdviewAssets/assets.json | 253 ++++++++ rdviewAssets/assets.png | Bin 0 -> 7459 bytes script/Extensions.js | 1176 ++++++++++++++++++++++++++++++++++++++ script/rdview2.js | 84 +++ 5 files changed, 1644 insertions(+), 81 deletions(-) create mode 100644 rdviewAssets/assets.json create mode 100644 rdviewAssets/assets.png create mode 100644 script/Extensions.js create mode 100644 script/rdview2.js diff --git a/index.html b/index.html index d6f1472..dfbf132 100644 --- a/index.html +++ b/index.html @@ -1,29 +1,31 @@ + + + 节奏医生编辑器教程 + + + + + + + + + + + + - - - 节奏医生编辑器教程 - - - - - - - - - - - - - - -
加载中...
- - + - - - - - - - - - - - - \ No newline at end of file + loadRDView(); + const originalCodeRenderer = $docsify.markdown + ?.renderer?.code; + $docsify = { + ...$docsify, + ...{ + markdown: { + renderer: { + code: function (code, lang) { + if ( + lang.trim().startsWith( + "rdview2", + ) + ) { + const langParts = lang + .trim().split(" "); + const width = + parseInt( + langParts[1], + ) || 8; + const height = + parseInt( + langParts[2], + ) || 4; + const scale = + (parseFloat( + langParts[3], + ) || 1) * 2; + return `
`; + } else if ( + lang.trim().startsWith( + "rdview", + ) + ) { + return RDViewRender( + lang, + code, + ); + } + return originalCodeRenderer + ? originalCodeRenderer( + code, + lang, + ) + : `
${
+                                        escapeHtml(code)
+                                    }
`; + }, + image: function (src, title, alt) { + return `
${alt}${ + alt ? `

${alt}

` : "" + }
`; + }, + }, + }, + switchLightDarkMode: { + useSwitchMode: true, + top: 130, + right: 26, + svgColor: "#7d7b75", + }, + search: { + noData: { + "/": "没有找到结果!", + }, + paths: "auto", + placeholder: { + "/": "搜索", + }, + hideOtherSidebarContent: true, + }, + }, + }; + + + + + + + + + + + + + + diff --git a/rdviewAssets/assets.json b/rdviewAssets/assets.json new file mode 100644 index 0000000..0bad0ca --- /dev/null +++ b/rdviewAssets/assets.json @@ -0,0 +1,253 @@ +{ "frames": [ + { + "filename": "0.ase", + "frame": { "x": 0, "y": 0, "w": 327, "h": 160 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 327, "h": 160 }, + "sourceSize": { "w": 327, "h": 160 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.16-beta3-x64", + "image": "assets.png", + "format": "RGBA8888", + "size": { "w": 327, "h": 160 }, + "scale": "1", + "slices": [ + { "name": "event_SpinningRows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 246, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_SetMainWindow", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 246, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_RenameWindow", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 246, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_DesktopColor_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 249, "y": 20, "w": 8, "h": 5 }, "pivot": {"x": -3, "y": -6 } }] }, + { "name": "event_DesktopColor", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 232, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_HideWindow", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 232, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderWindows_3", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderWindows_2", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderWindows_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderWindows_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderWindows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 42, "w": 14, "h": 56 } }] }, + { "name": "event_ReorderRooms_3", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderRooms_2", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderRooms_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderRooms_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_CustomFlash_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 190, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_MacroEvent", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_ForwardEvent", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 64, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_ForwardDecorationEvent", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_ForwardRowEvent", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_SetWindowContent", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_WindowResize", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 64, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_Tile", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_Blend", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderSprite", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_ShakeScreenCustom", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 232, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderRow", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_NarrateRowInfo", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 176, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_ReadNarration", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 190, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "tab_icon_sounds", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 35, "y": 0, "w": 15, "h": 13 } }] }, + { "name": "tab_color_sounds", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 22, "y": 39, "w": 2, "h": 13 } }] }, + { "name": "content_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 80, "y": 106, "w": 5, "h": 5 }, "center": {"x": 2, "y": 2, "w": 1, "h": 1 } }] }, + { "name": "tab_icon_rows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 0, "y": 13, "w": 15, "h": 13 } }] }, + { "name": "tab_icon_actions", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 0, "y": 26, "w": 15, "h": 13 } }] }, + { "name": "tab_icon_rooms", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 0, "y": 39, "w": 15, "h": 13 } }] }, + { "name": "tab_icon_decorations", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 0, "y": 52, "w": 15, "h": 13 } }] }, + { "name": "tab_icon_windows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 0, "y": 65, "w": 15, "h": 13 } }] }, + { "name": "tab_color_rows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 24, "y": 39, "w": 2, "h": 13 } }] }, + { "name": "tab_color_actions", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 26, "y": 39, "w": 2, "h": 13 } }] }, + { "name": "tab_color_rooms", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 28, "y": 39, "w": 2, "h": 13 } }] }, + { "name": "tab_color_decorations", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 30, "y": 39, "w": 2, "h": 13 } }] }, + { "name": "tab_color_windows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 32, "y": 39, "w": 2, "h": 13 } }] }, + { "name": "tab_color_unknown", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 34, "y": 39, "w": 2, "h": 13 } }] }, + { "name": "tab_icon_unknown", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 0, "y": 78, "w": 15, "h": 13 } }] }, + { "name": "content_2", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 85, "y": 105, "w": 7, "h": 7 }, "center": {"x": 3, "y": 3, "w": 1, "h": 1 } }] }, + { "name": "event_Comment", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_ReorderRooms", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 42, "w": 14, "h": 56 } }] }, + { "name": "event_SetCrotchetsPerBar", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "event_PlaySong", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 0, "w": 28, "h": 14 } }] }, + { "name": "event_PlaySound", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 190, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_SetBeatsPerMinute", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 218, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_SetClapSounds", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 176, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_SetHeartExplodeVolume", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_SetHeartExplodeInterval", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "event_SetGameSound", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "event_SetBeatSound", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "event_SetCountingSound", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 176, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "event_SetOneshotWave", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_AddFreeTimeBeat", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 225, "y": 0, "w": 7, "h": 14 } }] }, + { "name": "event_PulseFreeTimeBeat", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 232, "y": 0, "w": 7, "h": 12 } }] }, + { "name": "event_SetTheme", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_SetVFXPreset", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 190, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_SetForeground", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_SetBackgroundColor", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_SetSpeed", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 204, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_Flash", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 190, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_CustomFlash", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 204, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_NewWindowDance", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_MoveCamera", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 176, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_PulseCamera", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_TextExplosion", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_ShowDialogue", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_ShowStatusSign", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_AdvanceText", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 218, "y": 0, "w": 7, "h": 14 } }] }, + { "name": "event_TintRows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "event_Tint", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 0, "w": 14, "h": 14 } }] }, + { "name": "event_TagAction", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_Stutter", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_ShowHands", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_ShakeScreen", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 204, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_SetVisible", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_SetRoomPerspective", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 64, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_SetRoomContentMode", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_SetPlayStyle", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 148, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_SetHandOwner", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_PaintHands", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 1, "w": 14, "h": 14 } }] }, + { "name": "event_PlayExpression", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_MoveRoom", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_MaskRoom", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_MoveRow", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 204, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_InvertColors", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 218, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_HideRow", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 42, "w": 14, "h": 14 } }] }, + { "name": "event_FlipScreen_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 218, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_FinishLevel", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 190, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_ChangePlayersRows", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 176, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_BassDrop", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 190, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_CallCustomMethod", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 176, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_PlayAnimation", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_Move", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 176, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_FadeRoom", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 64, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_Unknown", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 64, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "themes", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 15, "y": 39, "w": 7, "h": 13 } }] }, + { "name": "event_beat_pulse", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 98, "w": 3, "h": 14 }, "pivot": {"x": 1, "y": 0 } }] }, + { "name": "event_beat_hit", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 53, "y": 98, "w": 5, "h": 14 }, "pivot": {"x": 2, "y": 0 } }] }, + { "name": "event_beat_x", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 84, "y": 98, "w": 9, "h": 7 } }] }, + { "name": "char_0021", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 54, "y": 112, "w": 2, "h": 8 } }] }, + { "name": "char_0022", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 56, "y": 112, "w": 4, "h": 8 } }] }, + { "name": "char_0023", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 60, "y": 112, "w": 6, "h": 8 } }] }, + { "name": "char_0024", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 66, "y": 112, "w": 5, "h": 8 } }] }, + { "name": "char_0025", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 71, "y": 112, "w": 6, "h": 8 } }] }, + { "name": "char_0026", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 77, "y": 112, "w": 6, "h": 8 } }] }, + { "name": "char_0027", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 83, "y": 112, "w": 2, "h": 8 } }] }, + { "name": "char_0028", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 85, "y": 112, "w": 3, "h": 8 } }] }, + { "name": "char_0029", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 88, "y": 112, "w": 3, "h": 8 } }] }, + { "name": "char_002a", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 91, "y": 112, "w": 4, "h": 8 } }] }, + { "name": "char_002b", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 95, "y": 112, "w": 4, "h": 8 } }] }, + { "name": "char_002c", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 99, "y": 112, "w": 3, "h": 8 } }] }, + { "name": "char_002d", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 102, "y": 112, "w": 4, "h": 8 } }] }, + { "name": "char_002e", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 112, "w": 2, "h": 8 } }] }, + { "name": "char_002f", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 108, "y": 112, "w": 6, "h": 8 } }] }, + { "name": "char_0030", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0031", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 55, "y": 120, "w": 3, "h": 8 } }] }, + { "name": "char_0032", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 58, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0033", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 63, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0034", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 68, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0035", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 73, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0036", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0037", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 83, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0038", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 88, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0039", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 93, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_003a", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 98, "y": 120, "w": 2, "h": 8 } }] }, + { "name": "char_003b", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 100, "y": 120, "w": 2, "h": 8 } }] }, + { "name": "char_003c", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 102, "y": 120, "w": 4, "h": 8 } }] }, + { "name": "char_003d", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 120, "w": 4, "h": 8 } }] }, + { "name": "char_003e", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 110, "y": 120, "w": 4, "h": 8 } }] }, + { "name": "char_003f", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 114, "y": 120, "w": 5, "h": 8 } }] }, + { "name": "char_0040", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 128, "w": 6, "h": 8 } }] }, + { "name": "char_0041", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 56, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_0042", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 61, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_0043", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 66, "y": 128, "w": 4, "h": 8 } }] }, + { "name": "char_0044", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 70, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_0045", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 75, "y": 128, "w": 4, "h": 8 } }] }, + { "name": "char_0046", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 79, "y": 128, "w": 4, "h": 8 } }] }, + { "name": "char_0047", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 83, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_0048", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 88, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_0049", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 93, "y": 128, "w": 4, "h": 8 } }] }, + { "name": "char_004a", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 97, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_004b", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 102, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_004c", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 107, "y": 128, "w": 4, "h": 8 } }] }, + { "name": "char_004d", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 111, "y": 128, "w": 6, "h": 8 } }] }, + { "name": "char_004e", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 117, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_004f", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 122, "y": 128, "w": 5, "h": 8 } }] }, + { "name": "char_0050", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0051", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 55, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0052", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 60, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0053", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 65, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0054", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 70, "y": 136, "w": 4, "h": 8 } }] }, + { "name": "char_0055", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 74, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0056", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 79, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0057", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 84, "y": 136, "w": 6, "h": 8 } }] }, + { "name": "char_0058", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 90, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0059", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 95, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_005a", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 100, "y": 136, "w": 4, "h": 8 } }] }, + { "name": "char_005b", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 104, "y": 136, "w": 3, "h": 8 } }] }, + { "name": "char_005c", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 107, "y": 136, "w": 6, "h": 8 } }] }, + { "name": "char_005d", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 113, "y": 136, "w": 3, "h": 8 } }] }, + { "name": "char_005e", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 116, "y": 136, "w": 4, "h": 8 } }] }, + { "name": "char_005f", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 136, "w": 5, "h": 8 } }] }, + { "name": "char_0060", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 144, "w": 3, "h": 8 } }] }, + { "name": "char_0061", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 53, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_0062", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 58, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_0063", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 63, "y": 144, "w": 4, "h": 8 } }] }, + { "name": "char_0064", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 67, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_0065", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 72, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_0066", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 77, "y": 144, "w": 4, "h": 8 } }] }, + { "name": "char_0067", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 81, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_0068", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 86, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_0069", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 91, "y": 144, "w": 2, "h": 8 } }] }, + { "name": "char_006a", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 93, "y": 144, "w": 3, "h": 8 } }] }, + { "name": "char_006b", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 96, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_006c", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 101, "y": 144, "w": 2, "h": 8 } }] }, + { "name": "char_006d", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 103, "y": 144, "w": 6, "h": 8 } }] }, + { "name": "char_006e", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 109, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_006f", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 114, "y": 144, "w": 5, "h": 8 } }] }, + { "name": "char_0070", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_0071", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 55, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_0072", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 60, "y": 152, "w": 4, "h": 8 } }] }, + { "name": "char_0073", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 64, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_0074", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 69, "y": 152, "w": 4, "h": 8 } }] }, + { "name": "char_0075", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 73, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_0076", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 78, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_0077", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 83, "y": 152, "w": 6, "h": 8 } }] }, + { "name": "char_0078", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 89, "y": 152, "w": 4, "h": 8 } }] }, + { "name": "char_0079", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 93, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_007a", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 98, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_007b", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 103, "y": 152, "w": 4, "h": 8 } }] }, + { "name": "char_007c", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 107, "y": 152, "w": 2, "h": 8 } }] }, + { "name": "char_007d", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 109, "y": 152, "w": 4, "h": 8 } }] }, + { "name": "char_007e", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 113, "y": 152, "w": 5, "h": 8 } }] }, + { "name": "char_0020", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 112, "w": 4, "h": 8 } }] }, + { "name": "event_tag", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 239, "y": 0, "w": 6, "h": 6 } }] }, + { "name": "event_tag_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 239, "y": 6, "w": 6, "h": 6 } }] }, + { "name": "event_beat_loop", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 75, "y": 98, "w": 9, "h": 8 }, "pivot": {"x": 5, "y": 4 } }] }, + { "name": "event_beat_cross", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 108, "w": 3, "h": 3 }, "pivot": {"x": 1, "y": -6 } }] }, + { "name": "event_beat_hit_burn", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 63, "y": 98, "w": 7, "h": 14 }, "pivot": {"x": 3, "y": 0 } }] }, + { "name": "event_beat_synco", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 93, "y": 98, "w": 9, "h": 7 } }] }, + { "name": "event_beat_hit_freeze", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 58, "y": 98, "w": 5, "h": 14 }, "pivot": {"x": 2, "y": 0 } }] }, + { "name": "event_beat_skip", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 70, "y": 98, "w": 5, "h": 14 } }] }, + { "name": "event_beat_area", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 95, "y": 105, "w": 3, "h": 4 }, "center": {"x": 0, "y": 1, "w": 2, "h": 2 } }] }, + { "name": "event_beat_line", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 102, "y": 98, "w": 9, "h": 7 } }] }, + { "name": "event_CustomFlash_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 204, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_FlipScreen_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 232, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_FlipScreen", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 218, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_FlipScreen_2", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 232, "y": 70, "w": 14, "h": 14 } }] }, + { "name": "event_FloatingText_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 204, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_FloatingText_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 218, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_PaintHands_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_PaintHands_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_SetBackgroundColor_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 56, "w": 14, "h": 14 } }] }, + { "name": "event_SetBackgroundColor_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 137, "y": 60, "w": 8, "h": 6 }, "pivot": {"x": -3, "y": -4 } }] }, + { "name": "event_SetForeground_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 137, "y": 74, "w": 7, "h": 5 }, "pivot": {"x": -3, "y": -4 } }] }, + { "name": "event_Tint_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_Tint_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 106, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_TintRows_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 14, "w": 14, "h": 14 } }] }, + { "name": "event_TintRows_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 28, "w": 14, "h": 14 } }] }, + { "name": "event_ShowRooms_1", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 162, "y": 98, "w": 28, "h": 28 } }] }, + { "name": "event_ShowRooms_0", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 134, "y": 98, "w": 28, "h": 28 } }] }, + { "name": "event_ChangeCharacter", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 120, "y": 84, "w": 14, "h": 14 } }] }, + { "name": "event_SetRowXs", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 50, "y": 14, "w": 28, "h": 14 } }] }, + { "name": "event_outline", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 75, "y": 106, "w": 5, "h": 5 }, "center": {"x": 2, "y": 2, "w": 1, "h": 1 } }] }, + { "name": "event_back", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 92, "y": 105, "w": 3, "h": 3 }, "center": {"x": 1, "y": 1, "w": 1, "h": 1 } }] } + ] + } +} diff --git a/rdviewAssets/assets.png b/rdviewAssets/assets.png new file mode 100644 index 0000000000000000000000000000000000000000..028437289ecd91c8cf7f7f3d6d22d8d1858cb389 GIT binary patch literal 7459 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 e3T3o6v}%bdywNuO;kUn@01Xvg= this.left && point.x <= this.right && point.y >= this.top && point.y <= this.bottom; + } +}; +var Color = class _Color { + red; + green; + blue; + alpha; + constructor(r, g, b, a) { + if (typeof r === "string") { + if (r.startsWith("#")) { + r = r.substring(1); + } + r = r.trim(); + switch (r.length) { + case 3: + r = r.split("").map((c) => c + c).join(""); + break; + case 4: + r = "ff" + r.split("").map((c) => c + c).join(""); + break; + case 6: + r = "ff" + r; + break; + case 8: + break; + default: + r = "ffffffff"; + } + const u = parseInt(r, 16); + this.alpha = u >> 24 & 255; + this.red = u >> 16 & 255; + this.green = u >> 8 & 255; + this.blue = u & 255; + return; + } + if (r !== void 0 && g === void 0 && b === void 0 && a === void 0) { + this.alpha = r >> 24 & 255; + this.red = r >> 16 & 255; + this.green = r >> 8 & 255; + this.blue = r & 255; + return; + } + if (r !== void 0 && g !== void 0 && b !== void 0 && a === void 0) { + this.red = r; + this.green = g; + this.blue = b; + this.alpha = 255; + return; + } + this.red = r ?? 0; + this.green = g ?? 0; + this.blue = b ?? 0; + this.alpha = a ?? 0; + } + toUint32() { + return ((this.alpha & 255) << 24 | (this.red & 255) << 16 | (this.green & 255) << 8 | this.blue & 255) >>> 0; + } + clone() { + return new _Color(this.red, this.green, this.blue, this.alpha); + } +}; +var Paint = class { + color = new Color(255, 255, 255, 255); +}; +var SliceInfo = class { + bounds = new Rect(); + center = new Rect(); + pivot = new Point(); + scale = 1; + get isNinePatch() { + return !this.center.isEmpty; + } +}; +var AssetManager = class _AssetManager { + static AssetFilePath = "assets.png"; + static SlicesFilePath = "assets.json"; + static DirectoryPath = "."; + static assetFile = null; + static slices = /* @__PURE__ */ new Map(); + static _isLoaded = false; + constructor(dirpath) { + _AssetManager.DirectoryPath = dirpath; + _AssetManager.initialize(); + } + static get isLoaded() { + return this._isLoaded; + } + static async loadAssetFile() { + const pngPath = _AssetManager.DirectoryPath + "/" + this.AssetFilePath; + return await new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = (e) => reject(new Error(`Failed to load asset file: ${pngPath}`)); + img.src = pngPath; + }); + } + static async loadSlices() { + if (this._isLoaded) { + return /* @__PURE__ */ new Map(); + } + const jsonPath = _AssetManager.DirectoryPath + "/" + this.SlicesFilePath; + const response = await fetch(jsonPath); + const json = await response.json(); + const slices = json["meta"]["slices"]; + const sliceInfos = /* @__PURE__ */ new Map(); + for (const slice of slices) { + const name = slice["name"]; + const keys = slice["keys"]; + const sliceInfo = new SliceInfo(); + for (const key of keys) { + const bounds = key["bounds"]; + sliceInfo.bounds.left = bounds["x"]; + sliceInfo.bounds.top = bounds["y"]; + sliceInfo.bounds.right = bounds["x"] + bounds["w"]; + sliceInfo.bounds.bottom = bounds["y"] + bounds["h"]; + const center = key["center"]; + if (center) { + sliceInfo.center.left = center["x"]; + sliceInfo.center.top = center["y"]; + sliceInfo.center.right = center["x"] + center["w"]; + sliceInfo.center.bottom = center["y"] + center["h"]; + } + const pivot = key["pivot"]; + if (pivot) { + sliceInfo.pivot.x = pivot["x"]; + sliceInfo.pivot.y = pivot["y"]; + } + const data = key["data"]; + if (data) { + } + sliceInfos.set(name, sliceInfo); + } + } + return sliceInfos; + } + static async initialize() { + if (this._isLoaded) { + return; + } + this.assetFile = await this.loadAssetFile(); + this.slices = await this.loadSlices(); + this._isLoaded = true; + } +}; + +// RhythmBase.View/Assets/Consts.ts +var Tab = /* @__PURE__ */ function(Tab2) { + Tab2["Sounds"] = "sounds"; + Tab2["Rows"] = "rows"; + Tab2["Actions"] = "actions"; + Tab2["Decorations"] = "decorations"; + Tab2["Rooms"] = "rooms"; + Tab2["Windows"] = "windows"; + Tab2["Unknown"] = "unknown"; + return Tab2; +}({}); +var EventType = /* @__PURE__ */ function(EventType2) { + EventType2["AddClassicBeat"] = "AddClassicBeat"; + EventType2["AddFreeTimeBeat"] = "AddFreeTimeBeat"; + EventType2["AddOneshotBeat"] = "AddOneshotBeat"; + EventType2["AdvanceText"] = "AdvanceText"; + EventType2["BassDrop"] = "BassDrop"; + EventType2["Blend"] = "Blend"; + EventType2["CallCustomMethod"] = "CallCustomMethod"; + EventType2["ChangeCharacter"] = "ChangeCharacter"; + EventType2["ChangePlayersRows"] = "ChangePlayersRows"; + EventType2["Comment"] = "Comment"; + EventType2["CustomFlash"] = "CustomFlash"; + EventType2["DesktopColor"] = "DesktopColor"; + EventType2["FadeRoom"] = "FadeRoom"; + EventType2["FinishLevel"] = "FinishLevel"; + EventType2["Flash"] = "Flash"; + EventType2["FlipScreen"] = "FlipScreen"; + EventType2["FloatingText"] = "FloatingText"; + EventType2["ForwardDecorationEvent"] = "ForwardDecorationEvent"; + EventType2["ForwardEvent"] = "ForwardEvent"; + EventType2["ForwardRowEvent"] = "ForwardRowEvent"; + EventType2["HideRow"] = "HideRow"; + EventType2["HideWindow"] = "HideWindow"; + EventType2["InvertColors"] = "InvertColors"; + EventType2["MacroEvent"] = "MacroEvent"; + EventType2["MaskRoom"] = "MaskRoom"; + EventType2["Move"] = "Move"; + EventType2["MoveCamera"] = "MoveCamera"; + EventType2["MoveRoom"] = "MoveRoom"; + EventType2["MoveRow"] = "MoveRow"; + EventType2["NarrateRowInfo"] = "NarrateRowInfo"; + EventType2["NewWindowDance"] = "NewWindowDance"; + EventType2["PaintHands"] = "PaintHands"; + EventType2["PlayAnimation"] = "PlayAnimation"; + EventType2["PlayExpression"] = "PlayExpression"; + EventType2["PlaySong"] = "PlaySong"; + EventType2["PlaySound"] = "PlaySound"; + EventType2["PulseCamera"] = "PulseCamera"; + EventType2["PulseFreeTimeBeat"] = "PulseFreeTimeBeat"; + EventType2["ReadNarration"] = "ReadNarration"; + EventType2["RenameWindow"] = "RenameWindow"; + EventType2["ReorderRooms"] = "ReorderRooms"; + EventType2["ReorderRow"] = "ReorderRow"; + EventType2["ReorderSprite"] = "ReorderSprite"; + EventType2["ReorderWindows"] = "ReorderWindows"; + EventType2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; + EventType2["SetBackgroundColor"] = "SetBackgroundColor"; + EventType2["SetBeatSound"] = "SetBeatSound"; + EventType2["SetBeatsPerMinute"] = "SetBeatsPerMinute"; + EventType2["SetClapSounds"] = "SetClapSounds"; + EventType2["SetCountingSound"] = "SetCountingSound"; + EventType2["SetCrotchetsPerBar"] = "SetCrotchetsPerBar"; + EventType2["SetForeground"] = "SetForeground"; + EventType2["SetGameSound"] = "SetGameSound"; + EventType2["SetHandOwner"] = "SetHandOwner"; + EventType2["SetHeartExplodeInterval"] = "SetHeartExplodeInterval"; + EventType2["SetHeartExplodeVolume"] = "SetHeartExplodeVolume"; + EventType2["SetMainWindow"] = "SetMainWindow"; + EventType2["SetOneshotWave"] = "SetOneshotWave"; + EventType2["SetPlayStyle"] = "SetPlayStyle"; + EventType2["SetRoomContentMode"] = "SetRoomContentMode"; + EventType2["SetRoomPerspective"] = "SetRoomPerspective"; + EventType2["SetRowXs"] = "SetRowXs"; + EventType2["SetSpeed"] = "SetSpeed"; + EventType2["SetTheme"] = "SetTheme"; + EventType2["SetVFXPreset"] = "SetVFXPreset"; + EventType2["SetVisible"] = "SetVisible"; + EventType2["SetWindowContent"] = "SetWindowContent"; + EventType2["ShakeScreen"] = "ShakeScreen"; + EventType2["ShakeScreenCustom"] = "ShakeScreenCustom"; + EventType2["ShowDialogue"] = "ShowDialogue"; + EventType2["ShowHands"] = "ShowHands"; + EventType2["ShowRooms"] = "ShowRooms"; + EventType2["ShowStatusSign"] = "ShowStatusSign"; + EventType2["ShowSubdivisionsRows"] = "ShowSubdivisionsRows"; + EventType2["SpinningRows"] = "SpinningRows"; + EventType2["Stutter"] = "Stutter"; + EventType2["TagAction"] = "TagAction"; + EventType2["TextExplosion"] = "TextExplosion"; + EventType2["Tile"] = "Tile"; + EventType2["Tint"] = "Tint"; + EventType2["TintRows"] = "TintRows"; + EventType2["WindowResize"] = "WindowResize"; + return EventType2; +}({}); +var EventAttriblte = /* @__PURE__ */ function(EventAttriblte2) { + EventAttriblte2[EventAttriblte2["None"] = 0] = "None"; + EventAttriblte2[EventAttriblte2["DurationEvent"] = 1] = "DurationEvent"; + EventAttriblte2[EventAttriblte2["RoomEvent"] = 2] = "RoomEvent"; + return EventAttriblte2; +}({}); +var EventInfo = class { + defaultTab; + durationKey = "duration"; + attr; + get isDurationEvent() { + return (this.attr & EventAttriblte.DurationEvent) !== 0; + } + get isRoomEvent() { + return (this.attr & EventAttriblte.RoomEvent) !== 0; + } + constructor(tab, enumAttriblte, durationKey) { + this.defaultTab = tab; + this.attr = enumAttriblte ?? EventAttriblte.None; + if (durationKey !== void 0) { + this.durationKey = durationKey; + } + } +}; +var WordInfo = class { + phrase; + length; + constructor(phrase, length) { + this.phrase = phrase; + this.length = length; + } +}; +var WordInfos = { + SayReaDyGetSetGoNew: new WordInfo("Rea, Dy, Get, Set, Go!", 4), + SayReaDyGetSetOne: new WordInfo("Rea, Dy, Get, Set, One!", 4), + SayGetSetGo: new WordInfo("Get, Set, Go!", 2), + SayGetSetOne: new WordInfo("Get, Set, One!", 2), + JustSayRea: new WordInfo("Rea", 0), + JustSayDy: new WordInfo("Dy", 0), + JustSayGet: new WordInfo("Get", 0), + JustSaySet: new WordInfo("Set", 0), + JustSayAnd: new WordInfo("And", 0), + JustSayGo: new WordInfo("Go!", 0), + JustSayStop: new WordInfo("Stop", 0), + JustSayAndStop: new WordInfo("And Stop!", 0), + SaySwitch: new WordInfo("Switch", 0), + SayWatch: new WordInfo("Watch", 0), + SayListen: new WordInfo("Listen", 0), + Count1: new WordInfo("1", 0), + Count2: new WordInfo("2", 0), + Count3: new WordInfo("3", 0), + Count4: new WordInfo("4", 0), + Count5: new WordInfo("5", 0), + Count6: new WordInfo("6", 0), + Count7: new WordInfo("7", 0), + Count8: new WordInfo("8", 0), + Count9: new WordInfo("9", 0), + Count10: new WordInfo("10", 0), + SayReadyGetSetGo: new WordInfo("Ready, Get, Set, Go!", 4), + JustSayReady: new WordInfo("Ready", 0) +}; +var EventInfos = { + AddClassicBeat: new EventInfo(Tab.Rows), + AddFreeTimeBeat: new EventInfo(Tab.Rows), + AddOneshotBeat: new EventInfo(Tab.Rows), + AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + BassDrop: new EventInfo(Tab.Actions), + Blend: new EventInfo(Tab.Decorations), + CallCustomMethod: new EventInfo(Tab.Actions), + ChangeCharacter: new EventInfo(Tab.Actions), + ChangePlayersRows: new EventInfo(Tab.Actions), + Comment: new EventInfo(Tab.Unknown), + CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), + FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + FinishLevel: new EventInfo(Tab.Actions), + Flash: new EventInfo(Tab.Actions), + FlipScreen: new EventInfo(Tab.Actions), + FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ForwardDecorationEvent: new EventInfo(Tab.Decorations), + ForwardEvent: new EventInfo(Tab.Unknown), + ForwardRowEvent: new EventInfo(Tab.Rows), + HideRow: new EventInfo(Tab.Actions), + HideWindow: new EventInfo(Tab.Windows), + InvertColors: new EventInfo(Tab.Actions), + MacroEvent: new EventInfo(Tab.Unknown), + MaskRoom: new EventInfo(Tab.Rooms), + Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), + MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + MoveRow: new EventInfo(Tab.Rows, EventAttriblte.DurationEvent), + NarrateRowInfo: new EventInfo(Tab.Sounds), + NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + PlayAnimation: new EventInfo(Tab.Decorations), + PlayExpression: new EventInfo(Tab.Actions), + PlaySong: new EventInfo(Tab.Sounds), + PlaySound: new EventInfo(Tab.Sounds), + PulseCamera: new EventInfo(Tab.Actions), + PulseFreeTimeBeat: new EventInfo(Tab.Rows), + ReadNarration: new EventInfo(Tab.Sounds), + RenameWindow: new EventInfo(Tab.Windows), + ReorderRooms: new EventInfo(Tab.Rooms), + ReorderRow: new EventInfo(Tab.Rows), + ReorderSprite: new EventInfo(Tab.Decorations), + ReorderWindows: new EventInfo(Tab.Windows), + SayReadyGetSetGo: new EventInfo(Tab.Sounds), + SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetBeatSound: new EventInfo(Tab.Sounds), + SetBeatsPerMinute: new EventInfo(Tab.Sounds), + SetClapSounds: new EventInfo(Tab.Sounds), + SetCountingSound: new EventInfo(Tab.Sounds), + SetCrotchetsPerBar: new EventInfo(Tab.Sounds), + SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetGameSound: new EventInfo(Tab.Sounds), + SetHandOwner: new EventInfo(Tab.Actions), + SetHeartExplodeInterval: new EventInfo(Tab.Sounds), + SetHeartExplodeVolume: new EventInfo(Tab.Sounds), + SetMainWindow: new EventInfo(Tab.Windows), + SetOneshotWave: new EventInfo(Tab.Rows), + SetPlayStyle: new EventInfo(Tab.Actions), + SetRoomContentMode: new EventInfo(Tab.Rooms), + SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + SetRowXs: new EventInfo(Tab.Rows), + SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetVisible: new EventInfo(Tab.Decorations), + SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), + ShakeScreen: new EventInfo(Tab.Actions), + ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ShowDialogue: new EventInfo(Tab.Actions), + ShowHands: new EventInfo(Tab.Actions), + ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ShowSubdivisionsRows: new EventInfo(Tab.Actions), + SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + Stutter: new EventInfo(Tab.Actions), + TagAction: new EventInfo(Tab.Actions), + TextExplosion: new EventInfo(Tab.Actions), + Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), + Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), + TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent) +}; + +// RhythmBase.View/Extensions.ts +var PatchStyle = /* @__PURE__ */ function(PatchStyle2) { + PatchStyle2[PatchStyle2["Repeat"] = 0] = "Repeat"; + PatchStyle2[PatchStyle2["Strentch"] = 1] = "Strentch"; + return PatchStyle2; +}(PatchStyle || {}); +var IconStyle = class { + Enabled; + Active = false; + Hover = false; + Scale = 2; +}; +var Extensions = class { + static lineHeight = 6; + static charHeight = 8; + static iconSize = 14; + static evtag = "event_tag"; + static evbarea = "event_beat_area"; + static asm = new AssetManager("./rdviewAssets"); + constructor() { + AssetManager.initialize(); + } + static DrawSlice(canvas, src, dest, scale = 1, style = PatchStyle.Strentch, color) { + const ctx = canvas; + if (!ctx) return; + if (!AssetManager.slices.has(src)) { + return; + } + const info = AssetManager.slices.get(src); + if (dest instanceof Point) { + const destRect = new Rect(dest.x - info.pivot.x * scale, dest.y - info.pivot.y * scale, info.bounds.width * scale, info.bounds.height * scale); + if (color) { + if (color.alpha === 0) { + return destRect; + } + this.drawSliceWithColor(ctx, info, destRect, color); + } else { + this.drawSliceNormal(ctx, info, destRect); + } + return destRect; + } else { + if (info.isNinePatch) { + this.DrawNinePatch(canvas, info, dest, color, scale, style); + } else { + if (color) { + this.drawSliceWithColor(ctx, info, dest, color); + } else { + this.drawSliceNormal(ctx, info, dest); + } + } + } + } + static drawSliceNormal(ctx, info, destRect) { + const bitmap = AssetManager.assetFile; + if (!bitmap) return; + ctx.imageSmoothingEnabled = false; + ctx.drawImage(bitmap, info.bounds.x, info.bounds.y, info.bounds.width, info.bounds.height, destRect.x, destRect.y, destRect.width, destRect.height); + } + static drawSliceWithColor(ctx, info, destRect, color) { + const bitmap = AssetManager.assetFile; + if (!bitmap) return; + if (color.alpha === 0) { + return; + } + const tr = color.red / 255; + const tg = color.green / 255; + const tb = color.blue / 255; + const ta = color.alpha / 255; + ctx.save(); + const tempCanvas = typeof document !== "undefined" ? document.createElement("canvas") : {}; + tempCanvas.width = info.bounds.width; + tempCanvas.height = info.bounds.height; + const tempCtx = tempCanvas.getContext("2d"); + tempCtx.imageSmoothingEnabled = false; + tempCtx.drawImage(bitmap, info.bounds.x, info.bounds.y, info.bounds.width, info.bounds.height, 0, 0, info.bounds.width, info.bounds.height); + const imageData = tempCtx.getImageData(0, 0, info.bounds.width, info.bounds.height); + const data = imageData.data; + for (let i = 0; i < data.length; i += 4) { + const originalAlpha = data[i + 3]; + const gray = data[i] * 0.2126 + data[i + 1] * 0.7152 + data[i + 2] * 0.0722; + data[i] = gray * tr; + data[i + 1] = gray * tg; + data[i + 2] = gray * tb; + data[i + 3] = originalAlpha * ta; + } + tempCtx.putImageData(imageData, 0, 0); + ctx.imageSmoothingEnabled = false; + ctx.globalAlpha = 1; + ctx.drawImage(tempCanvas, 0, 0, info.bounds.width, info.bounds.height, destRect.x, destRect.y, destRect.width, destRect.height); + ctx.restore(); + } + static DrawNinePatch(canvas, info, dest, color, scale = 1, style = PatchStyle.Strentch) { + const ctx = canvas; + if (!ctx) return; + const bitmap = AssetManager.assetFile; + if (!bitmap) return; + const srcBounds = info.bounds; + const destRect = dest; + const centerBounds = info.center; + const sx0 = srcBounds.left; + const sx3 = srcBounds.right; + const sy0 = srcBounds.top; + const sy3 = srcBounds.bottom; + const sx1 = sx0 + centerBounds.left; + const sx2 = sx0 + centerBounds.right; + const sy1 = sy0 + centerBounds.top; + const sy2 = sy0 + centerBounds.bottom; + const swLeft = sx1 - sx0; + const swCenter = sx2 - sx1; + const swRight = sx3 - sx2; + const shTop = sy1 - sy0; + const shCenter = sy2 - sy1; + const shBottom = sy3 - sy2; + const dwLeft = swLeft * scale; + let dwRight = swRight * scale; + let dwCenter = destRect.width - dwLeft - dwRight; + if (dwCenter < 0) { + const scaleX = destRect.width / Math.max(1, swLeft + swRight); + dwRight = Math.max(0, destRect.width - Math.round(swLeft * scaleX)); + dwCenter = 0; + } + const dhTop = shTop * scale; + let dhBottom = shBottom * scale; + let dhCenter = destRect.height - dhTop - dhBottom; + if (dhCenter < 0) { + const scaleY = destRect.height / Math.max(1, shTop + shBottom); + dhBottom = Math.max(0, destRect.height - Math.round(shTop * scaleY)); + dhCenter = 0; + } + const srcXs = [ + sx0, + sx1, + sx2, + sx3 + ]; + const srcYs = [ + sy0, + sy1, + sy2, + sy3 + ]; + const dx0 = destRect.left; + const dx1 = dx0 + dwLeft; + const dx2 = dx1 + dwCenter; + const dx3 = destRect.right; + const dy0 = destRect.top; + const dy1 = dy0 + dhTop; + const dy2 = dy1 + dhCenter; + const dy3 = destRect.bottom; + const dstXs = [ + dx0, + dx1, + dx2, + dx3 + ]; + const dstYs = [ + dy0, + dy1, + dy2, + dy3 + ]; + for (let row = 0; row < 3; row++) { + for (let col = 0; col < 3; col++) { + const sLeft = srcXs[col]; + const sTop = srcYs[row]; + const sRight = srcXs[col + 1]; + const sBottom = srcYs[row + 1]; + const sW = sRight - sLeft; + const sH = sBottom - sTop; + if (sW <= 0 || sH <= 0) continue; + const dLeft = dstXs[col]; + const dTop = dstYs[row]; + const dRight = dstXs[col + 1]; + const dBottom = dstYs[row + 1]; + const dW = dRight - dLeft; + const dH = dBottom - dTop; + if (dW <= 0 || dH <= 0) continue; + if (style === PatchStyle.Repeat) { + for (let y = dTop; y < dBottom; y += sH * scale) { + const th = Math.min(sH, (dBottom - y) / scale); + for (let x = dLeft; x < dRight; x += sW * scale) { + const tw = Math.min(sW, (dRight - x) / scale); + var sRect = new Rect(sLeft, sTop, tw, th); + var dRect = new Rect(x, y, tw * scale, th * scale); + if (color && color.alpha > 0) { + this.drawSliceWithColor(ctx, { + bounds: sRect, + pivot: new Point(0, 0), + isNinePatch: false, + center: new Rect(), + scale: 1 + }, dRect, color); + } else { + this.drawSliceNormal(ctx, { + bounds: sRect, + pivot: new Point(0, 0), + isNinePatch: false, + center: new Rect(), + scale: 1 + }, dRect); + } + } + } + } else { + if (color && color.alpha > 0) { + this.drawSliceWithColor(ctx, { + bounds: new Rect(sLeft, sTop, sW, sH), + pivot: new Point(0, 0), + isNinePatch: false, + center: new Rect(), + scale: 1 + }, new Rect(dLeft, dTop, dW, dH), color); + } else { + ctx.imageSmoothingEnabled = false; + ctx.drawImage(bitmap, sLeft, sTop, sW, sH, dLeft, dTop, dW, dH); + } + } + } + } + } + static MeasureRDFontText(canvas, text, scale = 1) { + let len = 0; + for (let i = 0; i < text.length; i++) { + const c = text.charAt(i); + if (c === "\n") { + len = 0; + } else { + const info = AssetManager.slices.get(`char_${c.charCodeAt(0).toString(16).padStart(4, "0")}`); + if (info) { + len += info.bounds.width * scale; + } + } + } + return len; + } + static DrawRDFontText(canvas, text, dest, color, scale = 1) { + const start = dest.clone(); + const result = new Rect(); + start.y -= this.lineHeight * scale; + for (let i = 0; i < text.length; i++) { + const c = text.charAt(i); + if (c === "\n") { + start.x = dest.x; + start.y += this.lineHeight * scale; + continue; + } else { + const charcode = c.charCodeAt(0).toString(16).padStart(4, "0"); + const area = this.DrawSlice(canvas, `char_${charcode}`, start, scale, PatchStyle.Strentch, color); + result.union(area); + start.x += area.width * scale; + } + } + return result; + } + static DrawEventIcon(canvas, evt, dest, style) { + let destRect = new Rect(); + const key = `event_${evt.type}`; + const evttype = evt.type; + const info = AssetManager.slices.get(key) ?? AssetManager.slices.get("event_Unknown") ?? (() => { + throw new Error("information not found."); + }); + if (!(info instanceof SliceInfo)) { + return new Rect(); + } + const pulse = "event_beat_pulse"; + const hit = "event_beat_hit"; + const hitf = "event_beat_hit_freeze"; + const hitb = "event_beat_hit_burn"; + const beatcross = "event_beat_cross"; + const beatx = "event_beat_x"; + const beatsynco = "event_beat_synco"; + const beatline = "event_beat_line"; + const beatcolor = new Color(4284539717); + const evtInfo = EventInfos[evt.type]; + evt.tab = evt.tab ?? evtInfo.defaultTab; + switch (evt.type) { + case EventType.AddClassicBeat: + { + const tick = evt.tick ?? 1; + const swing = evt.swing === 0 ? 1 : evt.swing; + const hold = evt.hold ?? 0; + const syncoswing = evt.syncoSwing ?? 0; + const syncobeat = evt.syncoBeat ?? -1; + const classicbeatlength = evt.length ?? 7; + destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale * (tick * (classicbeatlength - 1 - (syncoswing ?? 0))), this.iconSize * style.Scale); + if (hold > 0) { + this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, this.iconSize * style.Scale * hold, this.iconSize * style.Scale), style.Scale, PatchStyle.Repeat, new Color(style.Active ? 4291839731 : 4286462352)); + } + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + if (style.Hover) { + for (let i = 0; i < classicbeatlength - 1; i++) { + this.DrawSlice(canvas, pulse, new Point(dest.x + this.iconSize * style.Scale * (tick * (i + i % 2 * (1 - (swing ?? 1)) - (i <= (syncobeat ?? -1) ? 0 : syncoswing ?? 0))), dest.y), style.Scale); + } + } + this.DrawSlice(canvas, hit, new Point(dest.x + style.Scale * (this.iconSize * (tick * (classicbeatlength - 1 - (syncoswing ?? 0))) - 1), dest.y), style.Scale); + } + break; + case EventType.AddFreeTimeBeat: + { + const hold = (evt.hold ?? 0) - info.bounds.width / this.iconSize; + destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(beatcolor.clone(), style.Active, style.Enabled ?? evt.active ?? true), style); + this.DrawRDFontText(canvas, ((evt.pulse ?? 0) + 1).toString(), new Point(dest.x + 1.5 * style.Scale, dest.y + 10 * style.Scale), new Color(4294967295), style.Scale); + if ((evt.pulse ?? 0) == 6) { + this.DrawSlice(canvas, hit, new Point(dest.x, dest.y), style.Scale); + } + if (hold > 0) { + this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, this.iconSize * style.Scale * hold, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(style.Active ? 4284539717 : 4281299234)); + } + } + break; + case EventType.AddOneshotBeat: + { + const tick = evt.tick ?? 1; + const interval = evt.interval ?? 1; + const loop = Math.floor(evt.loops ?? 0); + const subdiv = evt.subdivisions ?? 1; + const freezeBurnMode = evt.freezeBurnMode ?? "Wave"; + const delay = freezeBurnMode === "Freezeshot" ? evt.delay ?? 0 : 0; + destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale * (loop * interval + tick + delay), this.iconSize * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + const subdivwidth = this.iconSize * style.Scale * (subdiv - 1) / subdiv * tick; + if (subdiv > 1) { + this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, subdivwidth, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(4279480353)); + } + if (evt.skipshot ?? false) { + this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width + subdivwidth, dest.y, style.Scale * this.iconSize * interval - subdivwidth, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(4291115835)); + } + if (style.Hover) { + for (let l = 0; l <= loop; l++) { + for (let i = 0; i < subdiv; i++) { + this.DrawSlice(canvas, pulse, new Point(dest.x + this.iconSize * style.Scale * (l * interval + i * tick / subdiv), dest.y), style.Scale); + } + } + } + for (let l = 0; l <= loop; l++) { + for (let i = 0; i < subdiv; i++) { + this.DrawSlice(canvas, hit, new Point(dest.x + style.Scale * (this.iconSize * (l * interval + delay + tick + i * tick / subdiv) - 1), dest.y), style.Scale); + } + } + const off = interval - tick; + if (freezeBurnMode !== "Wave") { + let posx = dest.x - off * style.Scale * this.iconSize; + this.DrawSlice(canvas, beatcross, new Point(posx, dest.y), style.Scale); + switch (freezeBurnMode) { + case "Freezeshot": + posx += delay * style.Scale * this.iconSize; + this.DrawSlice(canvas, beatcross, new Point(posx, dest.y), style.Scale); + for (let l = 0; l <= loop; l++) { + this.DrawSlice(canvas, hitf, new Point(dest.x + style.Scale * (this.iconSize * (l * interval + tick) - 1), dest.y), style.Scale); + } + break; + case "Burnshot": + posx -= tick * style.Scale * this.iconSize; + this.DrawSlice(canvas, beatcross, new Point(posx, dest.y), style.Scale); + for (let l = 0; l <= loop; l++) { + this.DrawSlice(canvas, hitb, new Point(dest.x + style.Scale * (this.iconSize * (l * interval + tick) - 1), dest.y), style.Scale); + } + break; + default: + break; + } + } + if (style.Active && style.Hover) { + this.DrawSlice(canvas, "event_beat_loop", new Point(destRect.right, destRect.top), style.Scale); + } + } + break; + case EventType.Comment: + { + const commentColor = new Color(evt.color); + console.log(evt.color, commentColor); + destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(commentColor, style.Active, style.Enabled ?? evt.active ?? true), style); + this.DrawSlice(canvas, key, dest, style.Scale); + } + break; + case EventType.DesktopColor: + { + destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * 4 * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + const endColor = new Color(evt.endColor); + this.DrawSlice(canvas, `${key}_0`, new Point(dest.x, dest.y + info.bounds.height * style.Scale), style.Scale, PatchStyle.Strentch, endColor); + this.DrawSlice(canvas, key, new Point(dest.x, dest.y + info.bounds.height * style.Scale), style.Scale); + } + break; + case EventType.PulseFreeTimeBeat: + { + const hold = (evt.hold ?? 0) - info.bounds.width / this.iconSize; + destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(beatcolor.clone(), style.Active, style.Enabled ?? evt.active ?? true), style); + let actionText; + switch (evt.action) { + case "Increment": + actionText = ">"; + break; + case "Decrement": + actionText = "<"; + break; + case "Remove": + actionText = "x"; + break; + case "Custom": + default: + actionText = ((evt.customPulse ?? 0) + 1).toString(); + break; + } + this.DrawRDFontText(canvas, actionText, new Point(dest.x + 1.5 * style.Scale, dest.y + 8 * style.Scale), new Color(4294967295), style.Scale); + if (evt.action === "Custom" && (evt.customPulse ?? 0) === 7) { + this.DrawSlice(canvas, hit, new Rect(dest.x - 2 * style.Scale, dest.y, 5 * style.Scale, info.bounds.height * style.Scale), style.Scale, PatchStyle.Strentch); + } + if (hold > 0) { + this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, this.iconSize * style.Scale * hold, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(style.Active ? 4291839731 : 4286462352)); + } + } + break; + case EventType.ReorderRooms: + { + destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale, this.iconSize * 4 * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + let currentDest = dest.clone(); + if (evt.order && Array.isArray(evt.order)) { + for (const r of evt.order) { + this.DrawSlice(canvas, `${key}_${r}`, currentDest.clone(), style.Scale); + currentDest.y += this.iconSize * style.Scale; + } + } + } + break; + case EventType.ReorderWindows: + { + destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale, this.iconSize * 4 * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + let currentDest = dest.clone(); + if (evt.order && Array.isArray(evt.order)) { + for (const r of evt.order) { + this.DrawSlice(canvas, `${key}_${r}`, currentDest.clone(), style.Scale); + currentDest.y += this.iconSize * style.Scale; + } + } + } + break; + case EventType.SayReadyGetSetGo: + { + const wordInfo = WordInfos[evt.phraseToSay]; + const len = wordInfo.length * evt.tick + 1; + destRect = new Rect(dest.x, dest.y, len * this.iconSize * style.Scale, this.iconSize * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + const stringToJion = wordInfo.phrase.split(" "); + let stringToDraw = [ + stringToJion[0] + ]; + let lw = this.MeasureRDFontText(canvas, stringToJion[0]); + const sw = this.MeasureRDFontText(canvas, " "); + for (let i = 1; i < stringToJion.length; i++) { + const part = stringToJion[i]; + const w = this.MeasureRDFontText(canvas, part); + if (lw + sw + w > (len * this.iconSize - 2) * style.Scale) { + lw = w; + stringToDraw.push(part); + } else { + lw += sw + w; + stringToDraw[stringToDraw.length - 1] += " " + part; + } + } + stringToDraw.splice(3); + const c = stringToDraw.length; + const top = dest.y + (this.iconSize - this.charHeight * c / 2) * style.Scale / 2; + for (let i = 0; i < c; i++) { + const line = stringToDraw[i]; + const p = new Point(dest.x + (len * this.iconSize * style.Scale - this.MeasureRDFontText(canvas, line, style.Scale / 2)) / 2, top + (i * this.charHeight + this.lineHeight) * style.Scale / 2); + this.DrawRDFontText(canvas, line, p, new Color(4294967295), style.Scale / 2); + } + } + break; + case EventType.SetRowXs: + { + destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + const width = info.bounds.width * style.Scale / 6; + const beatxInfo = AssetManager.slices.get(beatx); + if (!beatxInfo) break; + const iconwidth = beatxInfo.bounds.width; + const s = width / iconwidth; + let left = 0; + const top = this.iconSize * style.Scale / 2 - beatxInfo.bounds.height * s / 2; + if (evt.pattern) { + const pattern = evt.pattern; + for (const p of pattern) { + const patternKey = p === "x" ? beatx : beatline; + this.DrawSlice(canvas, patternKey, new Rect(dest.x + left, dest.y + top, width, beatxInfo.bounds.height * s), style.Scale, PatchStyle.Strentch); + left += width; + } + } + if ((evt.syncoBeat ?? -1) >= 0) { + this.DrawSlice(canvas, beatsynco, new Rect(dest.x + width * (evt.syncoBeat ?? 0), dest.y + top, width, beatxInfo.bounds.height * s), style.Scale, PatchStyle.Strentch); + } + } + break; + case EventType.ShowRooms: + { + destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale, this.iconSize * 4 * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + if (evt.rooms && Array.isArray(evt.rooms)) { + for (let i = 0; i < 4; i++) { + const roomState = evt.rooms[i] ? "1" : "0"; + this.DrawSlice(canvas, `${key}_${roomState}`, new Point(dest.x, dest.y + i * this.iconSize * style.Scale), style.Scale / 2); + } + } + } + break; + default: + destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); + this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); + switch (evt.type) { + case EventType.CustomFlash: + { + this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.startColor ?? 0)); + this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.endColor ?? 0)); + } + break; + case EventType.FlipScreen: + { + let suffix = ""; + const flipX = evt.flipX ?? false; + const flipY = evt.flipY ?? false; + if (flipX && flipY) { + suffix = "_2"; + } else if (flipX && !flipY) { + suffix = "_1"; + } else if (!flipX && flipY) { + suffix = "_0"; + } + this.DrawSlice(canvas, key + suffix, dest, style.Scale); + } + break; + case EventType.FloatingText: + { + this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.color ?? 0)); + this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.outlineColor ?? 0)); + } + break; + case EventType.MoveRoom: + { + canvas.save(); + const degree = evt.angle ?? 0; + const scaleWidth = evt.scale?.width ?? 0; + const scaleHeight = evt.scale?.height ?? 0; + if (scaleWidth === 0 || scaleHeight === 0) { + canvas.restore(); + break; + } + const pleft = (evt.pivot?.x ?? 0) / 100; + const ptop = 1 - (evt.pivot?.y ?? 0) / 100; + const uniform = Math.sqrt(scaleWidth * scaleWidth + scaleHeight * scaleHeight); + const w = scaleWidth / uniform; + const h = scaleHeight / uniform; + canvas.translate(dest.x + destRect.width / 2, dest.y + destRect.height / 2); + canvas.rotate(-degree * Math.PI / 180); + canvas.scale(w, h); + this.DrawSlice(canvas, key, new Point(-destRect.width / 2, -destRect.height / 2), style.Scale); + if (!(pleft < 0 || pleft > 1 || ptop < 0 || ptop > 1)) { + canvas.fillStyle = "rgb(255, 0, 0)"; + canvas.fillRect((pleft - 0.5) * destRect.width - 1, (ptop - 0.5) * destRect.height - 1, 2, 2); + } + canvas.restore(); + } + break; + case EventType.PaintHands: + { + this.DrawSlice(canvas, key, dest, style.Scale, PatchStyle.Strentch, new Color(evt.tintColor ?? 0)); + const border = evt.border ?? "None"; + if (border === "Outline") { + this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); + } else if (border === "Glow") { + this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); + } + } + break; + case EventType.SetBackgroundColor: + { + this.DrawSlice(canvas, key, dest, style.Scale); + const bgType = evt.backgroundType ?? "Color"; + if (bgType === "Color") { + this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.color ?? 0)); + } else if (bgType === "Image") { + this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(4294967295)); + } + } + break; + case EventType.SetCrotchetsPerBar: + { + const cpb = evt.crotchetsPerBar ?? 4; + this.DrawSlice(canvas, key, dest, style.Scale); + this.DrawRDFontText(canvas, cpb > 9 ? "-" : cpb.toString(), new Point(dest.x + 2 * style.Scale, dest.y + 7 * style.Scale), new Color(4278190080), style.Scale); + this.DrawRDFontText(canvas, "4", new Point(dest.x + 8 * style.Scale, dest.y + 12 * style.Scale), new Color(4278190080), style.Scale); + } + break; + case EventType.SetForeground: + { + this.DrawSlice(canvas, key, dest, style.Scale); + } + break; + case EventType.Tint: + { + this.DrawSlice(canvas, key, dest, style.Scale, PatchStyle.Strentch, new Color(evt.tintColor ?? 0)); + const border = evt.border ?? "None"; + if (border === "Outline") { + this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); + } else if (border === "Glow") { + this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); + } + } + break; + case EventType.TintRows: + { + this.DrawSlice(canvas, key, dest, style.Scale, PatchStyle.Strentch, new Color(evt.tintColor ?? 0)); + const border = evt.border ?? "None"; + if (border === "Outline") { + this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); + } else if (border === "Glow") { + this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); + } + } + break; + default: + this.drawSliceNormal(canvas, info, destRect); + break; + } + break; + } + if (evtInfo.isDurationEvent) { + evt.duration = 2; + } + if (evt.duration && evt.duration > 0 && style.Active) { + const duration = evt[evtInfo.durationKey]; + const durWidth = style.Scale * this.iconSize * duration - destRect.width; + const c = this.ColorOf(evt.tab); + c.alpha = style.Active ? 192 : 91; + if (durWidth > 0) { + this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, durWidth, destRect.height), style.Scale, PatchStyle.Repeat, c); + } + } + return destRect; + } + static ColorOf(tab) { + switch (tab) { + case "sounds": + return new Color(4292355123); + case "rows": + return new Color(4281094105); + case "actions": + return new Color(4291118003); + case "decorations": + return new Color(4278240345); + case "rooms": + return new Color(4292392978); + case "windows": + return new Color(4283479511); + default: + return new Color(4286874756); + } + } + static DrawBack(canvas, destRect, color, style) { + const outline = "event_outline"; + const back = "event_back"; + this.DrawSlice(canvas, outline, destRect, style.Scale, PatchStyle.Strentch, new Color(style.Active ? 4294967295 : 4289243304)); + destRect.inflate(-style.Scale, -style.Scale); + this.DrawSlice(canvas, back, destRect, style.Scale, PatchStyle.Strentch, color); + } + static WithState(color, active, enabled) { + const c = enabled ? color.clone() : new Color(4286874756); + c.alpha = active ? 192 : 91; + return c; + } +}; +export { + AssetManager, + Color, + Extensions, + IconStyle, + Paint, + Point, + Rect, + SliceInfo +}; diff --git a/script/rdview2.js b/script/rdview2.js new file mode 100644 index 0000000..b8ac205 --- /dev/null +++ b/script/rdview2.js @@ -0,0 +1,84 @@ +import { Extensions, IconStyle } from "/script/Extensions.js"; +function rend() { + const codeBlocks = document.querySelectorAll("canvas.rdview2-canvas"); + codeBlocks.forEach((block) => { + const width = block.getAttribute("data-width") || 8; + const height = block.getAttribute("data-height") || 4; + const scale = block.getAttribute("data-scale") || 2; + const data = block.getAttribute("data"); + const ctx = block.getContext("2d"); + block.width = width * scale * 14; + block.height = height * scale * 14; + if (!data) { + return; + } + const jsonData = JSON.parse(`[${JSON.parse(data)}]`); + + let lastX = -1, lastY = -1, lastActive = false; + let frameId = null; + + const style = new IconStyle(); + + block.render = (x, y, active) => { + if (x === lastX && y === lastY && active === lastActive) { + return; + } + lastX = x; + lastY = y; + lastActive = active; + + ctx.clearRect(0, 0, block.width, block.height); + for (const evt of jsonData) { + style.Scale = scale; + style.Hover = evt.area?.contains({x, y}) ?? false; + style.Active = evt.area?.contains({x, y}) ? active : false; + evt.area = Extensions.DrawEventIcon(ctx, evt, { + x: ((evt.beat ?? 1) - 1) * scale * 14, + y: (evt.y ?? 0) * scale * 14, + }, style); + } + } + + const throttledRender = (x, y, active) => { + if (frameId !== null) { + cancelAnimationFrame(frameId); + } + frameId = requestAnimationFrame(() => { + block.render(x, y, active); + frameId = null; + }); + } + + block.addEventListener("mousemove", (e) => { + const rect = block.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + throttledRender(x, y, false); + }); + block.addEventListener("mousedown", (e) => { + const rect = block.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + block.render(x, y, true); + }); + block.addEventListener("mouseup", (e) => { + const rect = block.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + block.render(x, y, false); + }); + block.addEventListener("mouseleave", (e) => { + if (frameId !== null) { + cancelAnimationFrame(frameId); + } + block.render(0, 0, false); + }); + block.render(0, 0, false); + }); +} + +window.$docsify.plugins = [].concat(window.$docsify.plugins, function (hook) { + hook.doneEach(function () { + rend(); + }); +}); From c1b00aa34dac10f26d07b1070c3edf6fcd02100b Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Fri, 12 Dec 2025 15:24:52 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E3=80=90=E5=AE=9E=E9=AA=8C=E3=80=91rdvie?= =?UTF-8?q?w2=20=E6=A0=B7=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/classicbeat.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/classicbeat.md b/pages/classicbeat.md index 2ef988d..40abb2c 100644 --- a/pages/classicbeat.md +++ b/pages/classicbeat.md @@ -10,14 +10,14 @@ 第二个选项“**摇摆**”就是剧情模式里老奶奶那样的摇摆普通拍子,可以使用拖动条来调节,对照下方绿色竖线的移动可以很直观地看到摇摆效果。不过拖动滑条你只能得到一些倍数十分规整的摇摆拍子,例如摇摆值为0.25,0.5,0.75等,如果你的音乐里真的有些更为不同寻常的摇摆幅度,那就要直接在框里填写数字了。 -```rdview 8 9 -eb.AddClassicBeat 1 1[swing=0.25,tick=6]; -eb.AddClassicBeat 1 2[swing=0.5,tick=6]; -eb.AddClassicBeat 1 3[swing=0.75,tick=6]; -eb.AddClassicBeat 1 4[tick=6]; -eb.AddClassicBeat 1 5[swing=1.25,tick=6]; -eb.AddClassicBeat 1 6[swing=1.5,tick=6]; -eb.AddClassicBeat 1 7[swing=1.75,tick=6]; +```rdview2 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 }, +{"beat": 2, "y": 4, "type": "AddClassicBeat", "row": 0, "tick": 1, "swing": 1, "hold": 0 }, +{"beat": 2, "y": 5, "type": "AddClassicBeat", "row": 0, "tick": 1, "swing": 1.25, "hold": 0 }, +{"beat": 2, "y": 6, "type": "AddClassicBeat", "row": 0, "tick": 1, "swing": 1.5, "hold": 0 }, +{"beat": 2, "y": 7, "type": "AddClassicBeat", "row": 0, "tick": 1, "swing": 1.75, "hold": 0 } ``` > 不要把摇摆程度拖到滑条的最右端,这样会产生一个不带`X`记号但只有2,4,6,7拍的节奏,无法读谱。 From 0fecdf5b19a8e62c72f550e875f19db4ea5c9e06 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Wed, 31 Dec 2025 22:11:33 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=EF=BC=88=E8=99=BD=E7=84=B6=E8=BF=98=E6=98=AF?= =?UTF-8?q?=E5=BE=88=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/rdview2.js | 121 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 31 deletions(-) diff --git a/script/rdview2.js b/script/rdview2.js index b8ac205..a3f2c52 100644 --- a/script/rdview2.js +++ b/script/rdview2.js @@ -2,11 +2,16 @@ import { Extensions, IconStyle } from "/script/Extensions.js"; function rend() { const codeBlocks = document.querySelectorAll("canvas.rdview2-canvas"); codeBlocks.forEach((block) => { + // 清理旧的实例 + if (block.cleanup) { + block.cleanup(); + } + const width = block.getAttribute("data-width") || 8; const height = block.getAttribute("data-height") || 4; const scale = block.getAttribute("data-scale") || 2; const data = block.getAttribute("data"); - const ctx = block.getContext("2d"); + const ctx = block.getContext("2d", { alpha: false, desynchronized: true }); block.width = width * scale * 14; block.height = height * scale * 14; if (!data) { @@ -14,34 +19,68 @@ function rend() { } const jsonData = JSON.parse(`[${JSON.parse(data)}]`); - let lastX = -1, lastY = -1, lastActive = false; + let lastActive = false; + let evtId = 0; let frameId = null; + let cachedRect = null; + let mdown = false; + + const eventPositions = jsonData.map(evt => ({ + evt, + x: ((evt.beat ?? 1) - 1) * scale * 14, + y: (evt.y ?? 0) * scale * 14 + })); const style = new IconStyle(); + style.Scale = scale; + + const updateRect = () => { + cachedRect = block.getBoundingClientRect(); + }; + updateRect(); + + let rectTimeout; + const debouncedUpdateRect = () => { + clearTimeout(rectTimeout); + rectTimeout = setTimeout(updateRect, 100); + }; + + const observer = new ResizeObserver(debouncedUpdateRect); + observer.observe(block); + + window.addEventListener("resize", debouncedUpdateRect, { passive: true }); + window.addEventListener("scroll", debouncedUpdateRect, { passive: true }); block.render = (x, y, active) => { - if (x === lastX && y === lastY && active === lastActive) { + const point = { x, y }; + let currentEvtId = null; + for (let i = 0; i < eventPositions.length; i++) { + const { evt } = eventPositions[i]; + if (evt.area?.contains(point)) { + currentEvtId = i; + break; + } + } + + if (currentEvtId === evtId && active === lastActive) { return; } - lastX = x; - lastY = y; + evtId = currentEvtId; lastActive = active; ctx.clearRect(0, 0, block.width, block.height); - for (const evt of jsonData) { - style.Scale = scale; - style.Hover = evt.area?.contains({x, y}) ?? false; - style.Active = evt.area?.contains({x, y}) ? active : false; - evt.area = Extensions.DrawEventIcon(ctx, evt, { - x: ((evt.beat ?? 1) - 1) * scale * 14, - y: (evt.y ?? 0) * scale * 14, - }, style); + + for (const { evt, x: posX, y: posY } of eventPositions) { + const isHovered = evt.area?.contains(point) ?? false; + style.Hover = isHovered; + style.Active = isHovered ? active : false; + evt.area = Extensions.DrawEventIcon(ctx, evt, { x: posX, y: posY }, style); } } const throttledRender = (x, y, active) => { if (frameId !== null) { - cancelAnimationFrame(frameId); + return; } frameId = requestAnimationFrame(() => { block.render(x, y, active); @@ -49,31 +88,51 @@ function rend() { }); } + const getMousePos = (e) => ({ + x: e.clientX - cachedRect.left, + y: e.clientY - cachedRect.top + }); + block.addEventListener("mousemove", (e) => { - const rect = block.getBoundingClientRect(); - const x = e.clientX - rect.left; - const y = e.clientY - rect.top; - throttledRender(x, y, false); - }); + const { x, y } = getMousePos(e); + console.log(x, y); + throttledRender(x, y, mdown); + }, { passive: true }); + block.addEventListener("mousedown", (e) => { - const rect = block.getBoundingClientRect(); - const x = e.clientX - rect.left; - const y = e.clientY - rect.top; - block.render(x, y, true); + const { x, y } = getMousePos(e); + mdown = true; + block.render(x, y, mdown); }); + block.addEventListener("mouseup", (e) => { - const rect = block.getBoundingClientRect(); - const x = e.clientX - rect.left; - const y = e.clientY - rect.top; - block.render(x, y, false); + const { x, y } = getMousePos(e); + mdown = false; + block.render(x, y, mdown); }); - block.addEventListener("mouseleave", (e) => { + + block.addEventListener("mouseleave", () => { + if (frameId !== null) { + cancelAnimationFrame(frameId); + frameId = null; + } + mdown = false; + evtId = null; + lastActive = false; + block.render(-1, -1, mdown); + }, { passive: true }); + + block.cleanup = () => { + observer.disconnect(); + window.removeEventListener("resize", debouncedUpdateRect); + window.removeEventListener("scroll", debouncedUpdateRect); + clearTimeout(rectTimeout); if (frameId !== null) { cancelAnimationFrame(frameId); } - block.render(0, 0, false); - }); - block.render(0, 0, false); + }; + + block.render(-1, -1, mdown); }); } From 6f8e88b93dd3306b6dab6af97d19c4592775ad0d Mon Sep 17 00:00:00 2001 From: Xiaolvjun <270791752@qq.com> Date: Mon, 12 Jan 2026 18:32:36 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20pages/appendix=5Faud?= =?UTF-8?q?ios.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/appendix_audios.md | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/pages/appendix_audios.md b/pages/appendix_audios.md index e409040..f2f7e36 100644 --- a/pages/appendix_audios.md +++ b/pages/appendix_audios.md @@ -262,6 +262,24 @@ | sndTutorialDubstep | MD-1的教程音乐 | 114 | | sndTutorialDubstep_Bassless | MD-1的教程音乐,无贝斯 | 114 | | sndTutorialDubstep_Dotted | MD-1的教程音乐,有附点 | 114 | +| sndTutorialHouse_Base | 5-25-2N的教程音乐 | 120 | +| sndTutorialHouse_AmenFill | 5-25-2N的教程音乐开始练习前摇(镲声) | 120 | +| sndTutorialHouse_FreezeCPU | 5-2的教程音乐(伊恩演示) | 120 | +| sndTutorialHouse_Freeze1 | 5-2教程音乐的第一阶段 | 120 | +| sndTutorialHouse_Freeze2 | 5-2教程音乐的第二阶段 | 120 | +| sndTutorialHouse_BurnCPU | 5-2N的教程音乐(伊恩演示) | 120 | +| sndTutorialHouse_Burn1 | 5-2N教程音乐的第一阶段 | 120 | +| sndTutorialHouse_Burn2 | 5-2N教程音乐的第二阶段 | 120 | +| sndTutorialHouse_Rest | 5-25-2N的教程音乐(休息) | 120 | +| sndTutorialHouse_Riser | 5-25-2N的教程音乐开始练习前摇(鼓声) | 120 | +| sndTutorialSyncopation | 6-1的教程音乐开头 | 110 | +| sndTutorialSyncopation | 6-1的教程音乐开头,无开头空白 | 110 | +| sndTutorialSyncopation_Phase1 | 6-1教程音乐第一阶段 | 110 | +| sndTutorialSyncopation_Phase2 | 6-1教程音乐第二阶段 | 110 | +| sndTutorialHoldshot | 7-1的教程音乐 | 95 | +| sndTutorialHoldshot_Phase1 | 7-1的教程音乐第一阶段 | 95 | +| sndTutorialHoldshot_Phase2 | 7-1的教程音乐第二阶段 | 95 | +| sndTutorialHoldshot_Phase3 | 7-1的教程音乐第三阶段 | 95 | | sndOrientalTechno | 1-1东方电舞曲 | 100 | | sndOrientalTechnodown | 1-1N东方回响贝斯的开头部分 | | | sndOrientalDubstep | 1-1N东方回响贝斯 | 130 | @@ -271,14 +289,70 @@ | sndOrientalInsomniac2 | 1-X 东方不眠夜 第二部分 | | | sndOrientalInsomniac3 | 1-X 东方不眠夜 第三部分 | | | sndOrientalInsomniacHardRep | 1-XN超东方不眠夜 | 160~180 | +| sndGongXi | 1-CNY春节贺岁片 | 145 | +| sndHalloween | 1-BOO恐怖鸟主题 | 100 | +| sndLofi | 2-1Lo-fi Hip-Hop Beats To Treat Patients To | 75 | +| sndCareless | 2-1Nwish i could care less | 75~81 | +| sndCarelessCN | 2-1Nwish i could care less中文版 | 75~81 | | sndSupraventricular88 | 2-2室上性心动过速 | 88 | +| sndUnreachable | 2-2NUnreachable | 180 | +| sndPuffPiece | 2-3缭绕 | 127 | +| Pomeranian | 2-3N嗅炸弹的博美犬 | 127.2 | +| song_of_the_sea | 2-42-4N的背景音乐 | 60 | +| sndAllTheTimes | 2-XAll The Times 咖啡之歌 | 145 | +| sndAllTheTimesCN | 2-XAll The Times 咖啡之歌中文版 | 145 | +| sndBitterness | 2-XNBitter Times 爱情是苦和甜的交错前半段 | 112~195 | +| sndBitternessCutscene | 2-XNBitter Times 爱情是苦和甜的交错后半段 | 112->195->264->195 | | sndTutorialBeans | 2-B1武士豆子跳 | 110 | +| sndSleepyGarden | 3-1沉睡花园 | 158 | | sndLounge | 3-1N休息室 | 75 | | sndBarbra | 3-2典雅 | 115 | +| sndDistantDuet | 3-3分离二重唱 | 194 | +| sndDistantDuetNight | 3-3分离二重唱·夜 | 194 | +| sndDistantDuet | 3-3分离二重唱 | 194 | +| sndDistantDuetNight | 3-3分离二重唱·夜 | 194 | | sndLesMisBar1 | 3-X轮班之歌 | 100 | | sndLesMisBar39 | 3-X轮班之歌 从第39小节开始 | | +| sndMinersong | 4-1实习医生培训演练表现评估 | 128->225.9->140~110? | +| sndRollerdisco | 4-1N滑板迪斯科震颤 | 125.5 | +| sndInvisible | 4-24-2N | 190 | | sndSteinway | 4-3斯坦威 | 80 | +| sndKnowYou | 4-4懂你 | 157 | | sndMurmurs | 4-4N喃喃细语 | 65 | +| sndLuckyBreak | 5-1路吉摔了一跤 | 156 | +| sndOSTL | 5-2One Slip Too Late 创伤之歌 | 175~150 | +| sndOSTLCN | 5-2One Slip Too Late 创伤之歌中文版 | 175~150 | +| sndFreezeshot | 5-2Lo-fi Beats For Patients To Chill To | 140 | +| sndFreezeshotH | 5-2N无以为继的伤心欲绝 | 176->100->80 | +| sndTherapy1 | 5-3七局伸展操第一部分 | 128 | +| sndTherapy2 | 5-3七局伸展操第二部分 | 124 | +| sndTherapy3 | 5-3七局伸展操第三部分 | 136 | +| sndTherapyEnding | 5-3七局伸展操结尾 | 136 | +| sndCorazonesViejos | 5-3N偕老 | 249? | +| sndDDS | 5-X梦想永不歇 | 95->62.6->102.5 | +| sndDDSCN | 5-X梦想永不歇中文版 | 95->62.6->102.5 | +| sndHaileyDuet | 6-1想把心事和你说 | 94.5->190->220->181->206? | +| sndHaileyDuetCN | 6-1想把心事和你说中文版 | 94.5->190->220->181->206? | +| sndEdegaRave | 6-2欢迎回来 | 200->85->200 | +| sndBossStage_Main | 6-XBoss战(包括埃德加批评佩奇的一段) | 150~255 | +| sndBossStage_NoCutscene | 6-XBoss战(不包括埃德加批评佩奇的一段) | 150~255 | +| sndBossStage_EndingShort | 6-XBoss战结尾(包括埃德加批评佩奇的一段) | 165 | +| sndBossStage_EndingLong | 6-XBoss战结尾(不包括埃德加批评佩奇的一段) | 165 | +| sndBlurred | 7-1模糊 | 70 | +| sndMontage | 7-X奇迹除颤器 | 160 | +| sndMontageIntro | 7-X奇迹除颤器前奏 | | +| sndColeSongLeaves | 7-X2奇迹除颤器安可版(佩奇离职分支) | 91->121.2->182-->156->240?->228?-->360 | +| sndColeSongStays | 7-X2奇迹除颤器安可版(佩奇在职分支) | 91->121.2->182-->156->240?->228?-->360 | +| sndArtExercise | X-1美术练习 | 140 | +| sndHelpingHands | X-0伸出援手 | 178 | +| sndHelpingHandsCN | X-0伸出援手中文版 | 178 | +| sndBlackestLuxuryCar | MD-1BlackestLuxuryCar | 178 | +| sndTapeStopNight | MD-2Tape/Stop/Night | 115 | +| sndThe90sDecision | MD-3The90sDecision | 128 | +| sndMeetAndTweet | X-MATMeet And Tweet | 110 | +| sndWornOutTapes | X-WOTWorn Out Tapes | 149 | +| sndSparkLine | X-KOB气球王国 | 124 | +| sndVividStasis | X-FTS恋恋群星 | 150 | | sndOsmBluesRadio | 夜间的病房内过剧情 | 98? | | SoftPianoIntimate | 第一章末尾的过剧情 | 88 | From 50bef7ba6d30de6e9fcfe8c13d713476f2e8bca2 Mon Sep 17 00:00:00 2001 From: Xiaolvjun <270791752@qq.com> Date: Mon, 12 Jan 2026 19:51:00 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20pages/credits.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/credits.md | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/credits.md b/pages/credits.md index 55b1b96..f654e9c 100644 --- a/pages/credits.md +++ b/pages/credits.md @@ -12,6 +12,7 @@ - [RaYmondCheung](https://space.bilibili.com/1579208) - [NoMathExpectation](https://space.bilibili.com/184862524) - [0x4D2](https://space.bilibili.com/478595264) + - [正宗的小绿君](https://space.bilibili.com/1782518253) - 视频制作: - [吾夜犹明](https://space.bilibili.com/29219948) - [山不转水到渠成](https://space.bilibili.com/4870582) From 9a060eb6ffb1350089eace6ad25fe1ad9b31b7a1 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Mon, 12 Jan 2026 20:58:25 +0800 Subject: [PATCH 07/16] =?UTF-8?q?[RDView]=20=E6=9B=B4=E6=96=B0=E7=BB=86?= =?UTF-8?q?=E5=88=86=E6=8B=8D=E7=9A=84=E5=9B=BE=E5=83=8F=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=95=BF=E6=8C=89=E4=BA=8C=E6=8B=8D=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/rdview.js | 5 +++- script/rdview.ts | 5 +++- style/assets/beats/subdivision-area.png | Bin 130 -> 129 bytes style/rdview.css | 30 ++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/script/rdview.js b/script/rdview.js index 90f77ca..fda7705 100644 --- a/script/rdview.js +++ b/script/rdview.js @@ -849,6 +849,9 @@ function ReadProperties(reader, event, pairs) { if (value = FindValue(pairs, "loop")) { event.BeatStyle.Loop = parseInt(value.Value); } + if (value = FindValue(pairs, "hold")) { + event.BeatStyle.Hold = parseFloat(value.Value); + } break; default: break; @@ -938,7 +941,7 @@ function ConstructDivObject(obj) { result += (((_a = obj.BeatStyle) === null || _a === void 0 ? void 0 : _a.RowXs[i]) === 'x') ? `
` : `
`; } return result; - }], [(obj.BeatType === BeatsSpecial.AddClassicBeat || obj.BeatType === BeatsSpecial.AddFreeTimeBeat || obj.BeatType === BeatsSpecial.PulseFreeTimeBeat) && ((_s = (_r = obj.BeatStyle) === null || _r === void 0 ? void 0 : _r.Hold) !== null && _s !== void 0 ? _s : 0) > 0, `holdbeat`, () => ''], [obj.BeatType === BeatsSpecial.AddOneshotBeat && obj.BeatStyle !== undefined && obj.BeatStyle.OneshotBeatSubType.includes(RDOneshotBeatSubType.Skipshot), `skipshot`, () => ''])}`; + }], [(obj.BeatType === BeatsSpecial.AddClassicBeat || obj.BeatType === BeatsSpecial.AddFreeTimeBeat || obj.BeatType === BeatsSpecial.PulseFreeTimeBeat || obj.BeatType === BeatsSpecial.AddOneshotBeat) && ((_s = (_r = obj.BeatStyle) === null || _r === void 0 ? void 0 : _r.Hold) !== null && _s !== void 0 ? _s : 0) > 0, `holdbeat`, () => ''], [obj.BeatType === BeatsSpecial.AddOneshotBeat && obj.BeatStyle !== undefined && obj.BeatStyle.OneshotBeatSubType.includes(RDOneshotBeatSubType.Skipshot), `skipshot`, () => ''])}`; } else if (obj instanceof RDGroup) { return `
0, `holdbeat`, () => ''], + [(obj.BeatType === BeatsSpecial.AddClassicBeat || obj.BeatType === BeatsSpecial.AddFreeTimeBeat || obj.BeatType === BeatsSpecial.PulseFreeTimeBeat || obj.BeatType === BeatsSpecial.AddOneshotBeat) && (obj.BeatStyle?.Hold ?? 0) > 0, `holdbeat`, () => ''], [obj.BeatType === BeatsSpecial.AddOneshotBeat && obj.BeatStyle !== undefined && obj.BeatStyle.OneshotBeatSubType.includes(RDOneshotBeatSubType.Skipshot), `skipshot`, () => ''], )}
`; } diff --git a/style/assets/beats/subdivision-area.png b/style/assets/beats/subdivision-area.png index 9915732d12a185d4444df4b13ad90c4eff048da7..1bd906b94b324322375cebbfb5d50fe0daa0ba1e 100644 GIT binary patch delta 87 zcmZo-Y-F5Z7+~$`;us<^HCg1|f*.beat:not(:has(.classicbeat)) { + &>div.holdbeat { + position: absolute; + width: calc((var(--hold) * 28 - 2) * 1px); + height: inherit; + background-size: auto 100%; + background-image: url(./assets/beats/hold-area.png); + transform: translate(calc(((var(--tick) + var(--delay)) * 28 - 4) * 1px), 0); + z-index: -2; + + &::after { + content: ''; + position: absolute; + width: 2px; + height: 28px; + background-size: auto 100%; + transform: translate(calc((var(--hold) * 28 - 2) * 1px), 0); + background-image: url(./assets/beats/hold-right.png); + } + } + + &:active>div.holdbeat { + background-image: url(./assets/beats/hold-hover-area.png); + + &::after { + background-image: url(./assets/beats/hold-hover-right.png); + } + } + } + &>.beat:has(.row-xs) { width: 56px; height: 28px; From 55c53278ea62cb5ae7c51bff69d82f7550a89608 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Mon, 12 Jan 2026 21:10:13 +0800 Subject: [PATCH 08/16] =?UTF-8?q?[RDView]=E4=BF=AE=E5=A4=8D=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E7=BB=84=E5=86=85=E7=9A=84=E5=8D=95=E5=8F=91=E6=8B=8D?= =?UTF-8?q?=E9=95=BF=E6=8C=89=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=9A=84=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- style/rdview.css | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/style/rdview.css b/style/rdview.css index 9ed2093..e8bd658 100644 --- a/style/rdview.css +++ b/style/rdview.css @@ -1153,7 +1153,7 @@ height: inherit; background-size: auto 100%; background-image: url(./assets/beats/hold-area.png); - transform: translate(calc(((var(--tick) + var(--delay)) * 28 - 4) * 1px), 0); + transform: translate(calc(((var(--tick) + var(--delay) + var(--loop) * var(--interval)) * 28 - 4) * 1px), 0); z-index: -2; &::after { @@ -2210,6 +2210,36 @@ } } + &>.beat:not(:has(.classicbeat)) { + &>div.holdbeat { + position: absolute; + width: calc((var(--hold) * 28 - 2) * 1px); + height: inherit; + background-size: auto 100%; + background-image: url(./assets/beats/hold-area.png); + transform: translate(calc(((var(--tick) + var(--delay) + var(--loop) * var(--interval)) * 28 - 4) * 1px), 0); + z-index: -2; + + &::after { + content: ''; + position: absolute; + width: 2px; + height: 28px; + background-size: auto 100%; + transform: translate(calc((var(--hold) * 28 - 2) * 1px), 0); + background-image: url(./assets/beats/hold-right.png); + } + } + + &:active>div.holdbeat { + background-image: url(./assets/beats/hold-hover-area.png); + + &::after { + background-image: url(./assets/beats/hold-hover-right.png); + } + } + } + &>.beat:has(.row-xs) { width: 56px; height: 28px; From 1e4e94cce755494b57648b56beb41062fd9c5a66 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Wed, 14 Jan 2026 00:43:51 +0800 Subject: [PATCH 09/16] =?UTF-8?q?[rdview2]=20=E6=80=A7=E8=83=BD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 10 +- pages/appendix_tools.md | 21 + script/View.js | 1027 +++++++++++++++++++++++++++++++++++++++ script/assets.bin | Bin 0 -> 4299 bytes script/assets.png | Bin 0 -> 6653 bytes script/special.js | 125 +++++ style/special.css | 2 +- 7 files changed, 1179 insertions(+), 6 deletions(-) create mode 100644 script/View.js create mode 100644 script/assets.bin create mode 100644 script/assets.png diff --git a/index.html b/index.html index dfbf132..95d0522 100644 --- a/index.html +++ b/index.html @@ -19,8 +19,8 @@ - -
加载中...
+ +
加载中...
- + + + @@ -137,7 +139,5 @@ - - diff --git a/pages/appendix_tools.md b/pages/appendix_tools.md index 70e9acb..3d1ea8b 100644 --- a/pages/appendix_tools.md +++ b/pages/appendix_tools.md @@ -20,4 +20,25 @@ g 1 1 5 4 #0ff{ }; +--- + +
+ --- \ No newline at end of file diff --git a/script/View.js b/script/View.js new file mode 100644 index 0000000..ebf2918 --- /dev/null +++ b/script/View.js @@ -0,0 +1,1027 @@ +// AssetManager.ts +var Point = class _Point { + x = 0; + y = 0; + constructor(x, y) { + if (x !== void 0 && y !== void 0) { + this.x = x; + this.y = y; + return; + } + } + clone() { + return new _Point(this.x, this.y); + } +}; +var Size = class { + width = 0; + height = 0; + constructor(width, height) { + if (width !== void 0 && height !== void 0) { + this.width = width; + this.height = height; + return; + } + } + clone() { + return new Point(this.width, this.height); + } +}; +var Rect = class _Rect { + left = 0; + top = 0; + right = 0; + bottom = 0; + get x() { + return this.left; + } + set x(value) { + const diff = value - this.left; + this.left += diff; + this.right += diff; + } + get y() { + return this.top; + } + set y(value) { + const diff = value - this.top; + this.top += diff; + this.bottom += diff; + } + get width() { + return this.right - this.left; + } + set width(value) { + this.right = this.left + value; + } + get height() { + return this.bottom - this.top; + } + set height(value) { + this.bottom = this.top + value; + } + get centerX() { + return (this.left + this.right) / 2; + } + get centerY() { + return (this.top + this.bottom) / 2; + } + get location() { + let point = new Point(); + point.x = this.centerX; + point.y = this.centerY; + return point; + } + set location(point) { + let w = this.width; + let h = this.height; + this.left = point.x; + this.right = this.left + w; + this.top = point.y; + this.bottom = this.top + h; + } + get size() { + let size = new Size(); + size.width = this.width; + size.height = this.height; + return size; + } + set size(size) { + this.width = size.width; + this.height = size.height; + } + get isEmpty() { + return this.width <= 0 || this.height <= 0; + } + constructor(arg0, arg1, arg2, arg3) { + if (typeof arg0 === "number" && typeof arg1 === "number") { + if (typeof arg2 === "number" && typeof arg3 === "number") { + this.left = arg0; + this.top = arg1; + this.right = arg0 + arg2; + this.bottom = arg1 + arg3; + return; + } + this.right = arg0; + this.bottom = arg1; + return; + } else if (arg0 instanceof Point && arg1 instanceof Size) { + this.left = arg0.x; + this.top = arg0.y; + this.right = arg0.x + arg1.width; + this.bottom = arg0.y + arg1.height; + return; + } else if (arg0 instanceof Size) { + this.right = arg0.width; + this.bottom = arg0.height; + return; + } + } + inflate(dx, dy) { + this.left -= dx; + this.right += dx; + this.top -= dy; + this.bottom += dy; + } + clone() { + return new _Rect(this.left, this.top, this.width, this.height); + } + union(rect) { + const left = Math.min(this.left, rect.left); + const top = Math.min(this.top, rect.top); + const right = Math.max(this.right, rect.right); + const bottom = Math.max(this.bottom, rect.bottom); + return new _Rect(left, top, right - left, bottom - top); + } +}; +var Color = class _Color { + argb = 0; + constructor(a, r, g, b) { + if (typeof a === "string") { + let s = a; + if (s.startsWith("#")) { + s = s.substring(1); + } + s = s.trim(); + switch (s.length) { + case 3: + s = "ff" + s.split("").map((c) => c + c).join(""); + break; + case 4: + s = s.split("").map((c) => c + c).join(""); + break; + case 6: + s = "ff" + s; + break; + case 8: + break; + default: + s = "ffffffff"; + } + const u = parseInt(s, 16); + this.argb = u; + return; + } + if (a !== void 0 && r === void 0 && g === void 0 && b === void 0) { + this.argb = a; + return; + } + if (a === void 0 && r !== void 0 && g !== void 0 && b !== void 0) { + const u = 255 << 24 | (r & 255) << 16 | (g & 255) << 8 | b & 255; + this.argb = u; + return; + } + if (a !== void 0 && r !== void 0 && g !== void 0 && b !== void 0) { + const u = a << 24 | (r & 255) << 16 | (g & 255) << 8 | b & 255; + this.argb = u; + return; + } + this.argb = 0; + } + get a() { + return this.argb >>> 24 & 255; + } + set a(value) { + const v = value & 255; + this.argb = v << 24 | this.argb & 16777215; + } + get r() { + return this.argb >>> 16 & 255; + } + set r(value) { + const v = value & 255; + this.argb = this.argb & 4278255615 | v << 16; + } + get g() { + return this.argb >>> 8 & 255; + } + set g(value) { + const v = value & 255; + this.argb = this.argb & 4294902015 | v << 8; + } + get b() { + return this.argb & 255; + } + set b(value) { + const v = value & 255; + this.argb = this.argb & 4294967040 | v; + } + toUint32() { + return this.argb; + } + clone() { + return new _Color(this.argb); + } + static FromRgba(r, g, b, a) { + return new _Color(a, r, g, b); + } + toRgbaString() { + return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a / 255})`; + } + toHexString(includeAlpha = true) { + if (includeAlpha) { + return `#${this.argb.toString(16).padStart(8, "0")}`; + } else { + const rgb = this.argb & 16777215; + return `#${rgb.toString(16).padStart(6, "0")}`; + } + } + equals(other) { + return this.argb === other.argb; + } + static get Transparent() { + return new _Color(0, 0, 0, 0); + } + static get Black() { + return new _Color(255, 0, 0, 0); + } + static get White() { + return new _Color(255, 255, 255, 255); + } + withAlpha(alpha) { + return new _Color(alpha, this.r, this.g, this.b); + } + withRed(red) { + return new _Color(this.a, red, this.g, this.b); + } + withGreen(green) { + return new _Color(this.a, this.r, green, this.b); + } + withBlue(blue) { + return new _Color(this.a, this.r, this.g, blue); + } +}; +var SliceInfo = class { + bounds = new Rect(); + center = new Rect(); + pivot = new Point(); + scale = 1; + blobUrl = ""; + get isNinePatch() { + return !this.center.isEmpty; + } +}; +var assetFilePath = "assets.png"; +var slicesFilePath = "assets.bin"; +var directoryPath = "./script"; +async function loadAssetFile() { + const pngPath = directoryPath + "/" + assetFilePath; + return await new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = (e) => reject(new Error(`Failed to load asset file: ${pngPath}`)); + img.src = pngPath; + }); +} +async function readFromStream(stream) { + const canvas = new OffscreenCanvas(1, 1); + let offset = 0; + const count = stream.getUint8(0); + offset += 1; + const sliceInfos = /* @__PURE__ */ new Map(); + for (let i = 0; i < count; i++) { + const sliceInfo = new SliceInfo(); + const keyLength = stream.getUint8(offset); + offset += 1; + const key = new TextDecoder().decode(new Uint8Array(stream.buffer, offset, keyLength)); + offset += keyLength; + const left = stream.getUint8(offset); + offset += 1; + const top = stream.getUint8(offset); + offset += 1; + const wh = stream.getUint16(offset, true); + offset += 2; + const width = wh & 31; + const height = wh >> 5 & 63; + sliceInfo.bounds = new Rect(left, top, width, height); + const hasCenter = (wh & 32768) !== 0; + const hasPivot = (wh & 16384) !== 0; + if (hasCenter) { + const centerByte = stream.getUint8(offset); + offset += 1; + const centerLeft = centerByte & 3; + const centerTop = centerByte >> 2 & 3; + const centerWidth = centerByte >> 4 & 3; + const centerHeight = centerByte >> 6 & 3; + sliceInfo.center = new Rect(centerLeft, centerTop, centerWidth, centerHeight); + } + if (hasPivot) { + const pivotByte = stream.getUint8(offset); + offset += 1; + let pivotLeft = pivotByte & 7; + let pivotTop = pivotByte >> 3 & 7; + if ((pivotByte & 128) !== 0) { + pivotLeft *= -1; + } + if ((pivotByte & 64) !== 0) { + pivotTop *= -1; + } + sliceInfo.pivot = new Point(pivotLeft, pivotTop); + } + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext("2d"); + if (ctx === null) { + throw new Error("Failed to get 2D context"); + } + ctx.clearRect(0, 0, width, height); + ctx.drawImage(assetFile, sliceInfo.bounds.left, sliceInfo.bounds.top, width, height, 0, 0, width, height); + const blob = await canvas.convertToBlob({ + type: "image/png" + }); + sliceInfo.blobUrl = URL.createObjectURL(blob); + sliceInfos.set(key, sliceInfo); + } + return sliceInfos; +} +var assetLoaded = false; +var assetFile = await loadAssetFile(); +var slices = await readFromStream(new DataView(await (await fetch(directoryPath + "/" + slicesFilePath)).arrayBuffer())).finally(() => { + assetLoaded = true; +}); + +// Consts.ts +var Tab = /* @__PURE__ */ function(Tab2) { + Tab2["Sounds"] = "sounds"; + Tab2["Rows"] = "rows"; + Tab2["Actions"] = "actions"; + Tab2["Decorations"] = "decorations"; + Tab2["Rooms"] = "rooms"; + Tab2["Windows"] = "windows"; + Tab2["Unknown"] = "unknown"; + return Tab2; +}({}); +var EventType = /* @__PURE__ */ function(EventType2) { + EventType2["AddClassicBeat"] = "AddClassicBeat"; + EventType2["AddFreeTimeBeat"] = "AddFreeTimeBeat"; + EventType2["AddOneshotBeat"] = "AddOneshotBeat"; + EventType2["AdvanceText"] = "AdvanceText"; + EventType2["BassDrop"] = "BassDrop"; + EventType2["Blend"] = "Blend"; + EventType2["CallCustomMethod"] = "CallCustomMethod"; + EventType2["ChangeCharacter"] = "ChangeCharacter"; + EventType2["ChangePlayersRows"] = "ChangePlayersRows"; + EventType2["Comment"] = "Comment"; + EventType2["CustomFlash"] = "CustomFlash"; + EventType2["DesktopColor"] = "DesktopColor"; + EventType2["FadeRoom"] = "FadeRoom"; + EventType2["FinishLevel"] = "FinishLevel"; + EventType2["Flash"] = "Flash"; + EventType2["FlipScreen"] = "FlipScreen"; + EventType2["FloatingText"] = "FloatingText"; + EventType2["ForwardDecorationEvent"] = "ForwardDecorationEvent"; + EventType2["ForwardEvent"] = "ForwardEvent"; + EventType2["ForwardRowEvent"] = "ForwardRowEvent"; + EventType2["HideRow"] = "HideRow"; + EventType2["HideWindow"] = "HideWindow"; + EventType2["InvertColors"] = "InvertColors"; + EventType2["MacroEvent"] = "MacroEvent"; + EventType2["MaskRoom"] = "MaskRoom"; + EventType2["Move"] = "Move"; + EventType2["MoveCamera"] = "MoveCamera"; + EventType2["MoveRoom"] = "MoveRoom"; + EventType2["MoveRow"] = "MoveRow"; + EventType2["NarrateRowInfo"] = "NarrateRowInfo"; + EventType2["NewWindowDance"] = "NewWindowDance"; + EventType2["PaintHands"] = "PaintHands"; + EventType2["PlayAnimation"] = "PlayAnimation"; + EventType2["PlayExpression"] = "PlayExpression"; + EventType2["PlaySong"] = "PlaySong"; + EventType2["PlaySound"] = "PlaySound"; + EventType2["PulseCamera"] = "PulseCamera"; + EventType2["PulseFreeTimeBeat"] = "PulseFreeTimeBeat"; + EventType2["ReadNarration"] = "ReadNarration"; + EventType2["RenameWindow"] = "RenameWindow"; + EventType2["ReorderRooms"] = "ReorderRooms"; + EventType2["ReorderRow"] = "ReorderRow"; + EventType2["ReorderSprite"] = "ReorderSprite"; + EventType2["ReorderWindows"] = "ReorderWindows"; + EventType2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; + EventType2["SetBackgroundColor"] = "SetBackgroundColor"; + EventType2["SetBeatSound"] = "SetBeatSound"; + EventType2["SetBeatsPerMinute"] = "SetBeatsPerMinute"; + EventType2["SetClapSounds"] = "SetClapSounds"; + EventType2["SetCountingSound"] = "SetCountingSound"; + EventType2["SetCrotchetsPerBar"] = "SetCrotchetsPerBar"; + EventType2["SetForeground"] = "SetForeground"; + EventType2["SetGameSound"] = "SetGameSound"; + EventType2["SetHandOwner"] = "SetHandOwner"; + EventType2["SetHeartExplodeInterval"] = "SetHeartExplodeInterval"; + EventType2["SetHeartExplodeVolume"] = "SetHeartExplodeVolume"; + EventType2["SetMainWindow"] = "SetMainWindow"; + EventType2["SetOneshotWave"] = "SetOneshotWave"; + EventType2["SetPlayStyle"] = "SetPlayStyle"; + EventType2["SetRoomContentMode"] = "SetRoomContentMode"; + EventType2["SetRoomPerspective"] = "SetRoomPerspective"; + EventType2["SetRowXs"] = "SetRowXs"; + EventType2["SetSpeed"] = "SetSpeed"; + EventType2["SetTheme"] = "SetTheme"; + EventType2["SetVFXPreset"] = "SetVFXPreset"; + EventType2["SetVisible"] = "SetVisible"; + EventType2["SetWindowContent"] = "SetWindowContent"; + EventType2["ShakeScreen"] = "ShakeScreen"; + EventType2["ShakeScreenCustom"] = "ShakeScreenCustom"; + EventType2["ShowDialogue"] = "ShowDialogue"; + EventType2["ShowHands"] = "ShowHands"; + EventType2["ShowRooms"] = "ShowRooms"; + EventType2["ShowStatusSign"] = "ShowStatusSign"; + EventType2["ShowSubdivisionsRows"] = "ShowSubdivisionsRows"; + EventType2["SpinningRows"] = "SpinningRows"; + EventType2["Stutter"] = "Stutter"; + EventType2["TagAction"] = "TagAction"; + EventType2["TextExplosion"] = "TextExplosion"; + EventType2["Tile"] = "Tile"; + EventType2["Tint"] = "Tint"; + EventType2["TintRows"] = "TintRows"; + EventType2["WindowResize"] = "WindowResize"; + return EventType2; +}({}); +var EventAttriblte = /* @__PURE__ */ function(EventAttriblte2) { + EventAttriblte2[EventAttriblte2["None"] = 0] = "None"; + EventAttriblte2[EventAttriblte2["DurationEvent"] = 1] = "DurationEvent"; + EventAttriblte2[EventAttriblte2["RoomEvent"] = 2] = "RoomEvent"; + return EventAttriblte2; +}({}); +var EventInfo = class { + defaultTab; + durationKey = "duration"; + attr; + get isDurationEvent() { + return (this.attr & EventAttriblte.DurationEvent) !== 0; + } + get isRoomEvent() { + return (this.attr & EventAttriblte.RoomEvent) !== 0; + } + constructor(tab, enumAttriblte, durationKey) { + this.defaultTab = tab; + this.attr = enumAttriblte ?? EventAttriblte.None; + if (durationKey !== void 0) { + this.durationKey = durationKey; + } + } +}; +var WordInfo = class { + phrase; + length; + constructor(phrase, length) { + this.phrase = phrase; + this.length = length; + } +}; +var WordInfos = { + SayReaDyGetSetGoNew: new WordInfo("Rea, Dy, Get, Set, Go!", 4), + SayReaDyGetSetOne: new WordInfo("Rea, Dy, Get, Set, One!", 4), + SayGetSetGo: new WordInfo("Get, Set, Go!", 2), + SayGetSetOne: new WordInfo("Get, Set, One!", 2), + JustSayRea: new WordInfo("Rea", 0), + JustSayDy: new WordInfo("Dy", 0), + JustSayGet: new WordInfo("Get", 0), + JustSaySet: new WordInfo("Set", 0), + JustSayAnd: new WordInfo("And", 0), + JustSayGo: new WordInfo("Go!", 0), + JustSayStop: new WordInfo("Stop", 0), + JustSayAndStop: new WordInfo("And Stop!", 0), + SaySwitch: new WordInfo("Switch", 0), + SayWatch: new WordInfo("Watch", 0), + SayListen: new WordInfo("Listen", 0), + Count1: new WordInfo("1", 0), + Count2: new WordInfo("2", 0), + Count3: new WordInfo("3", 0), + Count4: new WordInfo("4", 0), + Count5: new WordInfo("5", 0), + Count6: new WordInfo("6", 0), + Count7: new WordInfo("7", 0), + Count8: new WordInfo("8", 0), + Count9: new WordInfo("9", 0), + Count10: new WordInfo("10", 0), + SayReadyGetSetGo: new WordInfo("Ready, Get, Set, Go!", 4), + JustSayReady: new WordInfo("Ready", 0) +}; +var EventInfos = { + AddClassicBeat: new EventInfo(Tab.Rows), + AddFreeTimeBeat: new EventInfo(Tab.Rows), + AddOneshotBeat: new EventInfo(Tab.Rows), + AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + BassDrop: new EventInfo(Tab.Actions), + Blend: new EventInfo(Tab.Decorations), + CallCustomMethod: new EventInfo(Tab.Actions), + ChangeCharacter: new EventInfo(Tab.Actions), + ChangePlayersRows: new EventInfo(Tab.Actions), + Comment: new EventInfo(Tab.Unknown), + CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), + FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + FinishLevel: new EventInfo(Tab.Actions), + Flash: new EventInfo(Tab.Actions), + FlipScreen: new EventInfo(Tab.Actions), + FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ForwardDecorationEvent: new EventInfo(Tab.Decorations), + ForwardEvent: new EventInfo(Tab.Unknown), + ForwardRowEvent: new EventInfo(Tab.Rows), + HideRow: new EventInfo(Tab.Actions), + HideWindow: new EventInfo(Tab.Windows), + InvertColors: new EventInfo(Tab.Actions), + MacroEvent: new EventInfo(Tab.Unknown), + MaskRoom: new EventInfo(Tab.Rooms), + Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), + MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + NarrateRowInfo: new EventInfo(Tab.Sounds), + NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + PlayAnimation: new EventInfo(Tab.Decorations), + PlayExpression: new EventInfo(Tab.Actions), + PlaySong: new EventInfo(Tab.Sounds), + PlaySound: new EventInfo(Tab.Sounds), + PulseCamera: new EventInfo(Tab.Actions), + PulseFreeTimeBeat: new EventInfo(Tab.Rows), + ReadNarration: new EventInfo(Tab.Sounds), + RenameWindow: new EventInfo(Tab.Windows), + ReorderRooms: new EventInfo(Tab.Rooms), + ReorderRow: new EventInfo(Tab.Rows), + ReorderSprite: new EventInfo(Tab.Decorations), + ReorderWindows: new EventInfo(Tab.Windows), + SayReadyGetSetGo: new EventInfo(Tab.Sounds), + SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetBeatSound: new EventInfo(Tab.Sounds), + SetBeatsPerMinute: new EventInfo(Tab.Sounds), + SetClapSounds: new EventInfo(Tab.Sounds), + SetCountingSound: new EventInfo(Tab.Sounds), + SetCrotchetsPerBar: new EventInfo(Tab.Sounds), + SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetGameSound: new EventInfo(Tab.Sounds), + SetHandOwner: new EventInfo(Tab.Actions), + SetHeartExplodeInterval: new EventInfo(Tab.Sounds), + SetHeartExplodeVolume: new EventInfo(Tab.Sounds), + SetMainWindow: new EventInfo(Tab.Windows), + SetOneshotWave: new EventInfo(Tab.Rows), + SetPlayStyle: new EventInfo(Tab.Actions), + SetRoomContentMode: new EventInfo(Tab.Rooms), + SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + SetRowXs: new EventInfo(Tab.Rows), + SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetVisible: new EventInfo(Tab.Decorations), + SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), + ShakeScreen: new EventInfo(Tab.Actions), + ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ShowDialogue: new EventInfo(Tab.Actions), + ShowHands: new EventInfo(Tab.Actions), + ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ShowSubdivisionsRows: new EventInfo(Tab.Actions), + SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + Stutter: new EventInfo(Tab.Actions), + TagAction: new EventInfo(Tab.Actions), + TextExplosion: new EventInfo(Tab.Actions), + Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), + Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), + TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent) +}; + +// View.ts +var lineHeight = 6; +var charHeight = 8; +var iconSize = 14; +var IconStyle = class { + enabled = true; + active = false; + hover = false; + scale = 1; + showDuration = false; +}; +function withState(color, active, enabled) { + return (enabled ? color : new Color(4286874756)).withAlpha(active ? 192 : 91); +} +function createLayer(key, bound, color, style) { + const layer = document.createElement("div"); + const info = slices.get(key); + layer.style.position = "absolute"; + layer.style.boxSizing = "content-box"; + if (info.isNinePatch) { + const center = info.center; + const width = bound?.width ?? info.bounds.width; + const height = bound?.height ?? info.bounds.height; + layer.style.left = `${(bound?.left ?? bound?.x ?? 0) * style.scale}px`; + layer.style.top = `${(bound?.top ?? bound?.y ?? 0) * style.scale}px`; + layer.style.borderStyle = "solid"; + layer.style.borderWidth = `${center.top * style.scale}px ${(info.bounds.width - center.right) * style.scale}px ${(info.bounds.height - center.bottom) * style.scale}px ${center.left * style.scale}px`; + layer.style.borderImageSource = `url(${info.blobUrl})`; + layer.style.borderImageSlice = `${center.top} ${info.bounds.width - center.right} ${info.bounds.height - center.bottom} ${center.left} fill`; + layer.style.borderImageWidth = `1`; + layer.style.borderImageOutset = `0`; + layer.style.borderImageRepeat = `repeat`; + layer.style.width = `${(width - center.left - (info.bounds.width - center.right)) * style.scale}px`; + layer.style.height = `${(height - center.top - (info.bounds.height - center.bottom)) * style.scale}px`; + } else { + layer.style.left = `${((bound?.left ?? bound?.x ?? 0) - info.pivot.x) * style.scale}px`; + layer.style.top = `${((bound?.top ?? bound?.y ?? 0) - info.pivot.y) * style.scale}px`; + layer.style.width = `${(bound?.width ?? info.bounds.width) * style.scale}px`; + layer.style.height = `${(bound?.height ?? info.bounds.height) * style.scale}px`; + layer.style.backgroundImage = `url(${info.blobUrl})`; + layer.style.backgroundSize = `${bound?.width ?? info.bounds.width * style.scale}px ${bound?.height ?? info.bounds.height * style.scale}px`; + } + if (color && Color.White.equals(color) === false) { + const filterId = getColorMatrixId(color); + layer.style.filter = `url(#${filterId})`; + layer.onColorChange = (color2) => { + if (!color2) { + return; + } + const newFilterId = getColorMatrixId(color2); + layer.style.filter = `url(#${newFilterId})`; + }; + } else { + } + return layer; +} +var colorMatrixIds = /* @__PURE__ */ new Map(); +var colorMatrixCache = document.createElement("div"); +document.body.appendChild(colorMatrixCache); +function getColorMatrixId(rgba) { + if (colorMatrixIds.has(rgba.toUint32())) { + return colorMatrixIds.get(rgba.toUint32()); + } + const feColorMatrix = document.createElementNS("http://www.w3.org/2000/svg", "feColorMatrix"); + feColorMatrix.setAttribute("type", "matrix"); + const r = rgba.r / 255; + const g = rgba.g / 255; + const b = rgba.b / 255; + const a = rgba.a / 255; + feColorMatrix.setAttribute("values", `${r} 0 0 0 0 0 ${g} 0 0 0 0 0 ${b} 0 0 0 0 0 ${a} 0`); + const filter = document.createElementNS("http://www.w3.org/2000/svg", "filter"); + filter.setAttribute("id", `filter_${rgba.toHexString()}`); + filter.appendChild(feColorMatrix); + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + svg.setAttribute("width", "0"); + svg.setAttribute("height", "0"); + svg.appendChild(filter); + colorMatrixCache.appendChild(svg); + colorMatrixIds.set(rgba.toUint32(), filter.getAttribute("id")); + return filter.getAttribute("id"); +} +function createRDFontLayer(text, style) { + const lineHead = new Point(0, -charHeight); + const start = lineHead.clone(); + const layer = document.createElement("div"); + layer.style.position = "absolute"; + for (let i = 0; i < text.length; i++) { + const char = text.charAt(i); + if (char === "\n") { + start.x = lineHead.x; + start.y += lineHeight * style.scale; + } else { + const charCode = char.charCodeAt(0); + const charKey = `char_${charCode.toString(16).padStart(4, "0")}`; + const charInfo = slices.get(charKey); + const charLayer = createLayer(charKey, new Point(start.x, start.y), null, style); + start.x += (charInfo?.bounds.width ?? charHeight) * style.scale; + layer.appendChild(charLayer); + } + } + return layer; +} +function createBackLayer(size, color, style) { + const outline = "event_outline"; + const back = "event_back"; + const backLayer = createLayer(back, new Rect(1, 1, (size?.width ?? iconSize) - 2, (size?.height ?? iconSize) - 2), withState(color, style.active, style.enabled), style); + const outlineLayer = createLayer(outline, size ? new Rect(size) : null, new Color(style.active ? 4294967295 : 4289243304), style); + if (backLayer.onColorChange) { + backLayer.onStateChange = (style2) => backLayer.onColorChange(withState(color, style2.active, style2.enabled)); + } + if (outlineLayer.onColorChange) { + outlineLayer.onStateChange = (style2) => outlineLayer.onColorChange(new Color(style2.active ? 4294967295 : 4289243304)); + } + return [ + backLayer, + outlineLayer + ]; +} +function colorOf(tab) { + switch (tab) { + case Tab.Sounds: + return new Color("d92433"); + case Tab.Rows: + return new Color("2c4fdb"); + case Tab.Actions: + return new Color("c544b3"); + case Tab.Rooms: + return new Color("d8b811"); + case Tab.Decorations: + return new Color("00c459"); + case Tab.Windows: + return new Color("50b5d7"); + default: + return new Color("7d7d7d"); + } +} +function layerHoverInit(layer) { + layer.onStateChange = (style) => { + if (style.hover) { + layer.style.opacity = "1.0"; + } else { + layer.style.opacity = "0"; + } + }; +} +function createElementEvent(obj, style) { + console.log(style); + style = { + ...new IconStyle(), + ...style + }; + const evttype = obj.type; + let key0 = `event_${obj.type}`; + if (!slices.has(key0)) { + console.warn(`Slice for event type ${evttype} not found, using Unknown.`); + if (!slices.has("event_Unknown")) { + return null; + } + key0 = "event_Unknown"; + } + const info = slices.get(key0); + if (!info) { + console.warn(`Slice info for event type ${evttype} not found.`); + return null; + } + const evttypeEnum = EventType[evttype]; + const evinfo = EventInfos[evttypeEnum]; + const key = "event_" + evttype; + const pulse = "event_beat_pulse"; + const hit = "event_beat_hit"; + const hitf = "event_beat_hit_freeze"; + const hitb = "event_beat_hit_burn"; + const beatcross = "event_beat_cross"; + const beatx = "event_beat_x"; + const beatsynco = "event_beat_synco"; + const beatline = "event_beat_line"; + const evtag = "event_tag"; + const evbarea = "event_beat_area"; + const beatColor = new Color(4284539717); + const element = document.createElement("div"); + const internalLayers = []; + function addLayers(layers) { + for (const layer of layers) { + if (layer) { + element.appendChild(layer); + internalLayers.push(layer); + } + } + } + element.style.imageRendering = "pixelated"; + switch (evttype) { + case EventType.AddClassicBeat: + { + const tick = obj.tick ?? 1; + const swing = (obj.swing ?? 0) || 1; + const hold = obj.hold ?? 0; + const syncoSwing = obj.syncoSwing ?? 0; + const prexs = obj.preXs ?? { + syncoBeat: -1, + syncoSwing: 0 + }; + const length = obj.length ?? 7; + const iconWidth = iconSize * (tick * (length - 1 - prexs.syncoSwing)); + const holdBar = hold > 0 ? createLayer(evbarea, new Rect(iconWidth, 0, iconSize * hold, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; + if (holdBar) { + holdBar.style.pointerEvents = "none"; + } + const backLayers2 = createBackLayer(new Size(iconWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); + const pulses = []; + for (let i = 0; i < length - 1; i++) { + const pulseLayer = createLayer(pulse, new Point(iconSize * (tick * (i + i % 2 * (1 - swing) - (i <= prexs.syncoBeat ? 0 : prexs.syncoSwing))), 0), null, style); + layerHoverInit(pulseLayer); + pulses.push(pulseLayer); + } + const hitLayer = createLayer(hit, new Point(iconSize * (tick * (length - 1 - (prexs.syncoSwing ?? 0))) - 1, 0), null, style); + addLayers([ + holdBar, + ...backLayers2, + ...pulses, + hitLayer + ]); + } + break; + case EventType.AddOneshotBeat: + { + const tick = obj.tick ?? 1; + const interval = obj.interval ?? 2; + const loop = obj.loops ?? 0; + const subdiv = obj.subdivisions ?? 1; + const hold = obj.hold ?? false; + const mode = obj.freezeBurnMode ?? null; + const delay = obj.freezeBurnMode === "Freezeshot" ? obj.delay ?? 0 : 0; + const subdivWidth = iconSize * (subdiv - 1) / subdiv * tick; + const eventWidth = iconSize * (interval * loop + tick + delay); + const off = interval - tick; + const backLayers2 = createBackLayer(new Size(eventWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); + const holdWidth = iconSize * (interval - tick - delay); + const holdLayer = hold && holdWidth - subdivWidth > 0 ? createLayer(evbarea, new Rect(eventWidth + subdivWidth, 0, holdWidth - subdivWidth, iconSize), new Color(style.enabled ? 4291839731 : 4285493103), style) : null; + const subdivLayer = subdiv > 1 ? createLayer(evbarea, new Rect(eventWidth, 0, subdivWidth, iconSize), new Color(style.enabled ? 4279480353 : 4285493103), style) : null; + const skipshotLayer = obj.skipshot ?? false ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * interval - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style) : null; + if (holdLayer) holdLayer.style.pointerEvents = "none"; + if (subdivLayer) subdivLayer.style.pointerEvents = "none"; + if (skipshotLayer) skipshotLayer.style.pointerEvents = "none"; + const pulses = []; + const crossLayers = []; + const posx = -off * iconSize; + const hittype = mode === "Freezeshot" ? hitf : hitb; + for (let l = 0; l <= loop; l++) { + for (let i = 0; i < subdiv; i++) { + const pulseLayer = createLayer(pulse, new Point(iconSize * (l * interval + i * tick / subdiv), 0), null, style); + layerHoverInit(pulseLayer); + pulses.push(pulseLayer); + } + for (let i = 0; i < subdiv; i++) { + const hitLayer2 = createLayer(hit, new Point(iconSize * (l * interval + delay + tick + i * tick / subdiv) - 1, 0), null, style); + pulses.push(hitLayer2); + } + const crossLayer1 = mode || hold ? createLayer(beatcross, new Point(iconSize * l * interval + posx - 1, 0), null, style) : null; + const crossLayer2 = mode ? createLayer(beatcross, new Point(iconSize * (l - (mode === "Freezeshot" ? 0 : 1)) * interval - 1, 0), null, style) : null; + const hitLayer = createLayer(hittype, new Point(iconSize * (l * interval + tick) - 1, 0), null, style); + if (crossLayer1) { + layerHoverInit(crossLayer1); + crossLayers.push(crossLayer1); + } + if (crossLayer2) { + layerHoverInit(crossLayer2); + crossLayers.push(crossLayer2); + } + pulses.push(hitLayer); + } + const loopLayer = createLayer("event_beat_loop", new Point(eventWidth, 0), null, style); + loopLayer.style.opacity = "0"; + loopLayer.onStateChange = (style2) => { + if (style2.hover) { + loopLayer.style.opacity = "1.0"; + } else { + loopLayer.style.opacity = "0"; + } + }; + addLayers([ + ...backLayers2, + holdLayer, + subdivLayer, + skipshotLayer, + ...pulses, + loopLayer, + ...crossLayers + ]); + } + break; + case EventType.Comment: + { + const backLayers2 = createBackLayer(info.bounds.size, new Color(obj.color ?? "7d7d7d"), style); + const iconLayer = createLayer(key, null, null, style); + addLayers([ + ...backLayers2, + iconLayer + ]); + } + break; + case EventType.AddFreeTimeBeat: + { + const hold = obj.hold ?? 0; + const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; + if (holdLayer) { + holdLayer.style.pointerEvents = "none"; + } + const backLayers2 = createBackLayer(new Size(info.bounds.width, iconSize), beatColor, style); + const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; + const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style); + textLayer.style.left = `${1.5 * style.scale}px`; + textLayer.style.top = `${10 * style.scale}px`; + addLayers([ + holdLayer, + ...backLayers2, + hitLayer, + textLayer + ]); + } + break; + case EventType.DesktopColor: + { + const duration = obj.duration ?? 0; + const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height * 4), colorOf(obj.tab ?? evinfo.defaultTab), style); + const iconLayer = createLayer(`${key}_0`, new Point(0, info.bounds.height), null, style); + const iconColorLayer = createLayer(key, new Point(0, info.bounds.height), null, style); + const durationLayer = obj.duration > 1 ? createLayer(evbarea, new Rect(iconSize, 0, (duration - 1) * iconSize, info.bounds.height * 4), new Color(4283471790), style) : null; + addLayers([ + ...backLayers2, + durationLayer, + iconLayer, + iconColorLayer + ]); + } + break; + case EventType.PulseFreeTimeBeat: + { + const hold = obj.hold ?? 0; + const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, info.bounds.height), new Color(style.active ? 4291839731 : 4286462352), style) : null; + if (holdLayer) { + holdLayer.style.pointerEvents = "none"; + } + const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height), beatColor, style); + const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; + let text = ""; + switch (obj.action) { + case "Custom": + text = ((obj.customPulse ?? 0) + 1).toString(); + break; + case "Increment": + text = ">"; + break; + case "Decrement": + text = "<"; + break; + case "Remove": + text = "x"; + break; + } + const textLayer = createRDFontLayer(text, style); + textLayer.style.left = `${1.5 * style.scale}px`; + textLayer.style.top = `${10 * style.scale}px`; + addLayers([ + holdLayer, + ...backLayers2, + hitLayer, + textLayer + ]); + } + break; + case EventType.ReorderRooms: + case EventType.ReorderWindows: + { + const backLayers2 = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); + const orderLayers = []; + const order = obj.order ?? [ + 0, + 1, + 2, + 3 + ]; + for (let i = 0; i < order.length; i++) { + { + const orderLayer = createLayer(`${key}_${order[i]}`, new Point(0, i * iconSize), null, style); + orderLayers.push(orderLayer); + } + } + addLayers([ + ...backLayers2, + ...orderLayers + ]); + } + break; + default: + const backLayers = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); + addLayers(backLayers); + switch (evttype) { + case EventType.CustomFlash: + addLayers([ + createLayer(`${key}_0`, null, new Color(obj.startColor ?? "000000"), style), + createLayer(`${key}_1`, null, new Color(obj.endColor ?? "000000"), style) + ]); + break; + case EventType.FlipScreen: + const flip = (obj.flipX ? 1 : 0) | (obj.flipY ? 1 : 0); + if (flip === 0) { + addLayers([ + createLayer(key, null, null, style) + ]); + } else { + addLayers([ + createLayer(`${key}_${flip - 1}`, null, null, style) + ]); + } + default: + const layer = document.createElement("div"); + layer.style.position = "absolute"; + layer.style.left = "0"; + layer.style.top = "0"; + layer.style.width = `${info.bounds.width * style.scale}px`; + layer.style.height = `${info.bounds.height * style.scale}px`; + layer.style.backgroundSize = `${info.bounds.width * style.scale}px ${info.bounds.height * style.scale}px`; + layer.style.backgroundImage = `url(${info.blobUrl})`; + element.appendChild(layer); + break; + } + break; + } + element.onStateChange = (style2) => { + style2 = { + ...style2 + }; + internalLayers.forEach((layer) => { + if (layer.onStateChange) { + layer.onStateChange(style2); + } + }); + }; + return element; +} +export { + createElementEvent +}; diff --git a/script/assets.bin b/script/assets.bin new file mode 100644 index 0000000000000000000000000000000000000000..92ef7480c903dbd28478251478cce7f84cf1ab7a GIT binary patch literal 4299 zcmZ`-&2Jk;6kn4zw1K##q?Aw>)B>e-6xj8*`4CB*E-fMu#cqQ*u$tYS*h|(k%kDZ( z5waq2podh-v5Gi?$gQ{BI6+%Z`3rih5aP@~z?^H;P*49M-<}39%s?u`}>*fh!}F-jqbw9sS(Mg4i8Bpd-srn zzQ9--iTj{qhzE{uC z4a#Dx8F-9&ti1x3{-_;fUY2AUFAgy1 zmi}mJZ|+}t0CV=?!0GhBbS5o2%<)KT%RC{C3 zh!gT_qAoeGD>G>FuunoaA!mV{OOqwZi=*yI1Zv>c*+T+Q*o2c;8Eeuw&2fXXSQrBj zq_LE~LL=`xng#Mis;lMs)CBlK3Kx9JTn(^{M<%lwgkDT*KtGqtH9KUTHl2`CmWI3! zIgqi+GvHnx4# zd&`ecK!vzxNz(zJ@F8kzmle4y_JBUy_oK)f@eC- zdwh{FhiYJMID349HXxHB89+Zu9Z7^K)dU@~8C!HStyl!j*g^qzcz@9&K5zG^tuDtV zkee}ydr{MCvj7-U`@Fj$oDk~vAgeO8md9do8|R@mqw!;L4WR747HQ8Xk4pemlC9p1 zdoeUe4!o37!t8Yd4^<9=loruI?!s9aIwbR!7kRc%Yj9kpU)+H(4N*YB+6K)&#gzBQ z611)fMpT`Xk%@2n)CMbxEZq5`&uG|E#+Tuli4#9f)r{gi%mlQGNO28{ER(YYRT6G# z;LDIiqIE&aL1JYxQmOu~^63WKpds`=yid`d%9?nF#0>=6q?e}e1?i1t8G9;mrpLUf z^BHuOzYTWe$TvEKwW)9xvLtFY0G@Pffke?_$b)ULCa14Kd_V2VB^r0QI{=n!DWPMY zdEI0W$V0rc@*Zu*j4M<+9UNDvd=~R6=P{~Y#5!wl z24m`6{W3=6Dz<0OV&oWD(k)>gtzipm?<4C)UE5TC7LDVZ%6hSI0`rQK7?sXoR6d7M zC5KVh$U;6F{;mCN%9`%*(HpeI+k=l!d}w`mR!4zP+8aRsEEqO zaf}KR7!^-pRGPY@qAizS#k|S|jH;LJs0@~CS1_+WixDYcop$Ap>ZP(%$6DNvF^?|b zb89BjS<$r}rKMtw?Wkxgg%cPRCwEjtmC{R?SAGSf%6TkVeFO7qZ(&rwx}!R>LT0cp z_PbcpDPl>tyrXhfp&ww$wK;^Ux^_=RR5gxcRG7G@BB~a%m{)ok^UCKiuad*4dhwp} zrCNIjpR3PcNupz9m$9T%zo#-$bw9v7`Y}3J&^2-Qq*rK6+P`TJHMxTTvh?4^A8PUq zPA*uV^I+OOIsZ1kpJCCDqS>x9_pN*ZhWE2&_d+&lKbjxI;?Zs9@EN$Meyzq?gdl!gW)cah?9_#y!XS_&sfm+7%hQb=>=MvEMpfIp{JikeILluH}zWX z9VuJbhi6G{UZ&6Cbz^O@?pXRRykJK$j6GmTqiQvcOdT0%`jMYznoqHmmNwJYxdJR0l1fvGFWgdn*o2BPL>iQLjS$?MZ741JXRIeHU literal 0 HcmV?d00001 diff --git a/script/assets.png b/script/assets.png new file mode 100644 index 0000000000000000000000000000000000000000..e4d05383beeade28a733a02a4342c3c46f1dc9e4 GIT binary patch literal 6653 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 Hu0mjfFf!)X literal 0 HcmV?d00001 diff --git a/script/special.js b/script/special.js index 930c5cf..5e8373a 100644 --- a/script/special.js +++ b/script/special.js @@ -1,3 +1,5 @@ +import { createElementEvent } from "./View.js"; + let curx = 0; let cury = 0; let rowx; @@ -198,10 +200,133 @@ function rdview() { textarea.addEventListener('input', initCanvas); } +function rdview2() { + let rdview = document.getElementsByClassName("rdview2")[0]; + if (!rdview) return; + let rdcanvas = rdview.querySelector(".canvas"); + let textarea = rdview.querySelector("textarea.area"); + let number = rdview.querySelector(".number"); + const textareaStyles = window.getComputedStyle(textarea); + [ + 'fontFamily', 'fontSize', 'fontWeight', + 'letterSpacing', 'lineHeight', 'padding', + ].forEach(property => { + number.style[property] = textareaStyles[property]; + }); + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + const font = `${textareaStyles.fontSize} ${textareaStyles.fontFamily}`; + context.font = font; + function calcStringLines(sentence, width) { + if (!width) return 0; + const words = sentence.split(''); + let lineCount = 0; + + let currentLine = ''; + for (let i = 0; i < words.length; i++) { + const wordWidth = context.measureText(words[i]).width; + const lineWidth = context.measureText(currentLine).width; + if (lineWidth + wordWidth > width) { + lineCount++; + currentLine = words[i]; + } else { + currentLine += words[i]; + } + } + if (currentLine.trim() !== '') lineCount++; + return lineCount; + } + function calcLines() { + const lines = textarea.value.split('\n'); + const textareaWidth = textarea.getBoundingClientRect().width; + const textareaScrollWidth = textareaWidth - textarea.clientWidth; + const parseNumber = (v) => v.endsWith('px') ? parseInt(v.slice(0, -2), 10) : 0; + const textareaPaddingLeft = parseNumber(textareaStyles.paddingLeft); + const textareaPaddingRight = parseNumber(textareaStyles.paddingRight); + const textareaContentWidth = textareaWidth - textareaPaddingLeft - textareaPaddingRight - textareaScrollWidth; + const numLines = lines.map(lineString => calcStringLines(lineString, textareaContentWidth)); + let lineNumbers = []; + let i = 1; + while (numLines.length > 0) { + const numLinesOfSentence = numLines.shift(); + lineNumbers.push(i); + if (numLinesOfSentence > 1) { + Array(numLinesOfSentence - 1) + .fill('') + .forEach((_) => lineNumbers.push('')); + } + i++; + } + return lineNumbers; + } + function initLineNumbers() { + const lines = calcLines(); + const lineDoms = Array.from({ + length: lines.length, + }, (_, i) => `
${lines[i] || ' '}
`); + number.innerHTML = lineDoms.join(''); + } + function initCanvas() { + // const lang = textarea.value.split('\n')[0] + // const code = textarea.value.split('\n').slice(1).join('\n') + // rdcanvas.innerHTML = RDViewRender(lang, code) + const objs = JSON.parse(`[${textarea.value}]`); + const eventStyle = {"scale": 2.0, "showDuration": false }; + let maxy = 0; + 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); + }); + 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); + } + } + //rdcanvas.innerHTML = RDView2Render(json); + } + initCanvas() + initLineNumbers() + textarea.addEventListener('input', initLineNumbers); + textarea.addEventListener('input', initCanvas); +} + window.$docsify.plugins = [].concat(window.$docsify.plugins, function (hook) { hook.doneEach(function () { themePosition(); rdview(); + rdview2(); document.documentElement.scrollTop = document.body.scrollTop = 0; }); }); + +import("./docsify.min.js").then(() => { + +}); \ No newline at end of file diff --git a/style/special.css b/style/special.css index a5db117..7ca8cae 100644 --- a/style/special.css +++ b/style/special.css @@ -162,7 +162,7 @@ div.theme-positions>.infobox { .markdown-section:has(div.rdview) {} -div.rdview { +div.rdview, div.rdview2 { & div.canvas { width: 100%; } From 006a5fe4f53387bd3db771d9f8bee2f9f9da14fa Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Wed, 14 Jan 2026 00:46:21 +0800 Subject: [PATCH 10/16] changelog --- pages/changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pages/changelog.md b/pages/changelog.md index 255722d..a3038ea 100644 --- a/pages/changelog.md +++ b/pages/changelog.md @@ -1,5 +1,10 @@ # 更新信息 +#### 2026-01-14 +- 制作人员表增加了 +- RDView 对正式版编辑器新特性的部分适配 +- 正在逐步同步 RDView2(RhythmBase.View) 的适配 + #### 2025-11-29 - 调整目录结构 - 双人模式措辞更改 From fb2e0e124b4cb1cc6d722f63772ecca76d2509f9 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Wed, 14 Jan 2026 00:55:38 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20json=20=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=BC=82=E5=B8=B8=E6=9C=AA=E6=8D=95=E8=8E=B7=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 4 +- script/View.js | 1 - script/special.js | 241 +++++++++++++++++++++++++++++----------------- 3 files changed, 154 insertions(+), 92 deletions(-) diff --git a/index.html b/index.html index 95d0522..8dc7901 100644 --- a/index.html +++ b/index.html @@ -136,8 +136,8 @@ - + > --> diff --git a/script/View.js b/script/View.js index ebf2918..57d27c6 100644 --- a/script/View.js +++ b/script/View.js @@ -728,7 +728,6 @@ function layerHoverInit(layer) { }; } function createElementEvent(obj, style) { - console.log(style); style = { ...new IconStyle(), ...style diff --git a/script/special.js b/script/special.js index 5e8373a..aeddffd 100644 --- a/script/special.js +++ b/script/special.js @@ -23,7 +23,7 @@ let positions = { "r5": { "y": 78, "name": "二轨时的第二轨/四轨时的第二轨" }, "r6": { "y": 57, "name": "三轨时的第一轨" }, "r7": { "y": 36, "name": "四轨时的第一轨" }, -} +}; function themePosition() { let theme_positions = document.getElementById("theme-positions"); @@ -63,45 +63,74 @@ function themePosition() { rowx = null; columny = null; for (let key in positions) { - if (positions[key].x !== null && Math.abs(x - positions[key].x) < 5) + if ( + positions[key].x !== null && Math.abs(x - positions[key].x) < 5 + ) { rowx = positions[key].x; - if (positions[key].y !== null && Math.abs(y - positions[key].y) < 5) + } + if ( + positions[key].y !== null && Math.abs(y - positions[key].y) < 5 + ) { columny = positions[key].y; + } } if (rowx) { - perx.innerText = (rowx / 3.52).toFixed(2) + "%" - perx.classList.add("c") - pxx.innerText = rowx + "px" - pxx.classList.add("c") - } - else { - perx.innerText = x_percent.toFixed(2) + "%" - perx.classList.remove("c") - pxx.innerText = x + "px" - pxx.classList.remove("c") + perx.innerText = (rowx / 3.52).toFixed(2) + "%"; + perx.classList.add("c"); + pxx.innerText = rowx + "px"; + pxx.classList.add("c"); + } else { + perx.innerText = x_percent.toFixed(2) + "%"; + perx.classList.remove("c"); + pxx.innerText = x + "px"; + pxx.classList.remove("c"); } if (columny) { - pery.innerText = (100 - columny / 1.98).toFixed(2) + "%" - pery.classList.add("c") - pxy.innerText = 198 - columny + "px" - pxy.classList.add("c") - } - else { - pery.innerText = (100 - y_percent).toFixed(2) + "%" - pery.classList.remove("c") - pxy.innerText = 198 - y + "px" - pxy.classList.remove("c") + pery.innerText = (100 - columny / 1.98).toFixed(2) + "%"; + pery.classList.add("c"); + pxy.innerText = 198 - columny + "px"; + pxy.classList.add("c"); + } else { + pery.innerText = (100 - y_percent).toFixed(2) + "%"; + pery.classList.remove("c"); + pxy.innerText = 198 - y + "px"; + pxy.classList.remove("c"); } infobox.style.right = "calc(" + (100 - x_percent) + "% + 10px)"; - infobox.style.top = "calc(" + (y_percent) + "% + 10px)"; - selectbox.style.left = rowx ? (rowx / 3.52 - 3.41) + "%" : columny ? "0" : "calc(" + x_percent + "% - 3px"; - selectbox.style.bottom = columny ? (100 - columny / 1.98 - 5.305) + "%" : rowx ? "0" : "calc(" + (100 - y_percent) + "% - 3px)"; + infobox.style.top = "calc(" + y_percent + "% + 10px)"; + selectbox.style.left = rowx + ? (rowx / 3.52 - 3.41) + "%" + : columny + ? "0" + : "calc(" + x_percent + "% - 3px"; + selectbox.style.bottom = columny + ? (100 - columny / 1.98 - 5.305) + "%" + : rowx + ? "0" + : "calc(" + (100 - y_percent) + "% - 3px)"; selectbox.style.width = rowx ? "6.82%" : columny ? "100%" : "6px"; selectbox.style.height = columny ? "10.61%" : rowx ? "100%" : "6px"; - let rowname = rowx ? positions[Object.keys(positions).find(key => positions[key].x === rowx)].name : ""; - let columnname = columny ? positions[Object.keys(positions).find(key => positions[key].y === columny)].name : ""; - theme_positions.querySelector(".other").innerText = rowname && columnname ? columnname + "上的" + rowname : rowname ? rowname : columnname ? columnname : ""; + let rowname = rowx + ? positions[ + Object.keys(positions).find((key) => positions[key].x === rowx) + ].name + : ""; + let columnname = columny + ? positions[ + Object.keys(positions).find((key) => + positions[key].y === columny + ) + ].name + : ""; + theme_positions.querySelector(".other").innerText = + rowname && columnname + ? columnname + "上的" + rowname + : rowname + ? rowname + : columnname + ? columnname + : ""; }); theme_positions.addEventListener("mouseleave", function (event) { perx.innerText = "100%"; @@ -114,13 +143,12 @@ function themePosition() { selectbox.style.bottom = "50%"; selectbox.style.width = "0"; selectbox.style.height = "0"; - perx.classList.remove("c") - pery.classList.remove("c") - pxx.classList.remove("c") - pxy.classList.remove("c") + perx.classList.remove("c"); + pery.classList.remove("c"); + pxx.classList.remove("c"); + pxy.classList.remove("c"); other.innerText = ""; }); - } function rdview() { @@ -131,21 +159,25 @@ function rdview() { let number = rdview.querySelector(".number"); const textareaStyles = window.getComputedStyle(textarea); [ - 'fontFamily', 'fontSize', 'fontWeight', - 'letterSpacing', 'lineHeight', 'padding', - ].forEach(property => { + "fontFamily", + "fontSize", + "fontWeight", + "letterSpacing", + "lineHeight", + "padding", + ].forEach((property) => { number.style[property] = textareaStyles[property]; }); - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); const font = `${textareaStyles.fontSize} ${textareaStyles.fontFamily}`; context.font = font; function calcStringLines(sentence, width) { if (!width) return 0; - const words = sentence.split(''); + const words = sentence.split(""); let lineCount = 0; - let currentLine = ''; + let currentLine = ""; for (let i = 0; i < words.length; i++) { const wordWidth = context.measureText(words[i]).width; const lineWidth = context.measureText(currentLine).width; @@ -156,18 +188,22 @@ function rdview() { currentLine += words[i]; } } - if (currentLine.trim() !== '') lineCount++; + if (currentLine.trim() !== "") lineCount++; return lineCount; } function calcLines() { - const lines = textarea.value.split('\n'); + const lines = textarea.value.split("\n"); const textareaWidth = textarea.getBoundingClientRect().width; const textareaScrollWidth = textareaWidth - textarea.clientWidth; - const parseNumber = (v) => v.endsWith('px') ? parseInt(v.slice(0, -2), 10) : 0; + const parseNumber = (v) => + v.endsWith("px") ? parseInt(v.slice(0, -2), 10) : 0; const textareaPaddingLeft = parseNumber(textareaStyles.paddingLeft); const textareaPaddingRight = parseNumber(textareaStyles.paddingRight); - const textareaContentWidth = textareaWidth - textareaPaddingLeft - textareaPaddingRight - textareaScrollWidth; - const numLines = lines.map(lineString => calcStringLines(lineString, textareaContentWidth)); + const textareaContentWidth = textareaWidth - textareaPaddingLeft - + textareaPaddingRight - textareaScrollWidth; + const numLines = lines.map((lineString) => + calcStringLines(lineString, textareaContentWidth) + ); let lineNumbers = []; let i = 1; while (numLines.length > 0) { @@ -175,8 +211,8 @@ function rdview() { lineNumbers.push(i); if (numLinesOfSentence > 1) { Array(numLinesOfSentence - 1) - .fill('') - .forEach((_) => lineNumbers.push('')); + .fill("") + .forEach((_) => lineNumbers.push("")); } i++; } @@ -186,18 +222,18 @@ function rdview() { const lines = calcLines(); const lineDoms = Array.from({ length: lines.length, - }, (_, i) => `
${lines[i] || ' '}
`); - number.innerHTML = lineDoms.join(''); + }, (_, i) => `
${lines[i] || " "}
`); + number.innerHTML = lineDoms.join(""); } function initCanvas() { - const lang = textarea.value.split('\n')[0] - const code = textarea.value.split('\n').slice(1).join('\n') - rdcanvas.innerHTML = RDViewRender(lang, code) + const lang = textarea.value.split("\n")[0]; + const code = textarea.value.split("\n").slice(1).join("\n"); + rdcanvas.innerHTML = RDViewRender(lang, code); } - initCanvas() - initLineNumbers() - textarea.addEventListener('input', initLineNumbers); - textarea.addEventListener('input', initCanvas); + initCanvas(); + initLineNumbers(); + textarea.addEventListener("input", initLineNumbers); + textarea.addEventListener("input", initCanvas); } function rdview2() { @@ -208,21 +244,25 @@ function rdview2() { let number = rdview.querySelector(".number"); const textareaStyles = window.getComputedStyle(textarea); [ - 'fontFamily', 'fontSize', 'fontWeight', - 'letterSpacing', 'lineHeight', 'padding', - ].forEach(property => { + "fontFamily", + "fontSize", + "fontWeight", + "letterSpacing", + "lineHeight", + "padding", + ].forEach((property) => { number.style[property] = textareaStyles[property]; }); - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); const font = `${textareaStyles.fontSize} ${textareaStyles.fontFamily}`; context.font = font; function calcStringLines(sentence, width) { if (!width) return 0; - const words = sentence.split(''); + const words = sentence.split(""); let lineCount = 0; - let currentLine = ''; + let currentLine = ""; for (let i = 0; i < words.length; i++) { const wordWidth = context.measureText(words[i]).width; const lineWidth = context.measureText(currentLine).width; @@ -233,18 +273,22 @@ function rdview2() { currentLine += words[i]; } } - if (currentLine.trim() !== '') lineCount++; + if (currentLine.trim() !== "") lineCount++; return lineCount; } function calcLines() { - const lines = textarea.value.split('\n'); + const lines = textarea.value.split("\n"); const textareaWidth = textarea.getBoundingClientRect().width; const textareaScrollWidth = textareaWidth - textarea.clientWidth; - const parseNumber = (v) => v.endsWith('px') ? parseInt(v.slice(0, -2), 10) : 0; + const parseNumber = (v) => + v.endsWith("px") ? parseInt(v.slice(0, -2), 10) : 0; const textareaPaddingLeft = parseNumber(textareaStyles.paddingLeft); const textareaPaddingRight = parseNumber(textareaStyles.paddingRight); - const textareaContentWidth = textareaWidth - textareaPaddingLeft - textareaPaddingRight - textareaScrollWidth; - const numLines = lines.map(lineString => calcStringLines(lineString, textareaContentWidth)); + const textareaContentWidth = textareaWidth - textareaPaddingLeft - + textareaPaddingRight - textareaScrollWidth; + const numLines = lines.map((lineString) => + calcStringLines(lineString, textareaContentWidth) + ); let lineNumbers = []; let i = 1; while (numLines.length > 0) { @@ -252,8 +296,8 @@ function rdview2() { lineNumbers.push(i); if (numLinesOfSentence > 1) { Array(numLinesOfSentence - 1) - .fill('') - .forEach((_) => lineNumbers.push('')); + .fill("") + .forEach((_) => lineNumbers.push("")); } i++; } @@ -263,25 +307,46 @@ function rdview2() { const lines = calcLines(); const lineDoms = Array.from({ length: lines.length, - }, (_, i) => `
${lines[i] || ' '}
`); - number.innerHTML = lineDoms.join(''); + }, (_, i) => `
${lines[i] || " "}
`); + number.innerHTML = lineDoms.join(""); } function initCanvas() { // const lang = textarea.value.split('\n')[0] // const code = textarea.value.split('\n').slice(1).join('\n') // rdcanvas.innerHTML = RDViewRender(lang, code) - const objs = JSON.parse(`[${textarea.value}]`); - const eventStyle = {"scale": 2.0, "showDuration": false }; + // try { + // JSON.parse(`[${textarea.value}]`); + // } catch (e) { + // rdcanvas.innerHTML = `
JSON解析错误:${e.message}
`; + // } + let objs = []; + try { + objs = JSON.parse(`[${textarea.value}]`); + } catch (e) { + rdcanvas.innerHTML = + `
JSON解析错误:${e.message}
`; + return; + } + const eventStyle = { "scale": 2.0, "showDuration": false }; let maxy = 0; for (let obj of objs) { - const style = {... eventStyle, enabled: obj.active ?? true }; + 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.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; @@ -308,16 +373,15 @@ function rdview2() { rdcanvas.style.height = `${maxy + 4 * 14 * eventStyle.scale}px`; if (elem) { rdcanvas.appendChild(elem); + } } - } - //rdcanvas.innerHTML = RDView2Render(json); } - initCanvas() - initLineNumbers() - textarea.addEventListener('input', initLineNumbers); - textarea.addEventListener('input', initCanvas); + //rdcanvas.innerHTML = RDView2Render(json); + initCanvas(); + initLineNumbers(); + textarea.addEventListener("input", initLineNumbers); + textarea.addEventListener("input", initCanvas); } - window.$docsify.plugins = [].concat(window.$docsify.plugins, function (hook) { hook.doneEach(function () { themePosition(); @@ -328,5 +392,4 @@ window.$docsify.plugins = [].concat(window.$docsify.plugins, function (hook) { }); import("./docsify.min.js").then(() => { - -}); \ No newline at end of file +}); From 758645041b55cf89dab2eebaa6ea7bdbe326a1a0 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Wed, 14 Jan 2026 22:20:06 +0800 Subject: [PATCH 12/16] =?UTF-8?q?[RDView2]=20DOM=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=8C=E5=B7=A5=EF=BC=8C=E8=BF=9B=E5=85=A5?= =?UTF-8?q?=E5=8F=AF=E8=A1=8C=E6=80=A7=E6=B5=8B=E8=AF=95=E9=98=B6=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 35 +- pages/appendix_tools.md | 79 +- {script => rdviewAssets}/assets.bin | Bin 4299 -> 4326 bytes rdviewAssets/assets.png | Bin 7459 -> 6646 bytes script/Extensions.js | 1176 --------------------------- script/View.js | 576 ++++++++++--- script/assets.png | Bin 6653 -> 0 bytes script/rdview2.js | 143 ---- script/special.js | 10 +- 9 files changed, 548 insertions(+), 1471 deletions(-) rename {script => rdviewAssets}/assets.bin (66%) delete mode 100644 script/Extensions.js delete mode 100644 script/assets.png delete mode 100644 script/rdview2.js diff --git a/index.html b/index.html index 8dc7901..552e396 100644 --- a/index.html +++ b/index.html @@ -19,8 +19,8 @@ - -
加载中...
+ +
加载中...
- diff --git a/pages/appendix_tools.md b/pages/appendix_tools.md index 3d1ea8b..b9fe73d 100644 --- a/pages/appendix_tools.md +++ b/pages/appendix_tools.md @@ -23,22 +23,69 @@ g 1 1 5 4 #0ff{ ---
--- \ No newline at end of file diff --git a/script/assets.bin b/rdviewAssets/assets.bin similarity index 66% rename from script/assets.bin rename to rdviewAssets/assets.bin index 92ef7480c903dbd28478251478cce7f84cf1ab7a..2c1e294273840c8a547aecb8dd5761cf9caa2b25 100644 GIT binary patch delta 180 zcmX@D_)JmanNVt3YFS(K a;N}Fzvph@=29x#p+L;`gHgDq-WdZ<3S477E delta 108 zcmaE+cv_M1=|qV~zDF$1F$$-arRJ5y2d9?!CT8Y^XXd5kmmkqO$0!654@%8T%uR&~ z%ba5rfe5>#7H5~_7dYqVk diff --git a/rdviewAssets/assets.png b/rdviewAssets/assets.png index 028437289ecd91c8cf7f7f3d6d22d8d1858cb389..7b9cbb9235cda4699063f54216ca73a0946c1526 100644 GIT binary patch literal 6646 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 e3T3o6v}%bdywNuO;kUn@01Xvg= this.left && point.x <= this.right && point.y >= this.top && point.y <= this.bottom; - } -}; -var Color = class _Color { - red; - green; - blue; - alpha; - constructor(r, g, b, a) { - if (typeof r === "string") { - if (r.startsWith("#")) { - r = r.substring(1); - } - r = r.trim(); - switch (r.length) { - case 3: - r = r.split("").map((c) => c + c).join(""); - break; - case 4: - r = "ff" + r.split("").map((c) => c + c).join(""); - break; - case 6: - r = "ff" + r; - break; - case 8: - break; - default: - r = "ffffffff"; - } - const u = parseInt(r, 16); - this.alpha = u >> 24 & 255; - this.red = u >> 16 & 255; - this.green = u >> 8 & 255; - this.blue = u & 255; - return; - } - if (r !== void 0 && g === void 0 && b === void 0 && a === void 0) { - this.alpha = r >> 24 & 255; - this.red = r >> 16 & 255; - this.green = r >> 8 & 255; - this.blue = r & 255; - return; - } - if (r !== void 0 && g !== void 0 && b !== void 0 && a === void 0) { - this.red = r; - this.green = g; - this.blue = b; - this.alpha = 255; - return; - } - this.red = r ?? 0; - this.green = g ?? 0; - this.blue = b ?? 0; - this.alpha = a ?? 0; - } - toUint32() { - return ((this.alpha & 255) << 24 | (this.red & 255) << 16 | (this.green & 255) << 8 | this.blue & 255) >>> 0; - } - clone() { - return new _Color(this.red, this.green, this.blue, this.alpha); - } -}; -var Paint = class { - color = new Color(255, 255, 255, 255); -}; -var SliceInfo = class { - bounds = new Rect(); - center = new Rect(); - pivot = new Point(); - scale = 1; - get isNinePatch() { - return !this.center.isEmpty; - } -}; -var AssetManager = class _AssetManager { - static AssetFilePath = "assets.png"; - static SlicesFilePath = "assets.json"; - static DirectoryPath = "."; - static assetFile = null; - static slices = /* @__PURE__ */ new Map(); - static _isLoaded = false; - constructor(dirpath) { - _AssetManager.DirectoryPath = dirpath; - _AssetManager.initialize(); - } - static get isLoaded() { - return this._isLoaded; - } - static async loadAssetFile() { - const pngPath = _AssetManager.DirectoryPath + "/" + this.AssetFilePath; - return await new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = (e) => reject(new Error(`Failed to load asset file: ${pngPath}`)); - img.src = pngPath; - }); - } - static async loadSlices() { - if (this._isLoaded) { - return /* @__PURE__ */ new Map(); - } - const jsonPath = _AssetManager.DirectoryPath + "/" + this.SlicesFilePath; - const response = await fetch(jsonPath); - const json = await response.json(); - const slices = json["meta"]["slices"]; - const sliceInfos = /* @__PURE__ */ new Map(); - for (const slice of slices) { - const name = slice["name"]; - const keys = slice["keys"]; - const sliceInfo = new SliceInfo(); - for (const key of keys) { - const bounds = key["bounds"]; - sliceInfo.bounds.left = bounds["x"]; - sliceInfo.bounds.top = bounds["y"]; - sliceInfo.bounds.right = bounds["x"] + bounds["w"]; - sliceInfo.bounds.bottom = bounds["y"] + bounds["h"]; - const center = key["center"]; - if (center) { - sliceInfo.center.left = center["x"]; - sliceInfo.center.top = center["y"]; - sliceInfo.center.right = center["x"] + center["w"]; - sliceInfo.center.bottom = center["y"] + center["h"]; - } - const pivot = key["pivot"]; - if (pivot) { - sliceInfo.pivot.x = pivot["x"]; - sliceInfo.pivot.y = pivot["y"]; - } - const data = key["data"]; - if (data) { - } - sliceInfos.set(name, sliceInfo); - } - } - return sliceInfos; - } - static async initialize() { - if (this._isLoaded) { - return; - } - this.assetFile = await this.loadAssetFile(); - this.slices = await this.loadSlices(); - this._isLoaded = true; - } -}; - -// RhythmBase.View/Assets/Consts.ts -var Tab = /* @__PURE__ */ function(Tab2) { - Tab2["Sounds"] = "sounds"; - Tab2["Rows"] = "rows"; - Tab2["Actions"] = "actions"; - Tab2["Decorations"] = "decorations"; - Tab2["Rooms"] = "rooms"; - Tab2["Windows"] = "windows"; - Tab2["Unknown"] = "unknown"; - return Tab2; -}({}); -var EventType = /* @__PURE__ */ function(EventType2) { - EventType2["AddClassicBeat"] = "AddClassicBeat"; - EventType2["AddFreeTimeBeat"] = "AddFreeTimeBeat"; - EventType2["AddOneshotBeat"] = "AddOneshotBeat"; - EventType2["AdvanceText"] = "AdvanceText"; - EventType2["BassDrop"] = "BassDrop"; - EventType2["Blend"] = "Blend"; - EventType2["CallCustomMethod"] = "CallCustomMethod"; - EventType2["ChangeCharacter"] = "ChangeCharacter"; - EventType2["ChangePlayersRows"] = "ChangePlayersRows"; - EventType2["Comment"] = "Comment"; - EventType2["CustomFlash"] = "CustomFlash"; - EventType2["DesktopColor"] = "DesktopColor"; - EventType2["FadeRoom"] = "FadeRoom"; - EventType2["FinishLevel"] = "FinishLevel"; - EventType2["Flash"] = "Flash"; - EventType2["FlipScreen"] = "FlipScreen"; - EventType2["FloatingText"] = "FloatingText"; - EventType2["ForwardDecorationEvent"] = "ForwardDecorationEvent"; - EventType2["ForwardEvent"] = "ForwardEvent"; - EventType2["ForwardRowEvent"] = "ForwardRowEvent"; - EventType2["HideRow"] = "HideRow"; - EventType2["HideWindow"] = "HideWindow"; - EventType2["InvertColors"] = "InvertColors"; - EventType2["MacroEvent"] = "MacroEvent"; - EventType2["MaskRoom"] = "MaskRoom"; - EventType2["Move"] = "Move"; - EventType2["MoveCamera"] = "MoveCamera"; - EventType2["MoveRoom"] = "MoveRoom"; - EventType2["MoveRow"] = "MoveRow"; - EventType2["NarrateRowInfo"] = "NarrateRowInfo"; - EventType2["NewWindowDance"] = "NewWindowDance"; - EventType2["PaintHands"] = "PaintHands"; - EventType2["PlayAnimation"] = "PlayAnimation"; - EventType2["PlayExpression"] = "PlayExpression"; - EventType2["PlaySong"] = "PlaySong"; - EventType2["PlaySound"] = "PlaySound"; - EventType2["PulseCamera"] = "PulseCamera"; - EventType2["PulseFreeTimeBeat"] = "PulseFreeTimeBeat"; - EventType2["ReadNarration"] = "ReadNarration"; - EventType2["RenameWindow"] = "RenameWindow"; - EventType2["ReorderRooms"] = "ReorderRooms"; - EventType2["ReorderRow"] = "ReorderRow"; - EventType2["ReorderSprite"] = "ReorderSprite"; - EventType2["ReorderWindows"] = "ReorderWindows"; - EventType2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; - EventType2["SetBackgroundColor"] = "SetBackgroundColor"; - EventType2["SetBeatSound"] = "SetBeatSound"; - EventType2["SetBeatsPerMinute"] = "SetBeatsPerMinute"; - EventType2["SetClapSounds"] = "SetClapSounds"; - EventType2["SetCountingSound"] = "SetCountingSound"; - EventType2["SetCrotchetsPerBar"] = "SetCrotchetsPerBar"; - EventType2["SetForeground"] = "SetForeground"; - EventType2["SetGameSound"] = "SetGameSound"; - EventType2["SetHandOwner"] = "SetHandOwner"; - EventType2["SetHeartExplodeInterval"] = "SetHeartExplodeInterval"; - EventType2["SetHeartExplodeVolume"] = "SetHeartExplodeVolume"; - EventType2["SetMainWindow"] = "SetMainWindow"; - EventType2["SetOneshotWave"] = "SetOneshotWave"; - EventType2["SetPlayStyle"] = "SetPlayStyle"; - EventType2["SetRoomContentMode"] = "SetRoomContentMode"; - EventType2["SetRoomPerspective"] = "SetRoomPerspective"; - EventType2["SetRowXs"] = "SetRowXs"; - EventType2["SetSpeed"] = "SetSpeed"; - EventType2["SetTheme"] = "SetTheme"; - EventType2["SetVFXPreset"] = "SetVFXPreset"; - EventType2["SetVisible"] = "SetVisible"; - EventType2["SetWindowContent"] = "SetWindowContent"; - EventType2["ShakeScreen"] = "ShakeScreen"; - EventType2["ShakeScreenCustom"] = "ShakeScreenCustom"; - EventType2["ShowDialogue"] = "ShowDialogue"; - EventType2["ShowHands"] = "ShowHands"; - EventType2["ShowRooms"] = "ShowRooms"; - EventType2["ShowStatusSign"] = "ShowStatusSign"; - EventType2["ShowSubdivisionsRows"] = "ShowSubdivisionsRows"; - EventType2["SpinningRows"] = "SpinningRows"; - EventType2["Stutter"] = "Stutter"; - EventType2["TagAction"] = "TagAction"; - EventType2["TextExplosion"] = "TextExplosion"; - EventType2["Tile"] = "Tile"; - EventType2["Tint"] = "Tint"; - EventType2["TintRows"] = "TintRows"; - EventType2["WindowResize"] = "WindowResize"; - return EventType2; -}({}); -var EventAttriblte = /* @__PURE__ */ function(EventAttriblte2) { - EventAttriblte2[EventAttriblte2["None"] = 0] = "None"; - EventAttriblte2[EventAttriblte2["DurationEvent"] = 1] = "DurationEvent"; - EventAttriblte2[EventAttriblte2["RoomEvent"] = 2] = "RoomEvent"; - return EventAttriblte2; -}({}); -var EventInfo = class { - defaultTab; - durationKey = "duration"; - attr; - get isDurationEvent() { - return (this.attr & EventAttriblte.DurationEvent) !== 0; - } - get isRoomEvent() { - return (this.attr & EventAttriblte.RoomEvent) !== 0; - } - constructor(tab, enumAttriblte, durationKey) { - this.defaultTab = tab; - this.attr = enumAttriblte ?? EventAttriblte.None; - if (durationKey !== void 0) { - this.durationKey = durationKey; - } - } -}; -var WordInfo = class { - phrase; - length; - constructor(phrase, length) { - this.phrase = phrase; - this.length = length; - } -}; -var WordInfos = { - SayReaDyGetSetGoNew: new WordInfo("Rea, Dy, Get, Set, Go!", 4), - SayReaDyGetSetOne: new WordInfo("Rea, Dy, Get, Set, One!", 4), - SayGetSetGo: new WordInfo("Get, Set, Go!", 2), - SayGetSetOne: new WordInfo("Get, Set, One!", 2), - JustSayRea: new WordInfo("Rea", 0), - JustSayDy: new WordInfo("Dy", 0), - JustSayGet: new WordInfo("Get", 0), - JustSaySet: new WordInfo("Set", 0), - JustSayAnd: new WordInfo("And", 0), - JustSayGo: new WordInfo("Go!", 0), - JustSayStop: new WordInfo("Stop", 0), - JustSayAndStop: new WordInfo("And Stop!", 0), - SaySwitch: new WordInfo("Switch", 0), - SayWatch: new WordInfo("Watch", 0), - SayListen: new WordInfo("Listen", 0), - Count1: new WordInfo("1", 0), - Count2: new WordInfo("2", 0), - Count3: new WordInfo("3", 0), - Count4: new WordInfo("4", 0), - Count5: new WordInfo("5", 0), - Count6: new WordInfo("6", 0), - Count7: new WordInfo("7", 0), - Count8: new WordInfo("8", 0), - Count9: new WordInfo("9", 0), - Count10: new WordInfo("10", 0), - SayReadyGetSetGo: new WordInfo("Ready, Get, Set, Go!", 4), - JustSayReady: new WordInfo("Ready", 0) -}; -var EventInfos = { - AddClassicBeat: new EventInfo(Tab.Rows), - AddFreeTimeBeat: new EventInfo(Tab.Rows), - AddOneshotBeat: new EventInfo(Tab.Rows), - AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - BassDrop: new EventInfo(Tab.Actions), - Blend: new EventInfo(Tab.Decorations), - CallCustomMethod: new EventInfo(Tab.Actions), - ChangeCharacter: new EventInfo(Tab.Actions), - ChangePlayersRows: new EventInfo(Tab.Actions), - Comment: new EventInfo(Tab.Unknown), - CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), - FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - FinishLevel: new EventInfo(Tab.Actions), - Flash: new EventInfo(Tab.Actions), - FlipScreen: new EventInfo(Tab.Actions), - FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - ForwardDecorationEvent: new EventInfo(Tab.Decorations), - ForwardEvent: new EventInfo(Tab.Unknown), - ForwardRowEvent: new EventInfo(Tab.Rows), - HideRow: new EventInfo(Tab.Actions), - HideWindow: new EventInfo(Tab.Windows), - InvertColors: new EventInfo(Tab.Actions), - MacroEvent: new EventInfo(Tab.Unknown), - MaskRoom: new EventInfo(Tab.Rooms), - Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - MoveRow: new EventInfo(Tab.Rows, EventAttriblte.DurationEvent), - NarrateRowInfo: new EventInfo(Tab.Sounds), - NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - PlayAnimation: new EventInfo(Tab.Decorations), - PlayExpression: new EventInfo(Tab.Actions), - PlaySong: new EventInfo(Tab.Sounds), - PlaySound: new EventInfo(Tab.Sounds), - PulseCamera: new EventInfo(Tab.Actions), - PulseFreeTimeBeat: new EventInfo(Tab.Rows), - ReadNarration: new EventInfo(Tab.Sounds), - RenameWindow: new EventInfo(Tab.Windows), - ReorderRooms: new EventInfo(Tab.Rooms), - ReorderRow: new EventInfo(Tab.Rows), - ReorderSprite: new EventInfo(Tab.Decorations), - ReorderWindows: new EventInfo(Tab.Windows), - SayReadyGetSetGo: new EventInfo(Tab.Sounds), - SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetBeatSound: new EventInfo(Tab.Sounds), - SetBeatsPerMinute: new EventInfo(Tab.Sounds), - SetClapSounds: new EventInfo(Tab.Sounds), - SetCountingSound: new EventInfo(Tab.Sounds), - SetCrotchetsPerBar: new EventInfo(Tab.Sounds), - SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetGameSound: new EventInfo(Tab.Sounds), - SetHandOwner: new EventInfo(Tab.Actions), - SetHeartExplodeInterval: new EventInfo(Tab.Sounds), - SetHeartExplodeVolume: new EventInfo(Tab.Sounds), - SetMainWindow: new EventInfo(Tab.Windows), - SetOneshotWave: new EventInfo(Tab.Rows), - SetPlayStyle: new EventInfo(Tab.Actions), - SetRoomContentMode: new EventInfo(Tab.Rooms), - SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - SetRowXs: new EventInfo(Tab.Rows), - SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetVisible: new EventInfo(Tab.Decorations), - SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), - ShakeScreen: new EventInfo(Tab.Actions), - ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - ShowDialogue: new EventInfo(Tab.Actions), - ShowHands: new EventInfo(Tab.Actions), - ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - ShowSubdivisionsRows: new EventInfo(Tab.Actions), - SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - Stutter: new EventInfo(Tab.Actions), - TagAction: new EventInfo(Tab.Actions), - TextExplosion: new EventInfo(Tab.Actions), - Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent) -}; - -// RhythmBase.View/Extensions.ts -var PatchStyle = /* @__PURE__ */ function(PatchStyle2) { - PatchStyle2[PatchStyle2["Repeat"] = 0] = "Repeat"; - PatchStyle2[PatchStyle2["Strentch"] = 1] = "Strentch"; - return PatchStyle2; -}(PatchStyle || {}); -var IconStyle = class { - Enabled; - Active = false; - Hover = false; - Scale = 2; -}; -var Extensions = class { - static lineHeight = 6; - static charHeight = 8; - static iconSize = 14; - static evtag = "event_tag"; - static evbarea = "event_beat_area"; - static asm = new AssetManager("./rdviewAssets"); - constructor() { - AssetManager.initialize(); - } - static DrawSlice(canvas, src, dest, scale = 1, style = PatchStyle.Strentch, color) { - const ctx = canvas; - if (!ctx) return; - if (!AssetManager.slices.has(src)) { - return; - } - const info = AssetManager.slices.get(src); - if (dest instanceof Point) { - const destRect = new Rect(dest.x - info.pivot.x * scale, dest.y - info.pivot.y * scale, info.bounds.width * scale, info.bounds.height * scale); - if (color) { - if (color.alpha === 0) { - return destRect; - } - this.drawSliceWithColor(ctx, info, destRect, color); - } else { - this.drawSliceNormal(ctx, info, destRect); - } - return destRect; - } else { - if (info.isNinePatch) { - this.DrawNinePatch(canvas, info, dest, color, scale, style); - } else { - if (color) { - this.drawSliceWithColor(ctx, info, dest, color); - } else { - this.drawSliceNormal(ctx, info, dest); - } - } - } - } - static drawSliceNormal(ctx, info, destRect) { - const bitmap = AssetManager.assetFile; - if (!bitmap) return; - ctx.imageSmoothingEnabled = false; - ctx.drawImage(bitmap, info.bounds.x, info.bounds.y, info.bounds.width, info.bounds.height, destRect.x, destRect.y, destRect.width, destRect.height); - } - static drawSliceWithColor(ctx, info, destRect, color) { - const bitmap = AssetManager.assetFile; - if (!bitmap) return; - if (color.alpha === 0) { - return; - } - const tr = color.red / 255; - const tg = color.green / 255; - const tb = color.blue / 255; - const ta = color.alpha / 255; - ctx.save(); - const tempCanvas = typeof document !== "undefined" ? document.createElement("canvas") : {}; - tempCanvas.width = info.bounds.width; - tempCanvas.height = info.bounds.height; - const tempCtx = tempCanvas.getContext("2d"); - tempCtx.imageSmoothingEnabled = false; - tempCtx.drawImage(bitmap, info.bounds.x, info.bounds.y, info.bounds.width, info.bounds.height, 0, 0, info.bounds.width, info.bounds.height); - const imageData = tempCtx.getImageData(0, 0, info.bounds.width, info.bounds.height); - const data = imageData.data; - for (let i = 0; i < data.length; i += 4) { - const originalAlpha = data[i + 3]; - const gray = data[i] * 0.2126 + data[i + 1] * 0.7152 + data[i + 2] * 0.0722; - data[i] = gray * tr; - data[i + 1] = gray * tg; - data[i + 2] = gray * tb; - data[i + 3] = originalAlpha * ta; - } - tempCtx.putImageData(imageData, 0, 0); - ctx.imageSmoothingEnabled = false; - ctx.globalAlpha = 1; - ctx.drawImage(tempCanvas, 0, 0, info.bounds.width, info.bounds.height, destRect.x, destRect.y, destRect.width, destRect.height); - ctx.restore(); - } - static DrawNinePatch(canvas, info, dest, color, scale = 1, style = PatchStyle.Strentch) { - const ctx = canvas; - if (!ctx) return; - const bitmap = AssetManager.assetFile; - if (!bitmap) return; - const srcBounds = info.bounds; - const destRect = dest; - const centerBounds = info.center; - const sx0 = srcBounds.left; - const sx3 = srcBounds.right; - const sy0 = srcBounds.top; - const sy3 = srcBounds.bottom; - const sx1 = sx0 + centerBounds.left; - const sx2 = sx0 + centerBounds.right; - const sy1 = sy0 + centerBounds.top; - const sy2 = sy0 + centerBounds.bottom; - const swLeft = sx1 - sx0; - const swCenter = sx2 - sx1; - const swRight = sx3 - sx2; - const shTop = sy1 - sy0; - const shCenter = sy2 - sy1; - const shBottom = sy3 - sy2; - const dwLeft = swLeft * scale; - let dwRight = swRight * scale; - let dwCenter = destRect.width - dwLeft - dwRight; - if (dwCenter < 0) { - const scaleX = destRect.width / Math.max(1, swLeft + swRight); - dwRight = Math.max(0, destRect.width - Math.round(swLeft * scaleX)); - dwCenter = 0; - } - const dhTop = shTop * scale; - let dhBottom = shBottom * scale; - let dhCenter = destRect.height - dhTop - dhBottom; - if (dhCenter < 0) { - const scaleY = destRect.height / Math.max(1, shTop + shBottom); - dhBottom = Math.max(0, destRect.height - Math.round(shTop * scaleY)); - dhCenter = 0; - } - const srcXs = [ - sx0, - sx1, - sx2, - sx3 - ]; - const srcYs = [ - sy0, - sy1, - sy2, - sy3 - ]; - const dx0 = destRect.left; - const dx1 = dx0 + dwLeft; - const dx2 = dx1 + dwCenter; - const dx3 = destRect.right; - const dy0 = destRect.top; - const dy1 = dy0 + dhTop; - const dy2 = dy1 + dhCenter; - const dy3 = destRect.bottom; - const dstXs = [ - dx0, - dx1, - dx2, - dx3 - ]; - const dstYs = [ - dy0, - dy1, - dy2, - dy3 - ]; - for (let row = 0; row < 3; row++) { - for (let col = 0; col < 3; col++) { - const sLeft = srcXs[col]; - const sTop = srcYs[row]; - const sRight = srcXs[col + 1]; - const sBottom = srcYs[row + 1]; - const sW = sRight - sLeft; - const sH = sBottom - sTop; - if (sW <= 0 || sH <= 0) continue; - const dLeft = dstXs[col]; - const dTop = dstYs[row]; - const dRight = dstXs[col + 1]; - const dBottom = dstYs[row + 1]; - const dW = dRight - dLeft; - const dH = dBottom - dTop; - if (dW <= 0 || dH <= 0) continue; - if (style === PatchStyle.Repeat) { - for (let y = dTop; y < dBottom; y += sH * scale) { - const th = Math.min(sH, (dBottom - y) / scale); - for (let x = dLeft; x < dRight; x += sW * scale) { - const tw = Math.min(sW, (dRight - x) / scale); - var sRect = new Rect(sLeft, sTop, tw, th); - var dRect = new Rect(x, y, tw * scale, th * scale); - if (color && color.alpha > 0) { - this.drawSliceWithColor(ctx, { - bounds: sRect, - pivot: new Point(0, 0), - isNinePatch: false, - center: new Rect(), - scale: 1 - }, dRect, color); - } else { - this.drawSliceNormal(ctx, { - bounds: sRect, - pivot: new Point(0, 0), - isNinePatch: false, - center: new Rect(), - scale: 1 - }, dRect); - } - } - } - } else { - if (color && color.alpha > 0) { - this.drawSliceWithColor(ctx, { - bounds: new Rect(sLeft, sTop, sW, sH), - pivot: new Point(0, 0), - isNinePatch: false, - center: new Rect(), - scale: 1 - }, new Rect(dLeft, dTop, dW, dH), color); - } else { - ctx.imageSmoothingEnabled = false; - ctx.drawImage(bitmap, sLeft, sTop, sW, sH, dLeft, dTop, dW, dH); - } - } - } - } - } - static MeasureRDFontText(canvas, text, scale = 1) { - let len = 0; - for (let i = 0; i < text.length; i++) { - const c = text.charAt(i); - if (c === "\n") { - len = 0; - } else { - const info = AssetManager.slices.get(`char_${c.charCodeAt(0).toString(16).padStart(4, "0")}`); - if (info) { - len += info.bounds.width * scale; - } - } - } - return len; - } - static DrawRDFontText(canvas, text, dest, color, scale = 1) { - const start = dest.clone(); - const result = new Rect(); - start.y -= this.lineHeight * scale; - for (let i = 0; i < text.length; i++) { - const c = text.charAt(i); - if (c === "\n") { - start.x = dest.x; - start.y += this.lineHeight * scale; - continue; - } else { - const charcode = c.charCodeAt(0).toString(16).padStart(4, "0"); - const area = this.DrawSlice(canvas, `char_${charcode}`, start, scale, PatchStyle.Strentch, color); - result.union(area); - start.x += area.width * scale; - } - } - return result; - } - static DrawEventIcon(canvas, evt, dest, style) { - let destRect = new Rect(); - const key = `event_${evt.type}`; - const evttype = evt.type; - const info = AssetManager.slices.get(key) ?? AssetManager.slices.get("event_Unknown") ?? (() => { - throw new Error("information not found."); - }); - if (!(info instanceof SliceInfo)) { - return new Rect(); - } - const pulse = "event_beat_pulse"; - const hit = "event_beat_hit"; - const hitf = "event_beat_hit_freeze"; - const hitb = "event_beat_hit_burn"; - const beatcross = "event_beat_cross"; - const beatx = "event_beat_x"; - const beatsynco = "event_beat_synco"; - const beatline = "event_beat_line"; - const beatcolor = new Color(4284539717); - const evtInfo = EventInfos[evt.type]; - evt.tab = evt.tab ?? evtInfo.defaultTab; - switch (evt.type) { - case EventType.AddClassicBeat: - { - const tick = evt.tick ?? 1; - const swing = evt.swing === 0 ? 1 : evt.swing; - const hold = evt.hold ?? 0; - const syncoswing = evt.syncoSwing ?? 0; - const syncobeat = evt.syncoBeat ?? -1; - const classicbeatlength = evt.length ?? 7; - destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale * (tick * (classicbeatlength - 1 - (syncoswing ?? 0))), this.iconSize * style.Scale); - if (hold > 0) { - this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, this.iconSize * style.Scale * hold, this.iconSize * style.Scale), style.Scale, PatchStyle.Repeat, new Color(style.Active ? 4291839731 : 4286462352)); - } - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - if (style.Hover) { - for (let i = 0; i < classicbeatlength - 1; i++) { - this.DrawSlice(canvas, pulse, new Point(dest.x + this.iconSize * style.Scale * (tick * (i + i % 2 * (1 - (swing ?? 1)) - (i <= (syncobeat ?? -1) ? 0 : syncoswing ?? 0))), dest.y), style.Scale); - } - } - this.DrawSlice(canvas, hit, new Point(dest.x + style.Scale * (this.iconSize * (tick * (classicbeatlength - 1 - (syncoswing ?? 0))) - 1), dest.y), style.Scale); - } - break; - case EventType.AddFreeTimeBeat: - { - const hold = (evt.hold ?? 0) - info.bounds.width / this.iconSize; - destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(beatcolor.clone(), style.Active, style.Enabled ?? evt.active ?? true), style); - this.DrawRDFontText(canvas, ((evt.pulse ?? 0) + 1).toString(), new Point(dest.x + 1.5 * style.Scale, dest.y + 10 * style.Scale), new Color(4294967295), style.Scale); - if ((evt.pulse ?? 0) == 6) { - this.DrawSlice(canvas, hit, new Point(dest.x, dest.y), style.Scale); - } - if (hold > 0) { - this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, this.iconSize * style.Scale * hold, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(style.Active ? 4284539717 : 4281299234)); - } - } - break; - case EventType.AddOneshotBeat: - { - const tick = evt.tick ?? 1; - const interval = evt.interval ?? 1; - const loop = Math.floor(evt.loops ?? 0); - const subdiv = evt.subdivisions ?? 1; - const freezeBurnMode = evt.freezeBurnMode ?? "Wave"; - const delay = freezeBurnMode === "Freezeshot" ? evt.delay ?? 0 : 0; - destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale * (loop * interval + tick + delay), this.iconSize * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - const subdivwidth = this.iconSize * style.Scale * (subdiv - 1) / subdiv * tick; - if (subdiv > 1) { - this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, subdivwidth, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(4279480353)); - } - if (evt.skipshot ?? false) { - this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width + subdivwidth, dest.y, style.Scale * this.iconSize * interval - subdivwidth, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(4291115835)); - } - if (style.Hover) { - for (let l = 0; l <= loop; l++) { - for (let i = 0; i < subdiv; i++) { - this.DrawSlice(canvas, pulse, new Point(dest.x + this.iconSize * style.Scale * (l * interval + i * tick / subdiv), dest.y), style.Scale); - } - } - } - for (let l = 0; l <= loop; l++) { - for (let i = 0; i < subdiv; i++) { - this.DrawSlice(canvas, hit, new Point(dest.x + style.Scale * (this.iconSize * (l * interval + delay + tick + i * tick / subdiv) - 1), dest.y), style.Scale); - } - } - const off = interval - tick; - if (freezeBurnMode !== "Wave") { - let posx = dest.x - off * style.Scale * this.iconSize; - this.DrawSlice(canvas, beatcross, new Point(posx, dest.y), style.Scale); - switch (freezeBurnMode) { - case "Freezeshot": - posx += delay * style.Scale * this.iconSize; - this.DrawSlice(canvas, beatcross, new Point(posx, dest.y), style.Scale); - for (let l = 0; l <= loop; l++) { - this.DrawSlice(canvas, hitf, new Point(dest.x + style.Scale * (this.iconSize * (l * interval + tick) - 1), dest.y), style.Scale); - } - break; - case "Burnshot": - posx -= tick * style.Scale * this.iconSize; - this.DrawSlice(canvas, beatcross, new Point(posx, dest.y), style.Scale); - for (let l = 0; l <= loop; l++) { - this.DrawSlice(canvas, hitb, new Point(dest.x + style.Scale * (this.iconSize * (l * interval + tick) - 1), dest.y), style.Scale); - } - break; - default: - break; - } - } - if (style.Active && style.Hover) { - this.DrawSlice(canvas, "event_beat_loop", new Point(destRect.right, destRect.top), style.Scale); - } - } - break; - case EventType.Comment: - { - const commentColor = new Color(evt.color); - console.log(evt.color, commentColor); - destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(commentColor, style.Active, style.Enabled ?? evt.active ?? true), style); - this.DrawSlice(canvas, key, dest, style.Scale); - } - break; - case EventType.DesktopColor: - { - destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * 4 * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - const endColor = new Color(evt.endColor); - this.DrawSlice(canvas, `${key}_0`, new Point(dest.x, dest.y + info.bounds.height * style.Scale), style.Scale, PatchStyle.Strentch, endColor); - this.DrawSlice(canvas, key, new Point(dest.x, dest.y + info.bounds.height * style.Scale), style.Scale); - } - break; - case EventType.PulseFreeTimeBeat: - { - const hold = (evt.hold ?? 0) - info.bounds.width / this.iconSize; - destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(beatcolor.clone(), style.Active, style.Enabled ?? evt.active ?? true), style); - let actionText; - switch (evt.action) { - case "Increment": - actionText = ">"; - break; - case "Decrement": - actionText = "<"; - break; - case "Remove": - actionText = "x"; - break; - case "Custom": - default: - actionText = ((evt.customPulse ?? 0) + 1).toString(); - break; - } - this.DrawRDFontText(canvas, actionText, new Point(dest.x + 1.5 * style.Scale, dest.y + 8 * style.Scale), new Color(4294967295), style.Scale); - if (evt.action === "Custom" && (evt.customPulse ?? 0) === 7) { - this.DrawSlice(canvas, hit, new Rect(dest.x - 2 * style.Scale, dest.y, 5 * style.Scale, info.bounds.height * style.Scale), style.Scale, PatchStyle.Strentch); - } - if (hold > 0) { - this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, this.iconSize * style.Scale * hold, info.bounds.height * style.Scale), style.Scale, PatchStyle.Repeat, new Color(style.Active ? 4291839731 : 4286462352)); - } - } - break; - case EventType.ReorderRooms: - { - destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale, this.iconSize * 4 * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - let currentDest = dest.clone(); - if (evt.order && Array.isArray(evt.order)) { - for (const r of evt.order) { - this.DrawSlice(canvas, `${key}_${r}`, currentDest.clone(), style.Scale); - currentDest.y += this.iconSize * style.Scale; - } - } - } - break; - case EventType.ReorderWindows: - { - destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale, this.iconSize * 4 * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - let currentDest = dest.clone(); - if (evt.order && Array.isArray(evt.order)) { - for (const r of evt.order) { - this.DrawSlice(canvas, `${key}_${r}`, currentDest.clone(), style.Scale); - currentDest.y += this.iconSize * style.Scale; - } - } - } - break; - case EventType.SayReadyGetSetGo: - { - const wordInfo = WordInfos[evt.phraseToSay]; - const len = wordInfo.length * evt.tick + 1; - destRect = new Rect(dest.x, dest.y, len * this.iconSize * style.Scale, this.iconSize * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - const stringToJion = wordInfo.phrase.split(" "); - let stringToDraw = [ - stringToJion[0] - ]; - let lw = this.MeasureRDFontText(canvas, stringToJion[0]); - const sw = this.MeasureRDFontText(canvas, " "); - for (let i = 1; i < stringToJion.length; i++) { - const part = stringToJion[i]; - const w = this.MeasureRDFontText(canvas, part); - if (lw + sw + w > (len * this.iconSize - 2) * style.Scale) { - lw = w; - stringToDraw.push(part); - } else { - lw += sw + w; - stringToDraw[stringToDraw.length - 1] += " " + part; - } - } - stringToDraw.splice(3); - const c = stringToDraw.length; - const top = dest.y + (this.iconSize - this.charHeight * c / 2) * style.Scale / 2; - for (let i = 0; i < c; i++) { - const line = stringToDraw[i]; - const p = new Point(dest.x + (len * this.iconSize * style.Scale - this.MeasureRDFontText(canvas, line, style.Scale / 2)) / 2, top + (i * this.charHeight + this.lineHeight) * style.Scale / 2); - this.DrawRDFontText(canvas, line, p, new Color(4294967295), style.Scale / 2); - } - } - break; - case EventType.SetRowXs: - { - destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - const width = info.bounds.width * style.Scale / 6; - const beatxInfo = AssetManager.slices.get(beatx); - if (!beatxInfo) break; - const iconwidth = beatxInfo.bounds.width; - const s = width / iconwidth; - let left = 0; - const top = this.iconSize * style.Scale / 2 - beatxInfo.bounds.height * s / 2; - if (evt.pattern) { - const pattern = evt.pattern; - for (const p of pattern) { - const patternKey = p === "x" ? beatx : beatline; - this.DrawSlice(canvas, patternKey, new Rect(dest.x + left, dest.y + top, width, beatxInfo.bounds.height * s), style.Scale, PatchStyle.Strentch); - left += width; - } - } - if ((evt.syncoBeat ?? -1) >= 0) { - this.DrawSlice(canvas, beatsynco, new Rect(dest.x + width * (evt.syncoBeat ?? 0), dest.y + top, width, beatxInfo.bounds.height * s), style.Scale, PatchStyle.Strentch); - } - } - break; - case EventType.ShowRooms: - { - destRect = new Rect(dest.x, dest.y, this.iconSize * style.Scale, this.iconSize * 4 * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - if (evt.rooms && Array.isArray(evt.rooms)) { - for (let i = 0; i < 4; i++) { - const roomState = evt.rooms[i] ? "1" : "0"; - this.DrawSlice(canvas, `${key}_${roomState}`, new Point(dest.x, dest.y + i * this.iconSize * style.Scale), style.Scale / 2); - } - } - } - break; - default: - destRect = new Rect(dest.x, dest.y, info.bounds.width * style.Scale, info.bounds.height * style.Scale); - this.DrawBack(canvas, destRect.clone(), this.WithState(this.ColorOf(evt.tab), style.Active, style.Enabled ?? evt.active ?? true), style); - switch (evt.type) { - case EventType.CustomFlash: - { - this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.startColor ?? 0)); - this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.endColor ?? 0)); - } - break; - case EventType.FlipScreen: - { - let suffix = ""; - const flipX = evt.flipX ?? false; - const flipY = evt.flipY ?? false; - if (flipX && flipY) { - suffix = "_2"; - } else if (flipX && !flipY) { - suffix = "_1"; - } else if (!flipX && flipY) { - suffix = "_0"; - } - this.DrawSlice(canvas, key + suffix, dest, style.Scale); - } - break; - case EventType.FloatingText: - { - this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.color ?? 0)); - this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.outlineColor ?? 0)); - } - break; - case EventType.MoveRoom: - { - canvas.save(); - const degree = evt.angle ?? 0; - const scaleWidth = evt.scale?.width ?? 0; - const scaleHeight = evt.scale?.height ?? 0; - if (scaleWidth === 0 || scaleHeight === 0) { - canvas.restore(); - break; - } - const pleft = (evt.pivot?.x ?? 0) / 100; - const ptop = 1 - (evt.pivot?.y ?? 0) / 100; - const uniform = Math.sqrt(scaleWidth * scaleWidth + scaleHeight * scaleHeight); - const w = scaleWidth / uniform; - const h = scaleHeight / uniform; - canvas.translate(dest.x + destRect.width / 2, dest.y + destRect.height / 2); - canvas.rotate(-degree * Math.PI / 180); - canvas.scale(w, h); - this.DrawSlice(canvas, key, new Point(-destRect.width / 2, -destRect.height / 2), style.Scale); - if (!(pleft < 0 || pleft > 1 || ptop < 0 || ptop > 1)) { - canvas.fillStyle = "rgb(255, 0, 0)"; - canvas.fillRect((pleft - 0.5) * destRect.width - 1, (ptop - 0.5) * destRect.height - 1, 2, 2); - } - canvas.restore(); - } - break; - case EventType.PaintHands: - { - this.DrawSlice(canvas, key, dest, style.Scale, PatchStyle.Strentch, new Color(evt.tintColor ?? 0)); - const border = evt.border ?? "None"; - if (border === "Outline") { - this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); - } else if (border === "Glow") { - this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); - } - } - break; - case EventType.SetBackgroundColor: - { - this.DrawSlice(canvas, key, dest, style.Scale); - const bgType = evt.backgroundType ?? "Color"; - if (bgType === "Color") { - this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.color ?? 0)); - } else if (bgType === "Image") { - this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(4294967295)); - } - } - break; - case EventType.SetCrotchetsPerBar: - { - const cpb = evt.crotchetsPerBar ?? 4; - this.DrawSlice(canvas, key, dest, style.Scale); - this.DrawRDFontText(canvas, cpb > 9 ? "-" : cpb.toString(), new Point(dest.x + 2 * style.Scale, dest.y + 7 * style.Scale), new Color(4278190080), style.Scale); - this.DrawRDFontText(canvas, "4", new Point(dest.x + 8 * style.Scale, dest.y + 12 * style.Scale), new Color(4278190080), style.Scale); - } - break; - case EventType.SetForeground: - { - this.DrawSlice(canvas, key, dest, style.Scale); - } - break; - case EventType.Tint: - { - this.DrawSlice(canvas, key, dest, style.Scale, PatchStyle.Strentch, new Color(evt.tintColor ?? 0)); - const border = evt.border ?? "None"; - if (border === "Outline") { - this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); - } else if (border === "Glow") { - this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); - } - } - break; - case EventType.TintRows: - { - this.DrawSlice(canvas, key, dest, style.Scale, PatchStyle.Strentch, new Color(evt.tintColor ?? 0)); - const border = evt.border ?? "None"; - if (border === "Outline") { - this.DrawSlice(canvas, `${key}_0`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); - } else if (border === "Glow") { - this.DrawSlice(canvas, `${key}_1`, dest, style.Scale, PatchStyle.Strentch, new Color(evt.borderColor ?? 0)); - } - } - break; - default: - this.drawSliceNormal(canvas, info, destRect); - break; - } - break; - } - if (evtInfo.isDurationEvent) { - evt.duration = 2; - } - if (evt.duration && evt.duration > 0 && style.Active) { - const duration = evt[evtInfo.durationKey]; - const durWidth = style.Scale * this.iconSize * duration - destRect.width; - const c = this.ColorOf(evt.tab); - c.alpha = style.Active ? 192 : 91; - if (durWidth > 0) { - this.DrawSlice(canvas, this.evbarea, new Rect(dest.x + destRect.width, dest.y, durWidth, destRect.height), style.Scale, PatchStyle.Repeat, c); - } - } - return destRect; - } - static ColorOf(tab) { - switch (tab) { - case "sounds": - return new Color(4292355123); - case "rows": - return new Color(4281094105); - case "actions": - return new Color(4291118003); - case "decorations": - return new Color(4278240345); - case "rooms": - return new Color(4292392978); - case "windows": - return new Color(4283479511); - default: - return new Color(4286874756); - } - } - static DrawBack(canvas, destRect, color, style) { - const outline = "event_outline"; - const back = "event_back"; - this.DrawSlice(canvas, outline, destRect, style.Scale, PatchStyle.Strentch, new Color(style.Active ? 4294967295 : 4289243304)); - destRect.inflate(-style.Scale, -style.Scale); - this.DrawSlice(canvas, back, destRect, style.Scale, PatchStyle.Strentch, color); - } - static WithState(color, active, enabled) { - const c = enabled ? color.clone() : new Color(4286874756); - c.alpha = active ? 192 : 91; - return c; - } -}; -export { - AssetManager, - Color, - Extensions, - IconStyle, - Paint, - Point, - Rect, - SliceInfo -}; diff --git a/script/View.js b/script/View.js index 57d27c6..52c6413 100644 --- a/script/View.js +++ b/script/View.js @@ -213,7 +213,22 @@ var Color = class _Color { return new _Color(this.argb); } static FromRgba(r, g, b, a) { - return new _Color(a, r, g, b); + if (typeof r === "string" && g === void 0 && b === void 0 && a === void 0) { + r = r.trim(); + if (r[0] === "#") r = r.slice(1); + if (r.length === 8) { + return new _Color(r.slice(6, 8) + r.slice(0, 6)); + } else if (r.length === 6) return new _Color(r); + else if (r.length === 4) { + return new _Color(r[3] + r[3] + r.slice(0, 3).split("").map((i) => i + i).join("")); + } else if (r.length === 3) { + return new _Color("FF" + r.split("").map((i) => i + i).join("")); + } else return new _Color(); + } else if (typeof r === "number" && typeof g === "number" && typeof b === "number" && typeof a === "number") { + return new _Color(a, r, g, b); + } else { + return new _Color(); + } } toRgbaString() { return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a / 255})`; @@ -263,7 +278,7 @@ var SliceInfo = class { }; var assetFilePath = "assets.png"; var slicesFilePath = "assets.bin"; -var directoryPath = "./script"; +var directoryPath = "./rdviewAssets"; async function loadAssetFile() { const pngPath = directoryPath + "/" + assetFilePath; return await new Promise((resolve, reject) => { @@ -351,6 +366,36 @@ var Tab = /* @__PURE__ */ function(Tab2) { Tab2["Unknown"] = "unknown"; return Tab2; }({}); +var SayReadyGetSetGoWords = /* @__PURE__ */ function(SayReadyGetSetGoWords2) { + SayReadyGetSetGoWords2["SayReaDyGetSetGoNew"] = "SayReaDyGetSetGoNew"; + SayReadyGetSetGoWords2["SayReaDyGetSetOne"] = "SayReaDyGetSetOne"; + SayReadyGetSetGoWords2["SayGetSetGo"] = "SayGetSetGo"; + SayReadyGetSetGoWords2["SayGetSetOne"] = "SayGetSetOne"; + SayReadyGetSetGoWords2["JustSayRea"] = "JustSayRea"; + SayReadyGetSetGoWords2["JustSayDy"] = "JustSayDy"; + SayReadyGetSetGoWords2["JustSayGet"] = "JustSayGet"; + SayReadyGetSetGoWords2["JustSaySet"] = "JustSaySet"; + SayReadyGetSetGoWords2["JustSayAnd"] = "JustSayAnd"; + SayReadyGetSetGoWords2["JustSayGo"] = "JustSayGo"; + SayReadyGetSetGoWords2["JustSayStop"] = "JustSayStop"; + SayReadyGetSetGoWords2["JustSayAndStop"] = "JustSayAndStop"; + SayReadyGetSetGoWords2["SaySwitch"] = "SaySwitch"; + SayReadyGetSetGoWords2["SayWatch"] = "SayWatch"; + SayReadyGetSetGoWords2["SayListen"] = "SayListen"; + SayReadyGetSetGoWords2["Count1"] = "Count1"; + SayReadyGetSetGoWords2["Count2"] = "Count2"; + SayReadyGetSetGoWords2["Count3"] = "Count3"; + SayReadyGetSetGoWords2["Count4"] = "Count4"; + SayReadyGetSetGoWords2["Count5"] = "Count5"; + SayReadyGetSetGoWords2["Count6"] = "Count6"; + SayReadyGetSetGoWords2["Count7"] = "Count7"; + SayReadyGetSetGoWords2["Count8"] = "Count8"; + SayReadyGetSetGoWords2["Count9"] = "Count9"; + SayReadyGetSetGoWords2["Count10"] = "Count10"; + SayReadyGetSetGoWords2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; + SayReadyGetSetGoWords2["JustSayReady"] = "JustSayReady"; + return SayReadyGetSetGoWords2; +}({}); var EventType = /* @__PURE__ */ function(EventType2) { EventType2["AddClassicBeat"] = "AddClassicBeat"; EventType2["AddFreeTimeBeat"] = "AddFreeTimeBeat"; @@ -455,9 +500,7 @@ var EventInfo = class { constructor(tab, enumAttriblte, durationKey) { this.defaultTab = tab; this.attr = enumAttriblte ?? EventAttriblte.None; - if (durationKey !== void 0) { - this.durationKey = durationKey; - } + this.durationKey = durationKey ?? "duration"; } }; var WordInfo = class { @@ -501,20 +544,20 @@ var EventInfos = { AddClassicBeat: new EventInfo(Tab.Rows), AddFreeTimeBeat: new EventInfo(Tab.Rows), AddOneshotBeat: new EventInfo(Tab.Rows), - AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), BassDrop: new EventInfo(Tab.Actions), Blend: new EventInfo(Tab.Decorations), CallCustomMethod: new EventInfo(Tab.Actions), ChangeCharacter: new EventInfo(Tab.Actions), ChangePlayersRows: new EventInfo(Tab.Actions), Comment: new EventInfo(Tab.Unknown), - CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), - FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), + FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), FinishLevel: new EventInfo(Tab.Actions), Flash: new EventInfo(Tab.Actions), FlipScreen: new EventInfo(Tab.Actions), - FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), ForwardDecorationEvent: new EventInfo(Tab.Decorations), ForwardEvent: new EventInfo(Tab.Unknown), ForwardRowEvent: new EventInfo(Tab.Rows), @@ -523,13 +566,13 @@ var EventInfos = { InvertColors: new EventInfo(Tab.Actions), MacroEvent: new EventInfo(Tab.Unknown), MaskRoom: new EventInfo(Tab.Rooms), - Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), NarrateRowInfo: new EventInfo(Tab.Sounds), - NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), PlayAnimation: new EventInfo(Tab.Decorations), PlayExpression: new EventInfo(Tab.Actions), PlaySong: new EventInfo(Tab.Sounds), @@ -543,13 +586,13 @@ var EventInfos = { ReorderSprite: new EventInfo(Tab.Decorations), ReorderWindows: new EventInfo(Tab.Windows), SayReadyGetSetGo: new EventInfo(Tab.Sounds), - SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetBeatSound: new EventInfo(Tab.Sounds), SetBeatsPerMinute: new EventInfo(Tab.Sounds), SetClapSounds: new EventInfo(Tab.Sounds), SetCountingSound: new EventInfo(Tab.Sounds), SetCrotchetsPerBar: new EventInfo(Tab.Sounds), - SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetGameSound: new EventInfo(Tab.Sounds), SetHandOwner: new EventInfo(Tab.Actions), SetHeartExplodeInterval: new EventInfo(Tab.Sounds), @@ -558,28 +601,28 @@ var EventInfos = { SetOneshotWave: new EventInfo(Tab.Rows), SetPlayStyle: new EventInfo(Tab.Actions), SetRoomContentMode: new EventInfo(Tab.Rooms), - SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), SetRowXs: new EventInfo(Tab.Rows), - SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetVisible: new EventInfo(Tab.Decorations), - SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), - ShakeScreen: new EventInfo(Tab.Actions), - ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), + ShakeScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), ShowDialogue: new EventInfo(Tab.Actions), ShowHands: new EventInfo(Tab.Actions), - ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), ShowSubdivisionsRows: new EventInfo(Tab.Actions), - SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), Stutter: new EventInfo(Tab.Actions), TagAction: new EventInfo(Tab.Actions), TextExplosion: new EventInfo(Tab.Actions), - Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent) + Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration") }; // View.ts @@ -600,8 +643,8 @@ function createLayer(key, bound, color, style) { const layer = document.createElement("div"); const info = slices.get(key); layer.style.position = "absolute"; - layer.style.boxSizing = "content-box"; - if (info.isNinePatch) { + layer.style.boxSizing = "content-box"; + if (info?.isNinePatch) { const center = info.center; const width = bound?.width ?? info.bounds.width; const height = bound?.height ?? info.bounds.height; @@ -617,12 +660,25 @@ function createLayer(key, bound, color, style) { layer.style.width = `${(width - center.left - (info.bounds.width - center.right)) * style.scale}px`; layer.style.height = `${(height - center.top - (info.bounds.height - center.bottom)) * style.scale}px`; } else { - layer.style.left = `${((bound?.left ?? bound?.x ?? 0) - info.pivot.x) * style.scale}px`; - layer.style.top = `${((bound?.top ?? bound?.y ?? 0) - info.pivot.y) * style.scale}px`; - layer.style.width = `${(bound?.width ?? info.bounds.width) * style.scale}px`; - layer.style.height = `${(bound?.height ?? info.bounds.height) * style.scale}px`; - layer.style.backgroundImage = `url(${info.blobUrl})`; - layer.style.backgroundSize = `${bound?.width ?? info.bounds.width * style.scale}px ${bound?.height ?? info.bounds.height * style.scale}px`; + if (bound instanceof Rect) { + layer.style.left = `${(bound.left - (info?.pivot.x ?? 0)) * style.scale}px`; + layer.style.top = `${(bound.top - (info?.pivot.y ?? 0)) * style.scale}px`; + layer.style.width = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px`; + layer.style.height = `${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; + if (info) { + layer.style.backgroundImage = `url(${info.blobUrl})`; + } + layer.style.backgroundSize = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px ${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; + } else { + layer.style.left = `${((bound?.x ?? 0) - (info?.pivot.x ?? 0)) * style.scale}px`; + layer.style.top = `${((bound?.y ?? 0) - (info?.pivot.y ?? 0)) * style.scale}px`; + layer.style.width = `${(info?.bounds.width ?? 0) * style.scale}px`; + layer.style.height = `${(info?.bounds.height ?? 0) * style.scale}px`; + if (info) { + layer.style.backgroundImage = `url(${info.blobUrl})`; + } + layer.style.backgroundSize = `${(info?.bounds.width ?? 0) * style.scale}px ${(info?.bounds.height ?? 0) * style.scale}px`; + } } if (color && Color.White.equals(color) === false) { const filterId = getColorMatrixId(color); @@ -663,7 +719,22 @@ function getColorMatrixId(rgba) { colorMatrixIds.set(rgba.toUint32(), filter.getAttribute("id")); return filter.getAttribute("id"); } -function createRDFontLayer(text, style) { +function measureRDFontText(text) { + let len = 0; + for (let i = 0; i < text.length; i++) { + const char = text.charAt(i); + if (char === "\n") { + len = 0; + } else { + const charCode = char.charCodeAt(0); + const charKey = `char_${charCode.toString(16).padStart(4, "0")}`; + const charInfo = slices.get(charKey); + len += charInfo?.bounds.width ?? 0; + } + } + return len; +} +function createRDFontLayer(text, style, color) { const lineHead = new Point(0, -charHeight); const start = lineHead.clone(); const layer = document.createElement("div"); @@ -677,9 +748,11 @@ function createRDFontLayer(text, style) { const charCode = char.charCodeAt(0); const charKey = `char_${charCode.toString(16).padStart(4, "0")}`; const charInfo = slices.get(charKey); - const charLayer = createLayer(charKey, new Point(start.x, start.y), null, style); - start.x += (charInfo?.bounds.width ?? charHeight) * style.scale; - layer.appendChild(charLayer); + if (charInfo) { + const charLayer = createLayer(charKey, new Point(start.x, start.y), color, style); + start.x += charInfo.bounds.width * style.scale; + layer.appendChild(charLayer); + } } } return layer; @@ -719,6 +792,7 @@ function colorOf(tab) { } } function layerHoverInit(layer) { + layer.style.opacity = "0"; layer.onStateChange = (style) => { if (style.hover) { layer.style.opacity = "1.0"; @@ -727,15 +801,46 @@ function layerHoverInit(layer) { } }; } +function createHintLayer(hint, width, color) { + const hintLayer = document.createElement("div"); + hintLayer.style.position = "absolute"; + hintLayer.style.left = `${width}px`; + hintLayer.style.width = `max-content`; + hintLayer.innerHTML = hint; + hintLayer.style.fontSize = `${18}px`; + hintLayer.style.fontFamily = "d9, Arial, sans-serif"; + hintLayer.style.color = color.toRgbaString(); + hintLayer.style.fontWeight = "bold"; + hintLayer.style.textShadow = ` + 2px 2px 0 black, + 2px 0px 0 black, + 2px -2px 0 black, + 0px -2px 0 black, + -2px -2px 0 black, + -2px 0px 0 black, + -2px 2px 0 black, + 0px 2px 0 black + `; + hintLayer.style.pointerEvents = "none"; + hintLayer.style.opacity = "0"; + hintLayer.style.zIndex = "10"; + hintLayer.onStateChange = (style) => { + if (style.hover) { + hintLayer.style.opacity = "1.0"; + } else { + hintLayer.style.opacity = "0"; + } + }; + return hintLayer; +} function createElementEvent(obj, style) { style = { ...new IconStyle(), ...style }; - const evttype = obj.type; + const evttype = obj.type ?? EventType.ForwardEvent; let key0 = `event_${obj.type}`; if (!slices.has(key0)) { - console.warn(`Slice for event type ${evttype} not found, using Unknown.`); if (!slices.has("event_Unknown")) { return null; } @@ -759,9 +864,13 @@ function createElementEvent(obj, style) { const beatline = "event_beat_line"; const evtag = "event_tag"; const evbarea = "event_beat_area"; + const evbskip = "event_beat_skip"; const beatColor = new Color(4284539717); const element = document.createElement("div"); const internalLayers = []; + if (evttype === EventType.NewWindowDance) { + obj.tab = obj.customTab ?? Tab.Windows; + } function addLayers(layers) { for (const layer of layers) { if (layer) { @@ -811,19 +920,22 @@ function createElementEvent(obj, style) { const loop = obj.loops ?? 0; const subdiv = obj.subdivisions ?? 1; const hold = obj.hold ?? false; + const skip = obj.skipshot ?? false; const mode = obj.freezeBurnMode ?? null; const delay = obj.freezeBurnMode === "Freezeshot" ? obj.delay ?? 0 : 0; const subdivWidth = iconSize * (subdiv - 1) / subdiv * tick; const eventWidth = iconSize * (interval * loop + tick + delay); const off = interval - tick; const backLayers2 = createBackLayer(new Size(eventWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); - const holdWidth = iconSize * (interval - tick - delay); + const holdWidth = hold ? iconSize * (interval - tick - delay) : 0; const holdLayer = hold && holdWidth - subdivWidth > 0 ? createLayer(evbarea, new Rect(eventWidth + subdivWidth, 0, holdWidth - subdivWidth, iconSize), new Color(style.enabled ? 4291839731 : 4285493103), style) : null; const subdivLayer = subdiv > 1 ? createLayer(evbarea, new Rect(eventWidth, 0, subdivWidth, iconSize), new Color(style.enabled ? 4279480353 : 4285493103), style) : null; - const skipshotLayer = obj.skipshot ?? false ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * interval - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style) : null; + const skipshotLayer = skip ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * (interval - delay) - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style) : null; + const skipHitLayer = skip ? createLayer(evbskip, new Point(eventWidth + iconSize * (interval - delay) - 1, 0), null, style) : null; if (holdLayer) holdLayer.style.pointerEvents = "none"; if (subdivLayer) subdivLayer.style.pointerEvents = "none"; if (skipshotLayer) skipshotLayer.style.pointerEvents = "none"; + if (skipHitLayer) skipHitLayer.style.pointerEvents = "none"; const pulses = []; const crossLayers = []; const posx = -off * iconSize; @@ -853,6 +965,7 @@ function createElementEvent(obj, style) { } const loopLayer = createLayer("event_beat_loop", new Point(eventWidth, 0), null, style); loopLayer.style.opacity = "0"; + loopLayer.style.zIndex = "5"; loopLayer.onStateChange = (style2) => { if (style2.hover) { loopLayer.style.opacity = "1.0"; @@ -865,12 +978,33 @@ function createElementEvent(obj, style) { holdLayer, subdivLayer, skipshotLayer, + skipHitLayer, ...pulses, loopLayer, ...crossLayers ]); } break; + case EventType.AddFreeTimeBeat: + { + const hold = obj.hold ?? 0; + const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; + if (holdLayer) { + holdLayer.style.pointerEvents = "none"; + } + const backLayers2 = createBackLayer(new Size(info.bounds.width, iconSize), beatColor, style); + const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; + const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style, null); + textLayer.style.left = `${1.5 * style.scale}px`; + textLayer.style.top = `${10 * style.scale}px`; + addLayers([ + holdLayer, + ...backLayers2, + hitLayer, + textLayer + ]); + } + break; case EventType.Comment: { const backLayers2 = createBackLayer(info.bounds.size, new Color(obj.color ?? "7d7d7d"), style); @@ -881,38 +1015,16 @@ function createElementEvent(obj, style) { ]); } break; - case EventType.AddFreeTimeBeat: - { - const hold = obj.hold ?? 0; - const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; - if (holdLayer) { - holdLayer.style.pointerEvents = "none"; - } - const backLayers2 = createBackLayer(new Size(info.bounds.width, iconSize), beatColor, style); - const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; - const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style); - textLayer.style.left = `${1.5 * style.scale}px`; - textLayer.style.top = `${10 * style.scale}px`; - addLayers([ - holdLayer, - ...backLayers2, - hitLayer, - textLayer - ]); - } - break; case EventType.DesktopColor: { - const duration = obj.duration ?? 0; - const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height * 4), colorOf(obj.tab ?? evinfo.defaultTab), style); - const iconLayer = createLayer(`${key}_0`, new Point(0, info.bounds.height), null, style); - const iconColorLayer = createLayer(key, new Point(0, info.bounds.height), null, style); - const durationLayer = obj.duration > 1 ? createLayer(evbarea, new Rect(iconSize, 0, (duration - 1) * iconSize, info.bounds.height * 4), new Color(4283471790), style) : null; + const backLayers2 = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); + console.log(info.bounds.size); + const iconColorLayer = createLayer(`${key}_0`, new Point(0, iconSize), new Color(obj.endColor ?? "ffffff"), style); + const iconLayer = createLayer(`${key}_1`, new Point(0, iconSize), null, style); addLayers([ ...backLayers2, - durationLayer, - iconLayer, - iconColorLayer + iconColorLayer, + iconLayer ]); } break; @@ -940,7 +1052,7 @@ function createElementEvent(obj, style) { text = "x"; break; } - const textLayer = createRDFontLayer(text, style); + const textLayer = createRDFontLayer(text, style, null); textLayer.style.left = `${1.5 * style.scale}px`; textLayer.style.top = `${10 * style.scale}px`; addLayers([ @@ -974,41 +1086,315 @@ function createElementEvent(obj, style) { ]); } break; + case EventType.SayReadyGetSetGo: + { + const wordInfo = WordInfos[obj.phraseToSay ?? SayReadyGetSetGoWords.JustSayGo]; + const len = wordInfo.length * (obj.tick ?? 0) + 1; + const stringToJoin = wordInfo.phrase.split(" "); + const stringToDraw = [ + stringToJoin[0] + ]; + let lw = measureRDFontText(stringToJoin[0]); + const sw = measureRDFontText(" "); + const backLayers2 = createBackLayer(new Size(len * iconSize, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); + const wordLayers = []; + for (let i = 1; i < stringToJoin.length; i++) { + const part = stringToJoin[i]; + const w = measureRDFontText(part); + if (lw + sw + w > len * iconSize * style.scale) { + lw = w; + stringToDraw.push(part); + } else { + lw += sw + w; + stringToDraw[stringToDraw.length - 1] += " " + part; + } + } + const c = Math.min(stringToDraw.length, 3); + let top = iconSize / 2 - charHeight * c / 4 + 1; + for (let i = 0; i < c; i++) { + const line = stringToDraw[i]; + const p = new Point((len * iconSize - measureRDFontText(line) / 2) / 2, top + (i * charHeight + lineHeight) / 2); + const wordLayer = createRDFontLayer(line, { + ...style, + scale: style.scale / 2 + }, null); + wordLayer.style.left = `${p.x * style.scale}px`; + wordLayer.style.top = `${p.y * style.scale}px`; + wordLayers.push(wordLayer); + } + addLayers([ + ...backLayers2, + ...wordLayers + ]); + } + break; + case EventType.SetRowXs: + { + const syncoBeat = obj.syncoBeat ?? -1; + const width = info.bounds.width / 6; + const iconBounds = slices.get(beatx).bounds; + const s = width / iconBounds.width; + let left = 0; + const top = iconSize / 2 - iconBounds.height * s / 2; + const patternLayers = []; + const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style); + for (let p of obj.pattern) { + const beatxLayer = createLayer(p === "x" ? beatx : beatline, new Rect(left, top, width, iconBounds.height * s), null, style); + patternLayers.push(beatxLayer); + left += width; + } + const syncoBeatLayer = syncoBeat >= 0 ? createLayer(beatsynco, new Rect(width * syncoBeat, top, width, iconBounds.height * s), null, style) : null; + addLayers([ + ...backLayers2, + ...patternLayers, + syncoBeatLayer + ]); + } + break; + case EventType.ShowRooms: + { + const backLayers2 = createBackLayer(new Size(iconSize, iconSize * 4), colorOf(obj.tab ?? evinfo.defaultTab), style); + const roomLayers = []; + for (let i = 0; i < 4; i++) { + const roomLayer = createLayer(`${key}_${obj.rooms.indexOf(i) >= 0 ? "1" : "0"}`, new Point(0, i * iconSize * style.scale), null, { + ...style, + scale: style.scale / 2 + }); + roomLayers.push(roomLayer); + } + addLayers([ + ...backLayers2, + ...roomLayers + ]); + } + break; default: const backLayers = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); addLayers(backLayers); switch (evttype) { case EventType.CustomFlash: + const iconLayer = createLayer(key, null, null, style); + const startColorLayer = createLayer(`${key}_0`, null, new Color(obj.startColor ?? "000000").withAlpha((obj.startOpacity ?? 0) * 255), style); + const endColorLayer = createLayer(`${key}_1`, null, new Color(obj.endColor ?? "000000").withAlpha((obj.endOpacity ?? 0) * 255), style); addLayers([ - createLayer(`${key}_0`, null, new Color(obj.startColor ?? "000000"), style), - createLayer(`${key}_1`, null, new Color(obj.endColor ?? "000000"), style) + iconLayer, + startColorLayer, + endColorLayer ]); break; case EventType.FlipScreen: - const flip = (obj.flipX ? 1 : 0) | (obj.flipY ? 1 : 0); - if (flip === 0) { + { + const flip = (obj.flipX ? 1 : 0) | (obj.flipY ? 2 : 0); + const iconLayer2 = createLayer(flip === 0 ? `${key}_0` : `${key}_${flip - 1}`, null, null, style); addLayers([ - createLayer(key, null, null, style) - ]); - } else { - addLayers([ - createLayer(`${key}_${flip - 1}`, null, null, style) + iconLayer2 ]); } + break; + case EventType.FloatingText: + { + const backColorLayer = createLayer(`${key}_0`, null, Color.FromRgba(obj.color ?? "FFFFFFFF"), style); + const foreColorLayer = createLayer(`${key}_1`, null, Color.FromRgba(obj.outlineColor ?? "FFFFFFFF"), style); + addLayers([ + backColorLayer, + foreColorLayer + ]); + } + break; + case EventType.MoveRoom: + { + const degree = obj.angle ?? 0; + const radius = -degree * Math.PI / 180; + let width = (obj.scale ? obj.scale[0] ?? 0 : 100) / 100; + let height = (obj.scale ? obj.scale[1] ?? 0 : 100) / 100; + const pleft = (obj.pivot ? obj.pivot[0] ?? 0 : 50) / 100; + const ptop = (obj.pivot ? obj.pivot[1] ?? 0 : 50) / 100; + if (width === 0 || height === 0) break; + const uniform = Math.sqrt(width * width + height * height); + width /= uniform; + height /= uniform; + const roomLayer = createLayer(key, new Rect(iconSize / 2, iconSize / 2, iconSize * width, iconSize * height), null, style); + let pivotx = width * (1 - pleft * 2); + let pivoty = height * (1 - ptop * 2); + const widthrotated = pivotx * Math.cos(radius) + pivoty * Math.sin(radius); + const heightrotated = -pivotx * Math.sin(radius) + pivoty * Math.cos(radius); + const pointLayer = document.createElement("div"); + pointLayer.style.position = "absolute"; + pointLayer.style.width = `${style.scale}px`; + pointLayer.style.height = `${style.scale}px`; + pointLayer.style.left = `${iconSize * (1 - widthrotated) * style.scale / 2}px`; + pointLayer.style.top = `${iconSize * (1 + heightrotated) * style.scale / 2}px`; + pointLayer.style.backgroundColor = "#FF0000"; + roomLayer.style.transform = `translate(-50%, -50%) rotate(${-degree}deg)`; + addLayers([ + roomLayer, + pointLayer + ]); + } + break; + case EventType.PaintHands: + case EventType.Tint: + case EventType.TintRows: + { + const border = obj.border; + const backColorLayer = createLayer(key, null, Color.FromRgba(obj.tintColor ?? "FFFFFFFF"), style); + const foreColorLayer = border ? createLayer(border === "Outline" ? `${key}_0` : border === "Glow" ? `${key}_1` : "", null, Color.FromRgba(obj.borderColor ?? "FFFFFFFF"), style) : null; + addLayers([ + backColorLayer, + foreColorLayer + ]); + } + break; + case EventType.SetBackgroundColor: + { + const backType = obj.backgroundType ?? "Color"; + const iconLayer2 = createLayer(key, null, null, style); + const images = obj.image ?? []; + const imagePath = images.length > 0 ? images[0] : ""; + const contentInfo = slices.get(`${key}_1`); + const colorLayer = createLayer(`${key}_0`, null, Color.FromRgba((backType === "Color" ? obj.color : null) ?? "FFFFFF"), style); + const contentLayer = backType === "Image" ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : null; + if (backType === "Image" && contentLayer) { + contentLayer.style.backgroundImage = `url(${imagePath})`; + contentLayer.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; + contentLayer.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; + } + addLayers([ + iconLayer2, + colorLayer, + contentLayer + ]); + } + break; + case EventType.SetCrotchetsPerBar: + { + const cpb = obj.crotchetsPerBar ?? 0; + const iconLayer2 = createLayer(key, null, null, style); + const cpbLayer = createRDFontLayer(cpb > 9 ? "-" : cpb.toString(), style, Color.Black); + const bLayer = createRDFontLayer("4", style, Color.Black); + cpbLayer.style.left = `${2 * style.scale}px`; + cpbLayer.style.top = `${9 * style.scale}px`; + bLayer.style.left = `${8 * style.scale}px`; + bLayer.style.top = `${14 * style.scale}px`; + addLayers([ + iconLayer2, + cpbLayer, + bLayer + ]); + } + break; + case EventType.SetForeground: + { + const iconLayer2 = createLayer(key, null, null, style); + const images = obj.image ?? []; + const imagePath = images.length > 0 ? images[0] : ""; + const contentInfo = slices.get(`${key}_1`); + const colorLayer = imagePath ? createLayer(`${key}_0`, null, Color.Black, style) : null; + const contentLayer = imagePath ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : null; + if (contentLayer) { + contentLayer.style.backgroundImage = `url(${imagePath})`; + contentLayer.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; + contentLayer.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; + } + addLayers([ + iconLayer2, + colorLayer, + contentLayer + ]); + } + break; default: - const layer = document.createElement("div"); - layer.style.position = "absolute"; - layer.style.left = "0"; - layer.style.top = "0"; - layer.style.width = `${info.bounds.width * style.scale}px`; - layer.style.height = `${info.bounds.height * style.scale}px`; - layer.style.backgroundSize = `${info.bounds.width * style.scale}px ${info.bounds.height * style.scale}px`; - layer.style.backgroundImage = `url(${info.blobUrl})`; - element.appendChild(layer); + const layer = createLayer(key, null, null, style); + addLayers([ + layer + ]); break; } break; } + if (evinfo.isDurationEvent) { + const duration = obj[evinfo.durationKey] ?? 0; + const durWidth = iconSize * duration; + const durationLayer = durWidth > info.bounds.width ? createLayer(evbarea, new Rect(info.bounds.width, 0, durWidth - info.bounds.width, info.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style) : null; + if (durationLayer) { + durationLayer.style.pointerEvents = "none"; + layerHoverInit(durationLayer); + } + addLayers([ + durationLayer + ]); + } + const rooms = obj.rooms ?? []; + const roomEnabled = new Color(4292392977); + const roomDisabled = new Color(4284177243); + if (evinfo.isRoomEvent) { + const roomLayers = []; + for (let i = 0; i < 4; i++) { + const roomLayer = createLayer(`room_${i}`, new Point(iconSize, 0), rooms.indexOf(i) > -1 ? roomEnabled : roomDisabled, style); + if (roomLayer) { + layerHoverInit(roomLayer); + } + roomLayers.push(roomLayer); + } + const roomTopLayer = rooms.indexOf(4) > -1 ? createLayer(`room_top`, new Point(iconSize, 0), roomEnabled, style) : null; + if (roomTopLayer) { + layerHoverInit(roomTopLayer); + } + roomLayers.push(roomTopLayer); + addLayers(roomLayers); + } + const condition = obj.if ?? ""; + if (condition.length > 0) { + const positive = /(? { style2 = { ...style2 diff --git a/script/assets.png b/script/assets.png deleted file mode 100644 index e4d05383beeade28a733a02a4342c3c46f1dc9e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6653 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 Hu0mjfFf!)X diff --git a/script/rdview2.js b/script/rdview2.js deleted file mode 100644 index a3f2c52..0000000 --- a/script/rdview2.js +++ /dev/null @@ -1,143 +0,0 @@ -import { Extensions, IconStyle } from "/script/Extensions.js"; -function rend() { - const codeBlocks = document.querySelectorAll("canvas.rdview2-canvas"); - codeBlocks.forEach((block) => { - // 清理旧的实例 - if (block.cleanup) { - block.cleanup(); - } - - const width = block.getAttribute("data-width") || 8; - const height = block.getAttribute("data-height") || 4; - const scale = block.getAttribute("data-scale") || 2; - const data = block.getAttribute("data"); - const ctx = block.getContext("2d", { alpha: false, desynchronized: true }); - block.width = width * scale * 14; - block.height = height * scale * 14; - if (!data) { - return; - } - const jsonData = JSON.parse(`[${JSON.parse(data)}]`); - - let lastActive = false; - let evtId = 0; - let frameId = null; - let cachedRect = null; - let mdown = false; - - const eventPositions = jsonData.map(evt => ({ - evt, - x: ((evt.beat ?? 1) - 1) * scale * 14, - y: (evt.y ?? 0) * scale * 14 - })); - - const style = new IconStyle(); - style.Scale = scale; - - const updateRect = () => { - cachedRect = block.getBoundingClientRect(); - }; - updateRect(); - - let rectTimeout; - const debouncedUpdateRect = () => { - clearTimeout(rectTimeout); - rectTimeout = setTimeout(updateRect, 100); - }; - - const observer = new ResizeObserver(debouncedUpdateRect); - observer.observe(block); - - window.addEventListener("resize", debouncedUpdateRect, { passive: true }); - window.addEventListener("scroll", debouncedUpdateRect, { passive: true }); - - block.render = (x, y, active) => { - const point = { x, y }; - let currentEvtId = null; - for (let i = 0; i < eventPositions.length; i++) { - const { evt } = eventPositions[i]; - if (evt.area?.contains(point)) { - currentEvtId = i; - break; - } - } - - if (currentEvtId === evtId && active === lastActive) { - return; - } - evtId = currentEvtId; - lastActive = active; - - ctx.clearRect(0, 0, block.width, block.height); - - for (const { evt, x: posX, y: posY } of eventPositions) { - const isHovered = evt.area?.contains(point) ?? false; - style.Hover = isHovered; - style.Active = isHovered ? active : false; - evt.area = Extensions.DrawEventIcon(ctx, evt, { x: posX, y: posY }, style); - } - } - - const throttledRender = (x, y, active) => { - if (frameId !== null) { - return; - } - frameId = requestAnimationFrame(() => { - block.render(x, y, active); - frameId = null; - }); - } - - const getMousePos = (e) => ({ - x: e.clientX - cachedRect.left, - y: e.clientY - cachedRect.top - }); - - block.addEventListener("mousemove", (e) => { - const { x, y } = getMousePos(e); - console.log(x, y); - throttledRender(x, y, mdown); - }, { passive: true }); - - block.addEventListener("mousedown", (e) => { - const { x, y } = getMousePos(e); - mdown = true; - block.render(x, y, mdown); - }); - - block.addEventListener("mouseup", (e) => { - const { x, y } = getMousePos(e); - mdown = false; - block.render(x, y, mdown); - }); - - block.addEventListener("mouseleave", () => { - if (frameId !== null) { - cancelAnimationFrame(frameId); - frameId = null; - } - mdown = false; - evtId = null; - lastActive = false; - block.render(-1, -1, mdown); - }, { passive: true }); - - block.cleanup = () => { - observer.disconnect(); - window.removeEventListener("resize", debouncedUpdateRect); - window.removeEventListener("scroll", debouncedUpdateRect); - clearTimeout(rectTimeout); - if (frameId !== null) { - cancelAnimationFrame(frameId); - } - }; - - block.render(-1, -1, mdown); - }); -} - -window.$docsify.plugins = [].concat(window.$docsify.plugins, function (hook) { - hook.doneEach(function () { - rend(); - }); -}); diff --git a/script/special.js b/script/special.js index aeddffd..1bf3445 100644 --- a/script/special.js +++ b/script/special.js @@ -311,17 +311,10 @@ function rdview2() { number.innerHTML = lineDoms.join(""); } function initCanvas() { - // const lang = textarea.value.split('\n')[0] - // const code = textarea.value.split('\n').slice(1).join('\n') - // rdcanvas.innerHTML = RDViewRender(lang, code) - // try { - // JSON.parse(`[${textarea.value}]`); - // } catch (e) { - // rdcanvas.innerHTML = `
JSON解析错误:${e.message}
`; - // } let objs = []; try { objs = JSON.parse(`[${textarea.value}]`); + rdcanvas.innerHTML = ""; } catch (e) { rdcanvas.innerHTML = `
JSON解析错误:${e.message}
`; @@ -376,7 +369,6 @@ function rdview2() { } } } - //rdcanvas.innerHTML = RDView2Render(json); initCanvas(); initLineNumbers(); textarea.addEventListener("input", initLineNumbers); From 51e8b1f4496308bb96fa5dbebd1bea8a1edc2b97 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Thu, 15 Jan 2026 19:01:12 +0800 Subject: [PATCH 13/16] =?UTF-8?q?[RDView2]=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/appendix_tools.md | 34 +- pages/classicbeat.md | 2 +- script/{View.js => rdtkview.js} | 674 ++++++++++++++++++-------------- script/special.js | 90 +++-- 4 files changed, 437 insertions(+), 363 deletions(-) rename script/{View.js => rdtkview.js} (73%) diff --git a/pages/appendix_tools.md b/pages/appendix_tools.md index b9fe73d..f8fa85f 100644 --- a/pages/appendix_tools.md +++ b/pages/appendix_tools.md @@ -22,6 +22,8 @@ g 1 1 5 4 #0ff{ --- +完整功能支持请前往[此处](https://view.obugs.cn)。 +
diff --git a/pages/classicbeat.md b/pages/classicbeat.md index 40abb2c..2f7c987 100644 --- a/pages/classicbeat.md +++ b/pages/classicbeat.md @@ -10,7 +10,7 @@ 第二个选项“**摇摆**”就是剧情模式里老奶奶那样的摇摆普通拍子,可以使用拖动条来调节,对照下方绿色竖线的移动可以很直观地看到摇摆效果。不过拖动滑条你只能得到一些倍数十分规整的摇摆拍子,例如摇摆值为0.25,0.5,0.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 }, diff --git a/script/View.js b/script/rdtkview.js similarity index 73% rename from script/View.js rename to script/rdtkview.js index 52c6413..a5aea5e 100644 --- a/script/View.js +++ b/script/rdtkview.js @@ -1,4 +1,4 @@ -// AssetManager.ts +// assetManager.ts var Point = class _Point { x = 0; y = 0; @@ -266,12 +266,34 @@ var Color = class _Color { return new _Color(this.a, this.r, this.g, blue); } }; +var canvas = new OffscreenCanvas(1, 1); +var blobs = /* @__PURE__ */ new Map(); var SliceInfo = class { bounds = new Rect(); center = new Rect(); pivot = new Point(); scale = 1; - blobUrl = ""; + async blobUrl() { + const key = `${this.bounds.left},${this.bounds.top},${this.bounds.width},${this.bounds.height}`; + const blob = blobs.get(key); + if (blob) { + return blob; + } else { + canvas.width = this.bounds.width; + canvas.height = this.bounds.height; + const ctx = canvas.getContext("2d"); + if (ctx === null) { + throw new Error("Failed to get 2D context"); + } + ctx.clearRect(0, 0, this.bounds.width, this.bounds.height); + ctx.drawImage(assetFile, this.bounds.left, this.bounds.top, this.bounds.width, this.bounds.height, 0, 0, this.bounds.width, this.bounds.height); + const blob2 = await canvas.convertToBlob({ + type: "image/png" + }); + blobs.set(key, URL.createObjectURL(blob2)); + return blobs.get(key); + } + } get isNinePatch() { return !this.center.isEmpty; } @@ -289,7 +311,6 @@ async function loadAssetFile() { }); } async function readFromStream(stream) { - const canvas = new OffscreenCanvas(1, 1); let offset = 0; const count = stream.getUint8(0); offset += 1; @@ -333,18 +354,6 @@ async function readFromStream(stream) { } sliceInfo.pivot = new Point(pivotLeft, pivotTop); } - canvas.width = width; - canvas.height = height; - const ctx = canvas.getContext("2d"); - if (ctx === null) { - throw new Error("Failed to get 2D context"); - } - ctx.clearRect(0, 0, width, height); - ctx.drawImage(assetFile, sliceInfo.bounds.left, sliceInfo.bounds.top, width, height, 0, 0, width, height); - const blob = await canvas.convertToBlob({ - type: "image/png" - }); - sliceInfo.blobUrl = URL.createObjectURL(blob); sliceInfos.set(key, sliceInfo); } return sliceInfos; @@ -355,15 +364,15 @@ var slices = await readFromStream(new DataView(await (await fetch(directoryPath assetLoaded = true; }); -// Consts.ts +// consts.ts var Tab = /* @__PURE__ */ function(Tab2) { - Tab2["Sounds"] = "sounds"; - Tab2["Rows"] = "rows"; - Tab2["Actions"] = "actions"; - Tab2["Decorations"] = "decorations"; - Tab2["Rooms"] = "rooms"; - Tab2["Windows"] = "windows"; - Tab2["Unknown"] = "unknown"; + Tab2["Sounds"] = "Sounds"; + Tab2["Rows"] = "Rows"; + Tab2["Actions"] = "Actions"; + Tab2["Decorations"] = "Sprites"; + Tab2["Rooms"] = "Rooms"; + Tab2["Windows"] = "Windows"; + Tab2["Unknown"] = "Unknown"; return Tab2; }({}); var SayReadyGetSetGoWords = /* @__PURE__ */ function(SayReadyGetSetGoWords2) { @@ -478,9 +487,18 @@ var EventType = /* @__PURE__ */ function(EventType2) { EventType2["Tile"] = "Tile"; EventType2["Tint"] = "Tint"; EventType2["TintRows"] = "TintRows"; + EventType2["Unknown"] = "Unknown"; EventType2["WindowResize"] = "WindowResize"; return EventType2; }({}); +var hiddenEventType = [ + EventType.ForwardDecorationEvent, + EventType.ForwardEvent, + EventType.ForwardRowEvent, + EventType.MacroEvent, + EventType.SpinningRows, + EventType.ShowSubdivisionsRows +]; var EventAttriblte = /* @__PURE__ */ function(EventAttriblte2) { EventAttriblte2[EventAttriblte2["None"] = 0] = "None"; EventAttriblte2[EventAttriblte2["DurationEvent"] = 1] = "DurationEvent"; @@ -545,29 +563,29 @@ var EventInfos = { AddFreeTimeBeat: new EventInfo(Tab.Rows), AddOneshotBeat: new EventInfo(Tab.Rows), AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - BassDrop: new EventInfo(Tab.Actions), + BassDrop: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), Blend: new EventInfo(Tab.Decorations), CallCustomMethod: new EventInfo(Tab.Actions), ChangeCharacter: new EventInfo(Tab.Actions), ChangePlayersRows: new EventInfo(Tab.Actions), Comment: new EventInfo(Tab.Unknown), - CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), FinishLevel: new EventInfo(Tab.Actions), - Flash: new EventInfo(Tab.Actions), - FlipScreen: new EventInfo(Tab.Actions), + Flash: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + FlipScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), ForwardDecorationEvent: new EventInfo(Tab.Decorations), - ForwardEvent: new EventInfo(Tab.Unknown), + ForwardEvent: new EventInfo(Tab.Unknown, EventAttriblte.RoomEvent), ForwardRowEvent: new EventInfo(Tab.Rows), HideRow: new EventInfo(Tab.Actions), HideWindow: new EventInfo(Tab.Windows), - InvertColors: new EventInfo(Tab.Actions), + InvertColors: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), MacroEvent: new EventInfo(Tab.Unknown), MaskRoom: new EventInfo(Tab.Rooms), Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), - MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), NarrateRowInfo: new EventInfo(Tab.Sounds), @@ -577,15 +595,15 @@ var EventInfos = { PlayExpression: new EventInfo(Tab.Actions), PlaySong: new EventInfo(Tab.Sounds), PlaySound: new EventInfo(Tab.Sounds), - PulseCamera: new EventInfo(Tab.Actions), + PulseCamera: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), PulseFreeTimeBeat: new EventInfo(Tab.Rows), ReadNarration: new EventInfo(Tab.Sounds), RenameWindow: new EventInfo(Tab.Windows), ReorderRooms: new EventInfo(Tab.Rooms), - ReorderRow: new EventInfo(Tab.Rows), + ReorderRow: new EventInfo(Tab.Actions), ReorderSprite: new EventInfo(Tab.Decorations), ReorderWindows: new EventInfo(Tab.Windows), - SayReadyGetSetGo: new EventInfo(Tab.Sounds), + SayReadyGetSetGo: new EventInfo(Tab.Sounds, EventAttriblte.RoomEvent), SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetBeatSound: new EventInfo(Tab.Sounds), SetBeatsPerMinute: new EventInfo(Tab.Sounds), @@ -594,7 +612,7 @@ var EventInfos = { SetCrotchetsPerBar: new EventInfo(Tab.Sounds), SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetGameSound: new EventInfo(Tab.Sounds), - SetHandOwner: new EventInfo(Tab.Actions), + SetHandOwner: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), SetHeartExplodeInterval: new EventInfo(Tab.Sounds), SetHeartExplodeVolume: new EventInfo(Tab.Sounds), SetMainWindow: new EventInfo(Tab.Windows), @@ -610,22 +628,23 @@ var EventInfos = { SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), ShakeScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - ShowDialogue: new EventInfo(Tab.Actions), - ShowHands: new EventInfo(Tab.Actions), + ShowDialogue: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + ShowHands: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), ShowSubdivisionsRows: new EventInfo(Tab.Actions), SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - Stutter: new EventInfo(Tab.Actions), + Stutter: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), TagAction: new EventInfo(Tab.Actions), - TextExplosion: new EventInfo(Tab.Actions), + TextExplosion: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + Unknown: new EventInfo(Tab.Unknown), WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration") }; -// View.ts +// rdtkview.ts var lineHeight = 6; var charHeight = 8; var iconSize = 14; @@ -636,11 +655,37 @@ var IconStyle = class { scale = 1; showDuration = false; }; +var FilterData = class { + color; + hue = 0; + saturation = 1; + brightness = 1; + getFilter() { + let filter = ""; + if (this.color) { + filter += `url(#${getColorMatrixId(this.color)}) `; + } + if (this.hue !== 0) { + filter += `hue-rotate(${this.hue * 360}deg) `; + } + if (this.saturation !== 1) { + filter += `saturate(${this.saturation}) `; + } + if (this.brightness !== 1) { + filter += `brightness(${this.brightness}) `; + } + return filter.trim() || "none"; + } +}; function withState(color, active, enabled) { return (enabled ? color : new Color(4286874756)).withAlpha(active ? 192 : 91); } -function createLayer(key, bound, color, style) { +async function createLayer(key, bound, color, style) { const layer = document.createElement("div"); + layer.filterData = new FilterData(); + layer.updateFilter = () => { + layer.style.filter = layer.filterData.getFilter(); + }; const info = slices.get(key); layer.style.position = "absolute"; layer.style.boxSizing = "content-box"; @@ -652,7 +697,7 @@ function createLayer(key, bound, color, style) { layer.style.top = `${(bound?.top ?? bound?.y ?? 0) * style.scale}px`; layer.style.borderStyle = "solid"; layer.style.borderWidth = `${center.top * style.scale}px ${(info.bounds.width - center.right) * style.scale}px ${(info.bounds.height - center.bottom) * style.scale}px ${center.left * style.scale}px`; - layer.style.borderImageSource = `url(${info.blobUrl})`; + layer.style.borderImageSource = `url(${await info.blobUrl()})`; layer.style.borderImageSlice = `${center.top} ${info.bounds.width - center.right} ${info.bounds.height - center.bottom} ${center.left} fill`; layer.style.borderImageWidth = `1`; layer.style.borderImageOutset = `0`; @@ -666,7 +711,7 @@ function createLayer(key, bound, color, style) { layer.style.width = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px`; layer.style.height = `${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; if (info) { - layer.style.backgroundImage = `url(${info.blobUrl})`; + layer.style.backgroundImage = `url(${await info.blobUrl()})`; } layer.style.backgroundSize = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px ${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; } else { @@ -675,21 +720,20 @@ function createLayer(key, bound, color, style) { layer.style.width = `${(info?.bounds.width ?? 0) * style.scale}px`; layer.style.height = `${(info?.bounds.height ?? 0) * style.scale}px`; if (info) { - layer.style.backgroundImage = `url(${info.blobUrl})`; + layer.style.backgroundImage = `url(${await info.blobUrl()})`; } layer.style.backgroundSize = `${(info?.bounds.width ?? 0) * style.scale}px ${(info?.bounds.height ?? 0) * style.scale}px`; } } if (color && Color.White.equals(color) === false) { - const filterId = getColorMatrixId(color); - layer.style.filter = `url(#${filterId})`; layer.onColorChange = (color2) => { if (!color2) { return; } - const newFilterId = getColorMatrixId(color2); - layer.style.filter = `url(#${newFilterId})`; + layer.filterData.color = color2; + layer.updateFilter(); }; + layer.onColorChange(color); } else { } return layer; @@ -707,7 +751,7 @@ function getColorMatrixId(rgba) { const g = rgba.g / 255; const b = rgba.b / 255; const a = rgba.a / 255; - feColorMatrix.setAttribute("values", `${r} 0 0 0 0 0 ${g} 0 0 0 0 0 ${b} 0 0 0 0 0 ${a} 0`); + feColorMatrix.setAttribute("values", `${r * r} 0 0 0 0 0 ${g * g} 0 0 0 0 0 ${b * b} 0 0 0 0 0 ${a} 0`); const filter = document.createElementNS("http://www.w3.org/2000/svg", "filter"); filter.setAttribute("id", `filter_${rgba.toHexString()}`); filter.appendChild(feColorMatrix); @@ -734,10 +778,11 @@ function measureRDFontText(text) { } return len; } -function createRDFontLayer(text, style, color) { +async function createRDFontLayer(text, style, color) { const lineHead = new Point(0, -charHeight); const start = lineHead.clone(); const layer = document.createElement("div"); + const charLayers = []; layer.style.position = "absolute"; for (let i = 0; i < text.length; i++) { const char = text.charAt(i); @@ -749,25 +794,37 @@ function createRDFontLayer(text, style, color) { const charKey = `char_${charCode.toString(16).padStart(4, "0")}`; const charInfo = slices.get(charKey); if (charInfo) { - const charLayer = createLayer(charKey, new Point(start.x, start.y), color, style); + const charLayer = await createLayer(charKey, new Point(start.x, start.y), color, style); start.x += charInfo.bounds.width * style.scale; - layer.appendChild(charLayer); + charLayers.push(charLayer); } } } + layer.updateFilter = () => { + charLayers.forEach((cl) => { + cl.updateFilter(); + }); + }; + charLayers.forEach((cl) => { + layer.appendChild(cl); + }); return layer; } function createBackLayer(size, color, style) { const outline = "event_outline"; const back = "event_back"; - const backLayer = createLayer(back, new Rect(1, 1, (size?.width ?? iconSize) - 2, (size?.height ?? iconSize) - 2), withState(color, style.active, style.enabled), style); - const outlineLayer = createLayer(outline, size ? new Rect(size) : null, new Color(style.active ? 4294967295 : 4289243304), style); - if (backLayer.onColorChange) { - backLayer.onStateChange = (style2) => backLayer.onColorChange(withState(color, style2.active, style2.enabled)); - } - if (outlineLayer.onColorChange) { - outlineLayer.onStateChange = (style2) => outlineLayer.onColorChange(new Color(style2.active ? 4294967295 : 4289243304)); - } + const backLayer = createLayer(back, new Rect(1, 1, (size?.width ?? iconSize) - 2, (size?.height ?? iconSize) - 2), withState(color, style.active, style.enabled), style).then((layer) => { + if (layer.onColorChange) { + layer.onStateChange = (style2) => layer.onColorChange(withState(color, style2.active, style2.enabled)); + } + return layer; + }); + const outlineLayer = createLayer(outline, size ? new Rect(size) : null, new Color(style.active ? 4294967295 : 4289243304), style).then((layer) => { + if (layer.onColorChange) { + layer.onStateChange = (style2) => layer.onColorChange(new Color(style2.active ? 4294967295 : 4289243304)); + } + return layer; + }); return [ backLayer, outlineLayer @@ -833,26 +890,29 @@ function createHintLayer(hint, width, color) { }; return hintLayer; } -function createElementEvent(obj, style) { +async function createElementEvent(obj, style) { style = { ...new IconStyle(), ...style }; - const evttype = obj.type ?? EventType.ForwardEvent; let key0 = `event_${obj.type}`; + const hasType = EventType.hasOwnProperty(obj.type); + if (!hasType) { + console.warn(obj.type ? `Unknown event type: ${obj.type}` : `Event type missing`); + } if (!slices.has(key0)) { if (!slices.has("event_Unknown")) { return null; } key0 = "event_Unknown"; } - const info = slices.get(key0); - if (!info) { + const evttype = obj.type ?? EventType.Unknown; + const slcinfo = slices.get(key0) ?? slices.get("event_Unknown"); + if (!slcinfo) { console.warn(`Slice info for event type ${evttype} not found.`); return null; } - const evttypeEnum = EventType[evttype]; - const evinfo = EventInfos[evttypeEnum]; + const evinfo = EventInfos[evttype] ?? EventInfos[EventType.Unknown]; const key = "event_" + evttype; const pulse = "event_beat_pulse"; const hit = "event_beat_hit"; @@ -867,18 +927,10 @@ function createElementEvent(obj, style) { const evbskip = "event_beat_skip"; const beatColor = new Color(4284539717); const element = document.createElement("div"); - const internalLayers = []; - if (evttype === EventType.NewWindowDance) { - obj.tab = obj.customTab ?? Tab.Windows; - } - function addLayers(layers) { - for (const layer of layers) { - if (layer) { - element.appendChild(layer); - internalLayers.push(layer); - } - } - } + element.eventStyle = { + ...style + }; + const layersToAdd = []; element.style.imageRendering = "pixelated"; switch (evttype) { case EventType.AddClassicBeat: @@ -886,31 +938,30 @@ function createElementEvent(obj, style) { const tick = obj.tick ?? 1; const swing = (obj.swing ?? 0) || 1; const hold = obj.hold ?? 0; - const syncoSwing = obj.syncoSwing ?? 0; const prexs = obj.preXs ?? { syncoBeat: -1, syncoSwing: 0 }; const length = obj.length ?? 7; const iconWidth = iconSize * (tick * (length - 1 - prexs.syncoSwing)); - const holdBar = hold > 0 ? createLayer(evbarea, new Rect(iconWidth, 0, iconSize * hold, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; - if (holdBar) { - holdBar.style.pointerEvents = "none"; - } + const holdBar = hold > 0 ? createLayer(evbarea, new Rect(iconWidth, 0, iconSize * hold, iconSize), new Color(style.active ? 4291839731 : 4286462352), style).then((layer) => { + layer.style.pointerEvents = "none"; + return layer; + }) : null; const backLayers2 = createBackLayer(new Size(iconWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); const pulses = []; for (let i = 0; i < length - 1; i++) { - const pulseLayer = createLayer(pulse, new Point(iconSize * (tick * (i + i % 2 * (1 - swing) - (i <= prexs.syncoBeat ? 0 : prexs.syncoSwing))), 0), null, style); - layerHoverInit(pulseLayer); + const pulseLayer = createLayer(pulse, new Point(iconSize * (tick * (i + i % 2 * (1 - swing) - (i <= prexs.syncoBeat ? 0 : prexs.syncoSwing))), 0), null, style).then((layer) => { + layerHoverInit(layer); + return layer; + }); pulses.push(pulseLayer); } const hitLayer = createLayer(hit, new Point(iconSize * (tick * (length - 1 - (prexs.syncoSwing ?? 0))) - 1, 0), null, style); - addLayers([ - holdBar, - ...backLayers2, - ...pulses, - hitLayer - ]); + layersToAdd.push(holdBar); + layersToAdd.push(...backLayers2); + layersToAdd.push(...pulses); + layersToAdd.push(hitLayer); } break; case EventType.AddOneshotBeat: @@ -928,114 +979,119 @@ function createElementEvent(obj, style) { const off = interval - tick; const backLayers2 = createBackLayer(new Size(eventWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); const holdWidth = hold ? iconSize * (interval - tick - delay) : 0; - const holdLayer = hold && holdWidth - subdivWidth > 0 ? createLayer(evbarea, new Rect(eventWidth + subdivWidth, 0, holdWidth - subdivWidth, iconSize), new Color(style.enabled ? 4291839731 : 4285493103), style) : null; - const subdivLayer = subdiv > 1 ? createLayer(evbarea, new Rect(eventWidth, 0, subdivWidth, iconSize), new Color(style.enabled ? 4279480353 : 4285493103), style) : null; - const skipshotLayer = skip ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * (interval - delay) - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style) : null; - const skipHitLayer = skip ? createLayer(evbskip, new Point(eventWidth + iconSize * (interval - delay) - 1, 0), null, style) : null; - if (holdLayer) holdLayer.style.pointerEvents = "none"; - if (subdivLayer) subdivLayer.style.pointerEvents = "none"; - if (skipshotLayer) skipshotLayer.style.pointerEvents = "none"; - if (skipHitLayer) skipHitLayer.style.pointerEvents = "none"; + const holdLayer = hold && holdWidth - subdivWidth > 0 ? createLayer(evbarea, new Rect(eventWidth + subdivWidth, 0, holdWidth - subdivWidth, iconSize), new Color(style.enabled ? 4291839731 : 4285493103), style).then((layer) => { + layer.style.pointerEvents = "none"; + return layer; + }) : null; + const subdivLayer = subdiv > 1 ? createLayer(evbarea, new Rect(eventWidth, 0, subdivWidth, iconSize), new Color(style.enabled ? 4279480353 : 4285493103), style).then((layer) => { + layer.style.pointerEvents = "none"; + return layer; + }) : null; + const skipshotLayer = skip ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * (interval - delay) - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style).then((layer) => { + layer.style.pointerEvents = "none"; + return layer; + }) : null; + const skipHitLayer = skip ? createLayer(evbskip, new Point(eventWidth + iconSize * (interval - delay) - 1, 0), null, style).then((layer) => { + layer.style.pointerEvents = "none"; + return layer; + }) : null; const pulses = []; const crossLayers = []; const posx = -off * iconSize; - const hittype = mode === "Freezeshot" ? hitf : hitb; + const hittype = mode === "Freezeshot" ? hitf : mode === "Burnshot" ? hitb : null; for (let l = 0; l <= loop; l++) { for (let i = 0; i < subdiv; i++) { - const pulseLayer = createLayer(pulse, new Point(iconSize * (l * interval + i * tick / subdiv), 0), null, style); - layerHoverInit(pulseLayer); + const pulseLayer = createLayer(pulse, new Point(iconSize * (l * interval + i * tick / subdiv), 0), null, style).then((layer) => { + layerHoverInit(layer); + return layer; + }); pulses.push(pulseLayer); } for (let i = 0; i < subdiv; i++) { const hitLayer2 = createLayer(hit, new Point(iconSize * (l * interval + delay + tick + i * tick / subdiv) - 1, 0), null, style); pulses.push(hitLayer2); } - const crossLayer1 = mode || hold ? createLayer(beatcross, new Point(iconSize * l * interval + posx - 1, 0), null, style) : null; - const crossLayer2 = mode ? createLayer(beatcross, new Point(iconSize * (l - (mode === "Freezeshot" ? 0 : 1)) * interval - 1, 0), null, style) : null; - const hitLayer = createLayer(hittype, new Point(iconSize * (l * interval + tick) - 1, 0), null, style); - if (crossLayer1) { - layerHoverInit(crossLayer1); - crossLayers.push(crossLayer1); - } - if (crossLayer2) { - layerHoverInit(crossLayer2); - crossLayers.push(crossLayer2); - } + const crossLayer1 = mode || hold ? createLayer(beatcross, new Point(iconSize * l * interval + posx - 1, 0), null, style).then((layer) => { + layerHoverInit(layer); + return layer; + }) : null; + const crossLayer2 = mode ? createLayer(beatcross, new Point(iconSize * (l - (mode === "Freezeshot" ? 0 : 1)) * interval - 1, 0), null, style).then((layer) => { + layerHoverInit(layer); + return layer; + }) : null; + const hitLayer = hittype ? createLayer(hittype, new Point(iconSize * (l * interval + tick) - 1, 0), null, style) : null; + crossLayers.push(crossLayer1); + crossLayers.push(crossLayer2); pulses.push(hitLayer); } - const loopLayer = createLayer("event_beat_loop", new Point(eventWidth, 0), null, style); - loopLayer.style.opacity = "0"; - loopLayer.style.zIndex = "5"; - loopLayer.onStateChange = (style2) => { - if (style2.hover) { - loopLayer.style.opacity = "1.0"; - } else { - loopLayer.style.opacity = "0"; - } - }; - addLayers([ - ...backLayers2, - holdLayer, - subdivLayer, - skipshotLayer, - skipHitLayer, - ...pulses, - loopLayer, - ...crossLayers - ]); + const loopLayer = createLayer("event_beat_loop", new Point(eventWidth, 0), null, style).then((loopLayer2) => { + loopLayer2.style.opacity = "0"; + loopLayer2.style.zIndex = "5"; + loopLayer2.onStateChange = (style2) => { + if (style2.hover) { + loopLayer2.style.opacity = "1.0"; + } else { + loopLayer2.style.opacity = "0"; + } + }; + return loopLayer2; + }); + layersToAdd.push(...backLayers2); + layersToAdd.push(holdLayer); + layersToAdd.push(subdivLayer); + layersToAdd.push(skipshotLayer); + layersToAdd.push(skipHitLayer); + layersToAdd.push(...pulses); + layersToAdd.push(loopLayer); + layersToAdd.push(...crossLayers); } break; case EventType.AddFreeTimeBeat: { const hold = obj.hold ?? 0; - const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; - if (holdLayer) { - holdLayer.style.pointerEvents = "none"; - } - const backLayers2 = createBackLayer(new Size(info.bounds.width, iconSize), beatColor, style); + const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(slcinfo.bounds.width, 0, iconSize * hold - slcinfo.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style).then((layer) => { + layer.style.pointerEvents = "none"; + return layer; + }) : null; + const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, iconSize), beatColor, style); const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; - const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style, null); - textLayer.style.left = `${1.5 * style.scale}px`; - textLayer.style.top = `${10 * style.scale}px`; - addLayers([ - holdLayer, - ...backLayers2, - hitLayer, - textLayer - ]); + const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style, null).then((textLayer2) => { + textLayer2.style.left = `${1.5 * style.scale}px`; + textLayer2.style.top = `${10 * style.scale}px`; + return textLayer2; + }); + layersToAdd.push(holdLayer); + layersToAdd.push(...backLayers2); + layersToAdd.push(hitLayer); + layersToAdd.push(textLayer); } break; case EventType.Comment: { - const backLayers2 = createBackLayer(info.bounds.size, new Color(obj.color ?? "7d7d7d"), style); + const backLayers2 = createBackLayer(slcinfo.bounds.size, new Color(obj.color ?? "7d7d7d"), style); const iconLayer = createLayer(key, null, null, style); - addLayers([ - ...backLayers2, - iconLayer - ]); + layersToAdd.push(...backLayers2); + layersToAdd.push(iconLayer); } break; case EventType.DesktopColor: { - const backLayers2 = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); - console.log(info.bounds.size); + const backLayers2 = createBackLayer(slcinfo.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); const iconColorLayer = createLayer(`${key}_0`, new Point(0, iconSize), new Color(obj.endColor ?? "ffffff"), style); const iconLayer = createLayer(`${key}_1`, new Point(0, iconSize), null, style); - addLayers([ - ...backLayers2, - iconColorLayer, - iconLayer - ]); + layersToAdd.push(...backLayers2); + layersToAdd.push(iconColorLayer); + layersToAdd.push(iconLayer); } break; case EventType.PulseFreeTimeBeat: { const hold = obj.hold ?? 0; - const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, info.bounds.height), new Color(style.active ? 4291839731 : 4286462352), style) : null; - if (holdLayer) { - holdLayer.style.pointerEvents = "none"; - } - const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height), beatColor, style); + const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(slcinfo.bounds.width, 0, iconSize * hold - slcinfo.bounds.width, slcinfo.bounds.height), new Color(style.active ? 4291839731 : 4286462352), style).then((layer) => { + layer.style.pointerEvents = "none"; + return layer; + }) : null; + const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, slcinfo.bounds.height), beatColor, style); const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; let text = ""; switch (obj.action) { @@ -1052,21 +1108,21 @@ function createElementEvent(obj, style) { text = "x"; break; } - const textLayer = createRDFontLayer(text, style, null); - textLayer.style.left = `${1.5 * style.scale}px`; - textLayer.style.top = `${10 * style.scale}px`; - addLayers([ - holdLayer, - ...backLayers2, - hitLayer, - textLayer - ]); + const textLayer = createRDFontLayer(text, style, null).then((textLayer2) => { + textLayer2.style.left = `${1.5 * style.scale}px`; + textLayer2.style.top = `${10 * style.scale}px`; + return textLayer2; + }); + layersToAdd.push(holdLayer); + layersToAdd.push(...backLayers2); + layersToAdd.push(hitLayer); + layersToAdd.push(textLayer); } break; case EventType.ReorderRooms: case EventType.ReorderWindows: { - const backLayers2 = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); + const backLayers2 = createBackLayer(slcinfo.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); const orderLayers = []; const order = obj.order ?? [ 0, @@ -1080,10 +1136,8 @@ function createElementEvent(obj, style) { orderLayers.push(orderLayer); } } - addLayers([ - ...backLayers2, - ...orderLayers - ]); + layersToAdd.push(...backLayers2); + layersToAdd.push(...orderLayers); } break; case EventType.SayReadyGetSetGo: @@ -1117,38 +1171,36 @@ function createElementEvent(obj, style) { const wordLayer = createRDFontLayer(line, { ...style, scale: style.scale / 2 - }, null); - wordLayer.style.left = `${p.x * style.scale}px`; - wordLayer.style.top = `${p.y * style.scale}px`; + }, null).then((wordLayer2) => { + wordLayer2.style.left = `${p.x * style.scale}px`; + wordLayer2.style.top = `${p.y * style.scale}px`; + return wordLayer2; + }); wordLayers.push(wordLayer); } - addLayers([ - ...backLayers2, - ...wordLayers - ]); + layersToAdd.push(...backLayers2); + layersToAdd.push(...wordLayers); } break; case EventType.SetRowXs: { const syncoBeat = obj.syncoBeat ?? -1; - const width = info.bounds.width / 6; + const width = slcinfo.bounds.width / 6; const iconBounds = slices.get(beatx).bounds; const s = width / iconBounds.width; let left = 0; const top = iconSize / 2 - iconBounds.height * s / 2; const patternLayers = []; - const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style); - for (let p of obj.pattern) { + const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, slcinfo.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style); + for (let p of obj.pattern ?? "------") { const beatxLayer = createLayer(p === "x" ? beatx : beatline, new Rect(left, top, width, iconBounds.height * s), null, style); patternLayers.push(beatxLayer); left += width; } const syncoBeatLayer = syncoBeat >= 0 ? createLayer(beatsynco, new Rect(width * syncoBeat, top, width, iconBounds.height * s), null, style) : null; - addLayers([ - ...backLayers2, - ...patternLayers, - syncoBeatLayer - ]); + layersToAdd.push(...backLayers2); + layersToAdd.push(...patternLayers); + layersToAdd.push(syncoBeatLayer); } break; case EventType.ShowRooms: @@ -1156,49 +1208,41 @@ function createElementEvent(obj, style) { const backLayers2 = createBackLayer(new Size(iconSize, iconSize * 4), colorOf(obj.tab ?? evinfo.defaultTab), style); const roomLayers = []; for (let i = 0; i < 4; i++) { - const roomLayer = createLayer(`${key}_${obj.rooms.indexOf(i) >= 0 ? "1" : "0"}`, new Point(0, i * iconSize * style.scale), null, { + const roomLayer = createLayer(`${key}_${(obj.rooms ?? []).indexOf(i) >= 0 ? "1" : "0"}`, new Point(0, i * iconSize * style.scale), null, { ...style, scale: style.scale / 2 }); roomLayers.push(roomLayer); } - addLayers([ - ...backLayers2, - ...roomLayers - ]); + layersToAdd.push(...backLayers2); + layersToAdd.push(...roomLayers); } break; default: - const backLayers = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); - addLayers(backLayers); + const backLayers = createBackLayer(slcinfo.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); + layersToAdd.push(...backLayers); switch (evttype) { case EventType.CustomFlash: const iconLayer = createLayer(key, null, null, style); const startColorLayer = createLayer(`${key}_0`, null, new Color(obj.startColor ?? "000000").withAlpha((obj.startOpacity ?? 0) * 255), style); const endColorLayer = createLayer(`${key}_1`, null, new Color(obj.endColor ?? "000000").withAlpha((obj.endOpacity ?? 0) * 255), style); - addLayers([ - iconLayer, - startColorLayer, - endColorLayer - ]); + layersToAdd.push(iconLayer); + layersToAdd.push(startColorLayer); + layersToAdd.push(endColorLayer); break; case EventType.FlipScreen: { const flip = (obj.flipX ? 1 : 0) | (obj.flipY ? 2 : 0); const iconLayer2 = createLayer(flip === 0 ? `${key}_0` : `${key}_${flip - 1}`, null, null, style); - addLayers([ - iconLayer2 - ]); + layersToAdd.push(iconLayer2); } break; case EventType.FloatingText: { const backColorLayer = createLayer(`${key}_0`, null, Color.FromRgba(obj.color ?? "FFFFFFFF"), style); const foreColorLayer = createLayer(`${key}_1`, null, Color.FromRgba(obj.outlineColor ?? "FFFFFFFF"), style); - addLayers([ - backColorLayer, - foreColorLayer - ]); + layersToAdd.push(backColorLayer); + layersToAdd.push(foreColorLayer); } break; case EventType.MoveRoom: @@ -1213,7 +1257,10 @@ function createElementEvent(obj, style) { const uniform = Math.sqrt(width * width + height * height); width /= uniform; height /= uniform; - const roomLayer = createLayer(key, new Rect(iconSize / 2, iconSize / 2, iconSize * width, iconSize * height), null, style); + const roomLayer = createLayer(key, new Rect(iconSize / 2, iconSize / 2, iconSize * width, iconSize * height), null, style).then((roomLayer2) => { + roomLayer2.style.transform = `translate(-50%, -50%) rotate(${-degree}deg)`; + return roomLayer2; + }); let pivotx = width * (1 - pleft * 2); let pivoty = height * (1 - ptop * 2); const widthrotated = pivotx * Math.cos(radius) + pivoty * Math.sin(radius); @@ -1225,11 +1272,8 @@ function createElementEvent(obj, style) { pointLayer.style.left = `${iconSize * (1 - widthrotated) * style.scale / 2}px`; pointLayer.style.top = `${iconSize * (1 + heightrotated) * style.scale / 2}px`; pointLayer.style.backgroundColor = "#FF0000"; - roomLayer.style.transform = `translate(-50%, -50%) rotate(${-degree}deg)`; - addLayers([ - roomLayer, - pointLayer - ]); + layersToAdd.push(roomLayer); + layersToAdd.push(Promise.resolve(pointLayer)); } break; case EventType.PaintHands: @@ -1239,10 +1283,8 @@ function createElementEvent(obj, style) { const border = obj.border; const backColorLayer = createLayer(key, null, Color.FromRgba(obj.tintColor ?? "FFFFFFFF"), style); const foreColorLayer = border ? createLayer(border === "Outline" ? `${key}_0` : border === "Glow" ? `${key}_1` : "", null, Color.FromRgba(obj.borderColor ?? "FFFFFFFF"), style) : null; - addLayers([ - backColorLayer, - foreColorLayer - ]); + layersToAdd.push(backColorLayer); + layersToAdd.push(foreColorLayer); } break; case EventType.SetBackgroundColor: @@ -1253,34 +1295,36 @@ function createElementEvent(obj, style) { const imagePath = images.length > 0 ? images[0] : ""; const contentInfo = slices.get(`${key}_1`); const colorLayer = createLayer(`${key}_0`, null, Color.FromRgba((backType === "Color" ? obj.color : null) ?? "FFFFFF"), style); - const contentLayer = backType === "Image" ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : null; - if (backType === "Image" && contentLayer) { - contentLayer.style.backgroundImage = `url(${imagePath})`; - contentLayer.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; - contentLayer.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; - } - addLayers([ - iconLayer2, - colorLayer, - contentLayer - ]); + const contentLayer = backType === "Image" ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style).then((contentLayer2) => { + if (backType === "Image" && contentLayer2) { + contentLayer2.style.backgroundImage = `url(${imagePath})`; + contentLayer2.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; + contentLayer2.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; + } + return contentLayer2; + }) : null; + layersToAdd.push(iconLayer2); + layersToAdd.push(colorLayer); + layersToAdd.push(contentLayer); } break; case EventType.SetCrotchetsPerBar: { const cpb = obj.crotchetsPerBar ?? 0; const iconLayer2 = createLayer(key, null, null, style); - const cpbLayer = createRDFontLayer(cpb > 9 ? "-" : cpb.toString(), style, Color.Black); - const bLayer = createRDFontLayer("4", style, Color.Black); - cpbLayer.style.left = `${2 * style.scale}px`; - cpbLayer.style.top = `${9 * style.scale}px`; - bLayer.style.left = `${8 * style.scale}px`; - bLayer.style.top = `${14 * style.scale}px`; - addLayers([ - iconLayer2, - cpbLayer, - bLayer - ]); + const cpbLayer = createRDFontLayer(cpb > 9 ? "-" : cpb.toString(), style, Color.Black).then((cpbLayer2) => { + cpbLayer2.style.left = `${2 * style.scale}px`; + cpbLayer2.style.top = `${9 * style.scale}px`; + return cpbLayer2; + }); + const bLayer = createRDFontLayer("4", style, Color.Black).then((bLayer2) => { + bLayer2.style.left = `${8 * style.scale}px`; + bLayer2.style.top = `${14 * style.scale}px`; + return bLayer2; + }); + layersToAdd.push(iconLayer2); + layersToAdd.push(cpbLayer); + layersToAdd.push(bLayer); } break; case EventType.SetForeground: @@ -1290,24 +1334,22 @@ function createElementEvent(obj, style) { const imagePath = images.length > 0 ? images[0] : ""; const contentInfo = slices.get(`${key}_1`); const colorLayer = imagePath ? createLayer(`${key}_0`, null, Color.Black, style) : null; - const contentLayer = imagePath ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : null; - if (contentLayer) { - contentLayer.style.backgroundImage = `url(${imagePath})`; - contentLayer.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; - contentLayer.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; - } - addLayers([ - iconLayer2, - colorLayer, - contentLayer - ]); + const contentLayer = imagePath ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style).then((contentLayer2) => { + if (contentLayer2) { + contentLayer2.style.backgroundImage = `url(${imagePath})`; + contentLayer2.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; + contentLayer2.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; + } + return contentLayer2; + }) : null; + layersToAdd.push(iconLayer2); + layersToAdd.push(colorLayer); + layersToAdd.push(contentLayer); } break; default: - const layer = createLayer(key, null, null, style); - addLayers([ - layer - ]); + const layer = createLayer(hasType ? key : "event_Unknown", null, null, style); + layersToAdd.push(layer); break; } break; @@ -1315,14 +1357,12 @@ function createElementEvent(obj, style) { if (evinfo.isDurationEvent) { const duration = obj[evinfo.durationKey] ?? 0; const durWidth = iconSize * duration; - const durationLayer = durWidth > info.bounds.width ? createLayer(evbarea, new Rect(info.bounds.width, 0, durWidth - info.bounds.width, info.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style) : null; - if (durationLayer) { - durationLayer.style.pointerEvents = "none"; - layerHoverInit(durationLayer); - } - addLayers([ - durationLayer - ]); + const durationLayer = durWidth > slcinfo.bounds.width ? createLayer(evbarea, new Rect(slcinfo.bounds.width, 0, durWidth - slcinfo.bounds.width, slcinfo.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style).then((layer) => { + layer.style.pointerEvents = "none"; + layerHoverInit(layer); + return layer; + }) : null; + layersToAdd.push(durationLayer); } const rooms = obj.rooms ?? []; const roomEnabled = new Color(4292392977); @@ -1330,37 +1370,36 @@ function createElementEvent(obj, style) { if (evinfo.isRoomEvent) { const roomLayers = []; for (let i = 0; i < 4; i++) { - const roomLayer = createLayer(`room_${i}`, new Point(iconSize, 0), rooms.indexOf(i) > -1 ? roomEnabled : roomDisabled, style); - if (roomLayer) { - layerHoverInit(roomLayer); - } + const roomLayer = createLayer(`room_${i}`, new Point(iconSize, 0), rooms.indexOf(i) > -1 ? roomEnabled : roomDisabled, style).then((roomLayer2) => { + if (roomLayer2) { + layerHoverInit(roomLayer2); + } + return roomLayer2; + }); roomLayers.push(roomLayer); } - const roomTopLayer = rooms.indexOf(4) > -1 ? createLayer(`room_top`, new Point(iconSize, 0), roomEnabled, style) : null; - if (roomTopLayer) { - layerHoverInit(roomTopLayer); - } + const roomTopLayer = rooms.indexOf(4) > -1 ? createLayer(`room_top`, new Point(iconSize, 0), roomEnabled, style).then((roomTopLayer2) => { + if (roomTopLayer2) { + layerHoverInit(roomTopLayer2); + } + return roomTopLayer2; + }) : null; roomLayers.push(roomTopLayer); - addLayers(roomLayers); + layersToAdd.push(...roomLayers); } const condition = obj.if ?? ""; if (condition.length > 0) { const positive = /(? 0 ? `Error: Unknown type: ${obj.type}` : "Error: Type missing", slcinfo.bounds.width * style.scale, colorOf(obj.tab ?? evinfo.defaultTab)); + } + break; + } + if (hintLayer) { + layersToAdd.push(Promise.resolve(hintLayer)); + } + if (obj["$style"]) { + const hsb = obj["$style"].hsb ?? [ + 0, + 0, + 0 + ]; + if (hsb[0] !== 0 || hsb[1] !== 0 || hsb[2] !== 0) { + layersToAdd.forEach((layer) => layer?.then((layer2) => { + layer2.filterData.hue = hsb[0]; + layer2.filterData.saturation = hsb[1]; + layer2.filterData.brightness = hsb[2]; + })); + } + layersToAdd.forEach((layer) => layer?.then((layer2) => { + layer2.updateFilter(); + })); } element.onStateChange = (style2) => { style2 = { ...style2 }; - internalLayers.forEach((layer) => { - if (layer.onStateChange) { - layer.onStateChange(style2); + layersToAdd.forEach((layer) => layer?.then((layer2) => { + if (layer2.onStateChange) { + layer2.onStateChange(style2); } - }); + })); }; + element.moveTo = function(x, y) { + this.style.left = `${x}px`; + this.style.top = `${y}px`; + }; + for await (const layer of layersToAdd) { + if (layer) { + element.appendChild(layer); + } + } + element.eventData = obj; return element; } export { + IconStyle, + colorOf, createElementEvent }; diff --git a/script/special.js b/script/special.js index 1bf3445..536258a 100644 --- a/script/special.js +++ b/script/special.js @@ -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); + elemPromises.push(elem); + Promise.all(elemPromises).then((elems) => { + elems.forEach((elem) => { + rdcanvas.appendChild(elem); + }); }); - 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); - } } + rdcanvas.style.position = "relative"; + rdcanvas.style.height = `${maxy + 4 * 14 * eventStyle.scale}px`; } initCanvas(); initLineNumbers(); From 4e1e57b08eea09ed90a2d44d64bfc21bc549ae1c Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Fri, 16 Jan 2026 20:07:12 +0800 Subject: [PATCH 14/16] =?UTF-8?q?[RDView]=20=E7=8E=B0=E5=B7=B2=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=EF=BC=8C=E5=9C=A8=20pages/classicbeat=20=E5=8F=AF?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E7=AC=AC=E4=B8=80=E4=B8=AA=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 44 +- rdviewAssets/assets | Bin 0 -> 4326 bytes script/rdtkview.js | 1156 ++++++++++++++++++++----------------- script/rdtkview_render.js | 82 +++ script/special.js | 10 +- 5 files changed, 727 insertions(+), 565 deletions(-) create mode 100644 rdviewAssets/assets create mode 100644 script/rdtkview_render.js diff --git a/index.html b/index.html index 552e396..5461011 100644 --- a/index.html +++ b/index.html @@ -35,7 +35,8 @@ }; - + diff --git a/rdviewAssets/assets b/rdviewAssets/assets new file mode 100644 index 0000000000000000000000000000000000000000..2c1e294273840c8a547aecb8dd5761cf9caa2b25 GIT binary patch literal 4326 zcmZ`-&2Jk;6yK0Gq=C2v(w0&e)D}u{RM_>m`4CQ=E-fMu#ipq^u$tYS*h|(k%kDZ( z5waq2podh-v5Gi?$gQ{BH~}rE`~|&L0&(Ua;LYyX^U|c3Xn*g$dEam5#ecs{*C~sw z1sbizJZNyAhkxWU&!3EmZFvr7R>XVEjRy9EvFQ;l$EQHT?JoJE80AB<&2 z#E|oDbPrC>j7TnZct{f2dj}NsJ?4Ved!RsR?Xfk+`|KxBF)5T;;NmsUsee6@puFzQ z*LnI~5Z`|KZHVty`mKxa6&YnS@EG%0dl@Y4w)V$fNrP|Fc#(K)C2`@8?EaV(U#5(7 zsU&Ci$7T-a%F-WA?AHG~iev17rc>#W8=fom?17#$DRG(d(4}FjKe7q|cyu%?ADGW# z8A0_~EIr7Ld_HI^fC@{OC1Y8X$|~64!cmO84GtW|Fl;b?6hpVcxXf>(7sb45`XuUD z`W76JSy?1b$ghk3%Yt2*bd!gD61oXF1LSO)EJm|S@>Hs;<@wYE_(BTjeac)7u#89MtQmw}OshaYo60piWQ{hR zkW!Y0yazduv5xZG&%ptivCl~e!$863n{1U2Ali`y;-*ZPsx57Q>;#OW@ZB6S>%?z?bHfRy@h32oiDvr%SvZrB10c&W5`KUWF^qh|8URbC9#~&6 z8g+QQLe^;(rc(CNoa>rU!IsyhLgfSP(Jy-eGoNKOm#scJG$oVApm+`}zMoU92PY6g_LJD^84Win1%Ao5b0J2YfF zKpl1%?WaAyK$t@{FgKh%zD^sE$&d`7AEk~Y!jx))4%v(?x{+2af@W-?06VUItQc5+!>RThGj7STZNz*!l(D2x|*woj{YT%}*!fiMkGK*8EN z%^YIN`(qJW*90S~C6kef@A%XPD~c@K`J&Hg*iy!q;Gu~VKTXw);yla*w2DY^6^bmA zvj|lZZfW4lkVK+2LCQj6WinE!{*LnLCR?W=^gg`i(XPsxc!nU?InXA(G<`2fZ!F8$ zRf#h_=0%;)ptJlfup>vl(IKo&g|m<)QL_Q?q+9bOiWWj1Y=Jd7eGTIKX;&`NxWnB6 zuw+XK9dpd0mvwxo(9!;nn zFCMr5oO|xYbVL%`#wGh-?S#`Ip{472<5=(#G7&SF%~VpO?^QS}N&wONdazM-;Pu=5x>#SN9~f?LIieu&X(9qBCU+NP>X(U{m& z(H8SBU{pA@sVo$WGniL8hk4}-7*#G}$?6r1YO`39yoY&q5hJIDCEbs(*R+8pS8pIx z(zUxPqLOhOqx=*`g_9T+XYQ(KOQlyauY3Wc%B8z1gQe)N)`QZ~l7RkY>&Bu0hlZ52_u_!8!o&R|qNk0mQ_U|#i2jB4*} ztBx#_S?r7bE|zo(Skf(RtDKeT2Uv2oj!;F{?yHC@#&L}DQ}uzm-qG@PfANUdX2HM|0y?Ji5aiJ_|Rs z+{#AMtFW7WM<>Otj%`M3UNG}Ck%W}wydO4y#*)6rXb}`kH_+N-89T5F9ex<~Js?Zx z)O)#mq-=f<9wxa6nLda2jkU$XW9d8ah8@K)c7Y*{s^!4aO?WL2lMNH3UrTENd(2ZC zqoudNt7o%~l@I@_KanXtu!vg5%BR29pU8(&>|~Z+1rIR6sDf>ohvC*{={b;knrP%e za#?{BlbC;NT?d&pCco`yUc_xTF98 literal 0 HcmV?d00001 diff --git a/script/rdtkview.js b/script/rdtkview.js index a5aea5e..be302b6 100644 --- a/script/rdtkview.js +++ b/script/rdtkview.js @@ -1,4 +1,282 @@ -// assetManager.ts +// definition.ts +var Tab = /* @__PURE__ */ function(Tab2) { + Tab2["Sounds"] = "Sounds"; + Tab2["Rows"] = "Rows"; + Tab2["Actions"] = "Actions"; + Tab2["Decorations"] = "Sprites"; + Tab2["Rooms"] = "Rooms"; + Tab2["Windows"] = "Windows"; + Tab2["Unknown"] = "Unknown"; + return Tab2; +}(Tab || {}); +var SayReadyGetSetGoWords = /* @__PURE__ */ function(SayReadyGetSetGoWords2) { + SayReadyGetSetGoWords2["SayReaDyGetSetGoNew"] = "SayReaDyGetSetGoNew"; + SayReadyGetSetGoWords2["SayReaDyGetSetOne"] = "SayReaDyGetSetOne"; + SayReadyGetSetGoWords2["SayGetSetGo"] = "SayGetSetGo"; + SayReadyGetSetGoWords2["SayGetSetOne"] = "SayGetSetOne"; + SayReadyGetSetGoWords2["JustSayRea"] = "JustSayRea"; + SayReadyGetSetGoWords2["JustSayDy"] = "JustSayDy"; + SayReadyGetSetGoWords2["JustSayGet"] = "JustSayGet"; + SayReadyGetSetGoWords2["JustSaySet"] = "JustSaySet"; + SayReadyGetSetGoWords2["JustSayAnd"] = "JustSayAnd"; + SayReadyGetSetGoWords2["JustSayGo"] = "JustSayGo"; + SayReadyGetSetGoWords2["JustSayStop"] = "JustSayStop"; + SayReadyGetSetGoWords2["JustSayAndStop"] = "JustSayAndStop"; + SayReadyGetSetGoWords2["SaySwitch"] = "SaySwitch"; + SayReadyGetSetGoWords2["SayWatch"] = "SayWatch"; + SayReadyGetSetGoWords2["SayListen"] = "SayListen"; + SayReadyGetSetGoWords2["Count1"] = "Count1"; + SayReadyGetSetGoWords2["Count2"] = "Count2"; + SayReadyGetSetGoWords2["Count3"] = "Count3"; + SayReadyGetSetGoWords2["Count4"] = "Count4"; + SayReadyGetSetGoWords2["Count5"] = "Count5"; + SayReadyGetSetGoWords2["Count6"] = "Count6"; + SayReadyGetSetGoWords2["Count7"] = "Count7"; + SayReadyGetSetGoWords2["Count8"] = "Count8"; + SayReadyGetSetGoWords2["Count9"] = "Count9"; + SayReadyGetSetGoWords2["Count10"] = "Count10"; + SayReadyGetSetGoWords2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; + SayReadyGetSetGoWords2["JustSayReady"] = "JustSayReady"; + return SayReadyGetSetGoWords2; +}(SayReadyGetSetGoWords || {}); +var EventType = /* @__PURE__ */ function(EventType2) { + EventType2["AddClassicBeat"] = "AddClassicBeat"; + EventType2["AddFreeTimeBeat"] = "AddFreeTimeBeat"; + EventType2["AddOneshotBeat"] = "AddOneshotBeat"; + EventType2["AdvanceText"] = "AdvanceText"; + EventType2["BassDrop"] = "BassDrop"; + EventType2["Blend"] = "Blend"; + EventType2["CallCustomMethod"] = "CallCustomMethod"; + EventType2["ChangeCharacter"] = "ChangeCharacter"; + EventType2["ChangePlayersRows"] = "ChangePlayersRows"; + EventType2["Comment"] = "Comment"; + EventType2["CustomFlash"] = "CustomFlash"; + EventType2["DesktopColor"] = "DesktopColor"; + EventType2["FadeRoom"] = "FadeRoom"; + EventType2["FinishLevel"] = "FinishLevel"; + EventType2["Flash"] = "Flash"; + EventType2["FlipScreen"] = "FlipScreen"; + EventType2["FloatingText"] = "FloatingText"; + EventType2["ForwardDecorationEvent"] = "ForwardDecorationEvent"; + EventType2["ForwardEvent"] = "ForwardEvent"; + EventType2["ForwardRowEvent"] = "ForwardRowEvent"; + EventType2["HideRow"] = "HideRow"; + EventType2["HideWindow"] = "HideWindow"; + EventType2["InvertColors"] = "InvertColors"; + EventType2["MacroEvent"] = "MacroEvent"; + EventType2["MaskRoom"] = "MaskRoom"; + EventType2["Move"] = "Move"; + EventType2["MoveCamera"] = "MoveCamera"; + EventType2["MoveRoom"] = "MoveRoom"; + EventType2["MoveRow"] = "MoveRow"; + EventType2["NarrateRowInfo"] = "NarrateRowInfo"; + EventType2["NewWindowDance"] = "NewWindowDance"; + EventType2["PaintHands"] = "PaintHands"; + EventType2["PlayAnimation"] = "PlayAnimation"; + EventType2["PlayExpression"] = "PlayExpression"; + EventType2["PlaySong"] = "PlaySong"; + EventType2["PlaySound"] = "PlaySound"; + EventType2["PulseCamera"] = "PulseCamera"; + EventType2["PulseFreeTimeBeat"] = "PulseFreeTimeBeat"; + EventType2["ReadNarration"] = "ReadNarration"; + EventType2["RenameWindow"] = "RenameWindow"; + EventType2["ReorderRooms"] = "ReorderRooms"; + EventType2["ReorderRow"] = "ReorderRow"; + EventType2["ReorderSprite"] = "ReorderSprite"; + EventType2["ReorderWindows"] = "ReorderWindows"; + EventType2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; + EventType2["SetBackgroundColor"] = "SetBackgroundColor"; + EventType2["SetBeatSound"] = "SetBeatSound"; + EventType2["SetBeatsPerMinute"] = "SetBeatsPerMinute"; + EventType2["SetClapSounds"] = "SetClapSounds"; + EventType2["SetCountingSound"] = "SetCountingSound"; + EventType2["SetCrotchetsPerBar"] = "SetCrotchetsPerBar"; + EventType2["SetForeground"] = "SetForeground"; + EventType2["SetGameSound"] = "SetGameSound"; + EventType2["SetHandOwner"] = "SetHandOwner"; + EventType2["SetHeartExplodeInterval"] = "SetHeartExplodeInterval"; + EventType2["SetHeartExplodeVolume"] = "SetHeartExplodeVolume"; + EventType2["SetMainWindow"] = "SetMainWindow"; + EventType2["SetOneshotWave"] = "SetOneshotWave"; + EventType2["SetPlayStyle"] = "SetPlayStyle"; + EventType2["SetRoomContentMode"] = "SetRoomContentMode"; + EventType2["SetRoomPerspective"] = "SetRoomPerspective"; + EventType2["SetRowXs"] = "SetRowXs"; + EventType2["SetSpeed"] = "SetSpeed"; + EventType2["SetTheme"] = "SetTheme"; + EventType2["SetVFXPreset"] = "SetVFXPreset"; + EventType2["SetVisible"] = "SetVisible"; + EventType2["SetWindowContent"] = "SetWindowContent"; + EventType2["ShakeScreen"] = "ShakeScreen"; + EventType2["ShakeScreenCustom"] = "ShakeScreenCustom"; + EventType2["ShowDialogue"] = "ShowDialogue"; + EventType2["ShowHands"] = "ShowHands"; + EventType2["ShowRooms"] = "ShowRooms"; + EventType2["ShowStatusSign"] = "ShowStatusSign"; + EventType2["ShowSubdivisionsRows"] = "ShowSubdivisionsRows"; + EventType2["SpinningRows"] = "SpinningRows"; + EventType2["Stutter"] = "Stutter"; + EventType2["TagAction"] = "TagAction"; + EventType2["TextExplosion"] = "TextExplosion"; + EventType2["Tile"] = "Tile"; + EventType2["Tint"] = "Tint"; + EventType2["TintRows"] = "TintRows"; + EventType2["Unknown"] = "Unknown"; + EventType2["WindowResize"] = "WindowResize"; + return EventType2; +}(EventType || {}); +var hiddenEventType = [ + EventType.ForwardDecorationEvent, + EventType.ForwardEvent, + EventType.ForwardRowEvent, + EventType.MacroEvent, + EventType.SpinningRows, + EventType.ShowSubdivisionsRows +]; +var EventAttriblte = /* @__PURE__ */ function(EventAttriblte2) { + EventAttriblte2[EventAttriblte2["None"] = 0] = "None"; + EventAttriblte2[EventAttriblte2["DurationEvent"] = 1] = "DurationEvent"; + EventAttriblte2[EventAttriblte2["RoomEvent"] = 2] = "RoomEvent"; + return EventAttriblte2; +}(EventAttriblte || {}); +var EventInfo = class { + defaultTab; + durationKey = "duration"; + attr; + get isDurationEvent() { + return (this.attr & EventAttriblte.DurationEvent) !== 0; + } + get isRoomEvent() { + return (this.attr & EventAttriblte.RoomEvent) !== 0; + } + constructor(tab, enumAttriblte, durationKey) { + this.defaultTab = tab; + this.attr = enumAttriblte ?? EventAttriblte.None; + this.durationKey = durationKey ?? "duration"; + } +}; +var WordInfo = class { + phrase; + length; + constructor(phrase, length) { + this.phrase = phrase; + this.length = length; + } +}; +var WordInfos = { + SayReaDyGetSetGoNew: new WordInfo("Rea, Dy, Get, Set, Go!", 4), + SayReaDyGetSetOne: new WordInfo("Rea, Dy, Get, Set, One!", 4), + SayGetSetGo: new WordInfo("Get, Set, Go!", 2), + SayGetSetOne: new WordInfo("Get, Set, One!", 2), + JustSayRea: new WordInfo("Rea", 0), + JustSayDy: new WordInfo("Dy", 0), + JustSayGet: new WordInfo("Get", 0), + JustSaySet: new WordInfo("Set", 0), + JustSayAnd: new WordInfo("And", 0), + JustSayGo: new WordInfo("Go!", 0), + JustSayStop: new WordInfo("Stop", 0), + JustSayAndStop: new WordInfo("And Stop!", 0), + SaySwitch: new WordInfo("Switch", 0), + SayWatch: new WordInfo("Watch", 0), + SayListen: new WordInfo("Listen", 0), + Count1: new WordInfo("1", 0), + Count2: new WordInfo("2", 0), + Count3: new WordInfo("3", 0), + Count4: new WordInfo("4", 0), + Count5: new WordInfo("5", 0), + Count6: new WordInfo("6", 0), + Count7: new WordInfo("7", 0), + Count8: new WordInfo("8", 0), + Count9: new WordInfo("9", 0), + Count10: new WordInfo("10", 0), + SayReadyGetSetGo: new WordInfo("Ready, Get, Set, Go!", 4), + JustSayReady: new WordInfo("Ready", 0) +}; +var EventInfos = { + AddClassicBeat: new EventInfo(Tab.Rows), + AddFreeTimeBeat: new EventInfo(Tab.Rows), + AddOneshotBeat: new EventInfo(Tab.Rows), + AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + BassDrop: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + Blend: new EventInfo(Tab.Decorations), + CallCustomMethod: new EventInfo(Tab.Actions), + ChangeCharacter: new EventInfo(Tab.Actions), + ChangePlayersRows: new EventInfo(Tab.Actions), + Comment: new EventInfo(Tab.Unknown), + CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), + FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + FinishLevel: new EventInfo(Tab.Actions), + Flash: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + FlipScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + ForwardDecorationEvent: new EventInfo(Tab.Decorations), + ForwardEvent: new EventInfo(Tab.Unknown, EventAttriblte.RoomEvent), + ForwardRowEvent: new EventInfo(Tab.Rows), + HideRow: new EventInfo(Tab.Actions), + HideWindow: new EventInfo(Tab.Windows), + InvertColors: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + MacroEvent: new EventInfo(Tab.Unknown), + MaskRoom: new EventInfo(Tab.Rooms), + Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + NarrateRowInfo: new EventInfo(Tab.Sounds), + NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + PlayAnimation: new EventInfo(Tab.Decorations), + PlayExpression: new EventInfo(Tab.Actions), + PlaySong: new EventInfo(Tab.Sounds), + PlaySound: new EventInfo(Tab.Sounds), + PulseCamera: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + PulseFreeTimeBeat: new EventInfo(Tab.Rows), + ReadNarration: new EventInfo(Tab.Sounds), + RenameWindow: new EventInfo(Tab.Windows), + ReorderRooms: new EventInfo(Tab.Rooms), + ReorderRow: new EventInfo(Tab.Actions), + ReorderSprite: new EventInfo(Tab.Decorations), + ReorderWindows: new EventInfo(Tab.Windows), + SayReadyGetSetGo: new EventInfo(Tab.Sounds, EventAttriblte.RoomEvent), + SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + SetBeatSound: new EventInfo(Tab.Sounds), + SetBeatsPerMinute: new EventInfo(Tab.Sounds), + SetClapSounds: new EventInfo(Tab.Sounds), + SetCountingSound: new EventInfo(Tab.Sounds), + SetCrotchetsPerBar: new EventInfo(Tab.Sounds), + SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + SetGameSound: new EventInfo(Tab.Sounds), + SetHandOwner: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + SetHeartExplodeInterval: new EventInfo(Tab.Sounds), + SetHeartExplodeVolume: new EventInfo(Tab.Sounds), + SetMainWindow: new EventInfo(Tab.Windows), + SetOneshotWave: new EventInfo(Tab.Rows), + SetPlayStyle: new EventInfo(Tab.Actions), + SetRoomContentMode: new EventInfo(Tab.Rooms), + SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + SetRowXs: new EventInfo(Tab.Rows), + SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + SetVisible: new EventInfo(Tab.Decorations), + SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), + ShakeScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + ShowDialogue: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + ShowHands: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + ShowSubdivisionsRows: new EventInfo(Tab.Actions), + SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + Stutter: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + TagAction: new EventInfo(Tab.Actions), + TextExplosion: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + Unknown: new EventInfo(Tab.Unknown), + WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration") +}; var Point = class _Point { x = 0; y = 0; @@ -266,50 +544,22 @@ var Color = class _Color { return new _Color(this.a, this.r, this.g, blue); } }; -var canvas = new OffscreenCanvas(1, 1); -var blobs = /* @__PURE__ */ new Map(); var SliceInfo = class { bounds = new Rect(); center = new Rect(); pivot = new Point(); scale = 1; - async blobUrl() { - const key = `${this.bounds.left},${this.bounds.top},${this.bounds.width},${this.bounds.height}`; - const blob = blobs.get(key); - if (blob) { - return blob; - } else { - canvas.width = this.bounds.width; - canvas.height = this.bounds.height; - const ctx = canvas.getContext("2d"); - if (ctx === null) { - throw new Error("Failed to get 2D context"); - } - ctx.clearRect(0, 0, this.bounds.width, this.bounds.height); - ctx.drawImage(assetFile, this.bounds.left, this.bounds.top, this.bounds.width, this.bounds.height, 0, 0, this.bounds.width, this.bounds.height); - const blob2 = await canvas.convertToBlob({ - type: "image/png" - }); - blobs.set(key, URL.createObjectURL(blob2)); - return blobs.get(key); - } - } get isNinePatch() { return !this.center.isEmpty; } }; + +// assetManager.ts var assetFilePath = "assets.png"; var slicesFilePath = "assets.bin"; var directoryPath = "./rdviewAssets"; -async function loadAssetFile() { - const pngPath = directoryPath + "/" + assetFilePath; - return await new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = (e) => reject(new Error(`Failed to load asset file: ${pngPath}`)); - img.src = pngPath; - }); -} +var assetSize = new Size(210, 160); +var assetUrl = directoryPath + "/" + assetFilePath; async function readFromStream(stream) { let offset = 0; const count = stream.getUint8(0); @@ -359,291 +609,10 @@ async function readFromStream(stream) { return sliceInfos; } var assetLoaded = false; -var assetFile = await loadAssetFile(); var slices = await readFromStream(new DataView(await (await fetch(directoryPath + "/" + slicesFilePath)).arrayBuffer())).finally(() => { assetLoaded = true; }); -// consts.ts -var Tab = /* @__PURE__ */ function(Tab2) { - Tab2["Sounds"] = "Sounds"; - Tab2["Rows"] = "Rows"; - Tab2["Actions"] = "Actions"; - Tab2["Decorations"] = "Sprites"; - Tab2["Rooms"] = "Rooms"; - Tab2["Windows"] = "Windows"; - Tab2["Unknown"] = "Unknown"; - return Tab2; -}({}); -var SayReadyGetSetGoWords = /* @__PURE__ */ function(SayReadyGetSetGoWords2) { - SayReadyGetSetGoWords2["SayReaDyGetSetGoNew"] = "SayReaDyGetSetGoNew"; - SayReadyGetSetGoWords2["SayReaDyGetSetOne"] = "SayReaDyGetSetOne"; - SayReadyGetSetGoWords2["SayGetSetGo"] = "SayGetSetGo"; - SayReadyGetSetGoWords2["SayGetSetOne"] = "SayGetSetOne"; - SayReadyGetSetGoWords2["JustSayRea"] = "JustSayRea"; - SayReadyGetSetGoWords2["JustSayDy"] = "JustSayDy"; - SayReadyGetSetGoWords2["JustSayGet"] = "JustSayGet"; - SayReadyGetSetGoWords2["JustSaySet"] = "JustSaySet"; - SayReadyGetSetGoWords2["JustSayAnd"] = "JustSayAnd"; - SayReadyGetSetGoWords2["JustSayGo"] = "JustSayGo"; - SayReadyGetSetGoWords2["JustSayStop"] = "JustSayStop"; - SayReadyGetSetGoWords2["JustSayAndStop"] = "JustSayAndStop"; - SayReadyGetSetGoWords2["SaySwitch"] = "SaySwitch"; - SayReadyGetSetGoWords2["SayWatch"] = "SayWatch"; - SayReadyGetSetGoWords2["SayListen"] = "SayListen"; - SayReadyGetSetGoWords2["Count1"] = "Count1"; - SayReadyGetSetGoWords2["Count2"] = "Count2"; - SayReadyGetSetGoWords2["Count3"] = "Count3"; - SayReadyGetSetGoWords2["Count4"] = "Count4"; - SayReadyGetSetGoWords2["Count5"] = "Count5"; - SayReadyGetSetGoWords2["Count6"] = "Count6"; - SayReadyGetSetGoWords2["Count7"] = "Count7"; - SayReadyGetSetGoWords2["Count8"] = "Count8"; - SayReadyGetSetGoWords2["Count9"] = "Count9"; - SayReadyGetSetGoWords2["Count10"] = "Count10"; - SayReadyGetSetGoWords2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; - SayReadyGetSetGoWords2["JustSayReady"] = "JustSayReady"; - return SayReadyGetSetGoWords2; -}({}); -var EventType = /* @__PURE__ */ function(EventType2) { - EventType2["AddClassicBeat"] = "AddClassicBeat"; - EventType2["AddFreeTimeBeat"] = "AddFreeTimeBeat"; - EventType2["AddOneshotBeat"] = "AddOneshotBeat"; - EventType2["AdvanceText"] = "AdvanceText"; - EventType2["BassDrop"] = "BassDrop"; - EventType2["Blend"] = "Blend"; - EventType2["CallCustomMethod"] = "CallCustomMethod"; - EventType2["ChangeCharacter"] = "ChangeCharacter"; - EventType2["ChangePlayersRows"] = "ChangePlayersRows"; - EventType2["Comment"] = "Comment"; - EventType2["CustomFlash"] = "CustomFlash"; - EventType2["DesktopColor"] = "DesktopColor"; - EventType2["FadeRoom"] = "FadeRoom"; - EventType2["FinishLevel"] = "FinishLevel"; - EventType2["Flash"] = "Flash"; - EventType2["FlipScreen"] = "FlipScreen"; - EventType2["FloatingText"] = "FloatingText"; - EventType2["ForwardDecorationEvent"] = "ForwardDecorationEvent"; - EventType2["ForwardEvent"] = "ForwardEvent"; - EventType2["ForwardRowEvent"] = "ForwardRowEvent"; - EventType2["HideRow"] = "HideRow"; - EventType2["HideWindow"] = "HideWindow"; - EventType2["InvertColors"] = "InvertColors"; - EventType2["MacroEvent"] = "MacroEvent"; - EventType2["MaskRoom"] = "MaskRoom"; - EventType2["Move"] = "Move"; - EventType2["MoveCamera"] = "MoveCamera"; - EventType2["MoveRoom"] = "MoveRoom"; - EventType2["MoveRow"] = "MoveRow"; - EventType2["NarrateRowInfo"] = "NarrateRowInfo"; - EventType2["NewWindowDance"] = "NewWindowDance"; - EventType2["PaintHands"] = "PaintHands"; - EventType2["PlayAnimation"] = "PlayAnimation"; - EventType2["PlayExpression"] = "PlayExpression"; - EventType2["PlaySong"] = "PlaySong"; - EventType2["PlaySound"] = "PlaySound"; - EventType2["PulseCamera"] = "PulseCamera"; - EventType2["PulseFreeTimeBeat"] = "PulseFreeTimeBeat"; - EventType2["ReadNarration"] = "ReadNarration"; - EventType2["RenameWindow"] = "RenameWindow"; - EventType2["ReorderRooms"] = "ReorderRooms"; - EventType2["ReorderRow"] = "ReorderRow"; - EventType2["ReorderSprite"] = "ReorderSprite"; - EventType2["ReorderWindows"] = "ReorderWindows"; - EventType2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; - EventType2["SetBackgroundColor"] = "SetBackgroundColor"; - EventType2["SetBeatSound"] = "SetBeatSound"; - EventType2["SetBeatsPerMinute"] = "SetBeatsPerMinute"; - EventType2["SetClapSounds"] = "SetClapSounds"; - EventType2["SetCountingSound"] = "SetCountingSound"; - EventType2["SetCrotchetsPerBar"] = "SetCrotchetsPerBar"; - EventType2["SetForeground"] = "SetForeground"; - EventType2["SetGameSound"] = "SetGameSound"; - EventType2["SetHandOwner"] = "SetHandOwner"; - EventType2["SetHeartExplodeInterval"] = "SetHeartExplodeInterval"; - EventType2["SetHeartExplodeVolume"] = "SetHeartExplodeVolume"; - EventType2["SetMainWindow"] = "SetMainWindow"; - EventType2["SetOneshotWave"] = "SetOneshotWave"; - EventType2["SetPlayStyle"] = "SetPlayStyle"; - EventType2["SetRoomContentMode"] = "SetRoomContentMode"; - EventType2["SetRoomPerspective"] = "SetRoomPerspective"; - EventType2["SetRowXs"] = "SetRowXs"; - EventType2["SetSpeed"] = "SetSpeed"; - EventType2["SetTheme"] = "SetTheme"; - EventType2["SetVFXPreset"] = "SetVFXPreset"; - EventType2["SetVisible"] = "SetVisible"; - EventType2["SetWindowContent"] = "SetWindowContent"; - EventType2["ShakeScreen"] = "ShakeScreen"; - EventType2["ShakeScreenCustom"] = "ShakeScreenCustom"; - EventType2["ShowDialogue"] = "ShowDialogue"; - EventType2["ShowHands"] = "ShowHands"; - EventType2["ShowRooms"] = "ShowRooms"; - EventType2["ShowStatusSign"] = "ShowStatusSign"; - EventType2["ShowSubdivisionsRows"] = "ShowSubdivisionsRows"; - EventType2["SpinningRows"] = "SpinningRows"; - EventType2["Stutter"] = "Stutter"; - EventType2["TagAction"] = "TagAction"; - EventType2["TextExplosion"] = "TextExplosion"; - EventType2["Tile"] = "Tile"; - EventType2["Tint"] = "Tint"; - EventType2["TintRows"] = "TintRows"; - EventType2["Unknown"] = "Unknown"; - EventType2["WindowResize"] = "WindowResize"; - return EventType2; -}({}); -var hiddenEventType = [ - EventType.ForwardDecorationEvent, - EventType.ForwardEvent, - EventType.ForwardRowEvent, - EventType.MacroEvent, - EventType.SpinningRows, - EventType.ShowSubdivisionsRows -]; -var EventAttriblte = /* @__PURE__ */ function(EventAttriblte2) { - EventAttriblte2[EventAttriblte2["None"] = 0] = "None"; - EventAttriblte2[EventAttriblte2["DurationEvent"] = 1] = "DurationEvent"; - EventAttriblte2[EventAttriblte2["RoomEvent"] = 2] = "RoomEvent"; - return EventAttriblte2; -}({}); -var EventInfo = class { - defaultTab; - durationKey = "duration"; - attr; - get isDurationEvent() { - return (this.attr & EventAttriblte.DurationEvent) !== 0; - } - get isRoomEvent() { - return (this.attr & EventAttriblte.RoomEvent) !== 0; - } - constructor(tab, enumAttriblte, durationKey) { - this.defaultTab = tab; - this.attr = enumAttriblte ?? EventAttriblte.None; - this.durationKey = durationKey ?? "duration"; - } -}; -var WordInfo = class { - phrase; - length; - constructor(phrase, length) { - this.phrase = phrase; - this.length = length; - } -}; -var WordInfos = { - SayReaDyGetSetGoNew: new WordInfo("Rea, Dy, Get, Set, Go!", 4), - SayReaDyGetSetOne: new WordInfo("Rea, Dy, Get, Set, One!", 4), - SayGetSetGo: new WordInfo("Get, Set, Go!", 2), - SayGetSetOne: new WordInfo("Get, Set, One!", 2), - JustSayRea: new WordInfo("Rea", 0), - JustSayDy: new WordInfo("Dy", 0), - JustSayGet: new WordInfo("Get", 0), - JustSaySet: new WordInfo("Set", 0), - JustSayAnd: new WordInfo("And", 0), - JustSayGo: new WordInfo("Go!", 0), - JustSayStop: new WordInfo("Stop", 0), - JustSayAndStop: new WordInfo("And Stop!", 0), - SaySwitch: new WordInfo("Switch", 0), - SayWatch: new WordInfo("Watch", 0), - SayListen: new WordInfo("Listen", 0), - Count1: new WordInfo("1", 0), - Count2: new WordInfo("2", 0), - Count3: new WordInfo("3", 0), - Count4: new WordInfo("4", 0), - Count5: new WordInfo("5", 0), - Count6: new WordInfo("6", 0), - Count7: new WordInfo("7", 0), - Count8: new WordInfo("8", 0), - Count9: new WordInfo("9", 0), - Count10: new WordInfo("10", 0), - SayReadyGetSetGo: new WordInfo("Ready, Get, Set, Go!", 4), - JustSayReady: new WordInfo("Ready", 0) -}; -var EventInfos = { - AddClassicBeat: new EventInfo(Tab.Rows), - AddFreeTimeBeat: new EventInfo(Tab.Rows), - AddOneshotBeat: new EventInfo(Tab.Rows), - AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - BassDrop: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - Blend: new EventInfo(Tab.Decorations), - CallCustomMethod: new EventInfo(Tab.Actions), - ChangeCharacter: new EventInfo(Tab.Actions), - ChangePlayersRows: new EventInfo(Tab.Actions), - Comment: new EventInfo(Tab.Unknown), - CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), - FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), - FinishLevel: new EventInfo(Tab.Actions), - Flash: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - FlipScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - ForwardDecorationEvent: new EventInfo(Tab.Decorations), - ForwardEvent: new EventInfo(Tab.Unknown, EventAttriblte.RoomEvent), - ForwardRowEvent: new EventInfo(Tab.Rows), - HideRow: new EventInfo(Tab.Actions), - HideWindow: new EventInfo(Tab.Windows), - InvertColors: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - MacroEvent: new EventInfo(Tab.Unknown), - MaskRoom: new EventInfo(Tab.Rooms), - Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), - MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), - MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - NarrateRowInfo: new EventInfo(Tab.Sounds), - NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - PlayAnimation: new EventInfo(Tab.Decorations), - PlayExpression: new EventInfo(Tab.Actions), - PlaySong: new EventInfo(Tab.Sounds), - PlaySound: new EventInfo(Tab.Sounds), - PulseCamera: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - PulseFreeTimeBeat: new EventInfo(Tab.Rows), - ReadNarration: new EventInfo(Tab.Sounds), - RenameWindow: new EventInfo(Tab.Windows), - ReorderRooms: new EventInfo(Tab.Rooms), - ReorderRow: new EventInfo(Tab.Actions), - ReorderSprite: new EventInfo(Tab.Decorations), - ReorderWindows: new EventInfo(Tab.Windows), - SayReadyGetSetGo: new EventInfo(Tab.Sounds, EventAttriblte.RoomEvent), - SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - SetBeatSound: new EventInfo(Tab.Sounds), - SetBeatsPerMinute: new EventInfo(Tab.Sounds), - SetClapSounds: new EventInfo(Tab.Sounds), - SetCountingSound: new EventInfo(Tab.Sounds), - SetCrotchetsPerBar: new EventInfo(Tab.Sounds), - SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - SetGameSound: new EventInfo(Tab.Sounds), - SetHandOwner: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - SetHeartExplodeInterval: new EventInfo(Tab.Sounds), - SetHeartExplodeVolume: new EventInfo(Tab.Sounds), - SetMainWindow: new EventInfo(Tab.Windows), - SetOneshotWave: new EventInfo(Tab.Rows), - SetPlayStyle: new EventInfo(Tab.Actions), - SetRoomContentMode: new EventInfo(Tab.Rooms), - SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), - SetRowXs: new EventInfo(Tab.Rows), - SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - SetVisible: new EventInfo(Tab.Decorations), - SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), - ShakeScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - ShowDialogue: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - ShowHands: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), - ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - ShowSubdivisionsRows: new EventInfo(Tab.Actions), - SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), - Stutter: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - TagAction: new EventInfo(Tab.Actions), - TextExplosion: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), - Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), - Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), - TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), - Unknown: new EventInfo(Tab.Unknown), - WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration") -}; - // rdtkview.ts var lineHeight = 6; var charHeight = 8; @@ -680,63 +649,155 @@ var FilterData = class { function withState(color, active, enabled) { return (enabled ? color : new Color(4286874756)).withAlpha(active ? 192 : 91); } -async function createLayer(key, bound, color, style) { - const layer = document.createElement("div"); - layer.filterData = new FilterData(); - layer.updateFilter = () => { - layer.style.filter = layer.filterData.getFilter(); - }; +function createLayerFromBackground(key, bound, color, style, backgroundRepeat = false) { const info = slices.get(key); - layer.style.position = "absolute"; - layer.style.boxSizing = "content-box"; + if (!info) return []; if (info?.isNinePatch) { + const rectBound = bound ?? new Rect(0, 0, info.bounds.width, info.bounds.height); const center = info.center; - const width = bound?.width ?? info.bounds.width; - const height = bound?.height ?? info.bounds.height; - layer.style.left = `${(bound?.left ?? bound?.x ?? 0) * style.scale}px`; - layer.style.top = `${(bound?.top ?? bound?.y ?? 0) * style.scale}px`; - layer.style.borderStyle = "solid"; - layer.style.borderWidth = `${center.top * style.scale}px ${(info.bounds.width - center.right) * style.scale}px ${(info.bounds.height - center.bottom) * style.scale}px ${center.left * style.scale}px`; - layer.style.borderImageSource = `url(${await info.blobUrl()})`; - layer.style.borderImageSlice = `${center.top} ${info.bounds.width - center.right} ${info.bounds.height - center.bottom} ${center.left} fill`; - layer.style.borderImageWidth = `1`; - layer.style.borderImageOutset = `0`; - layer.style.borderImageRepeat = `repeat`; - layer.style.width = `${(width - center.left - (info.bounds.width - center.right)) * style.scale}px`; - layer.style.height = `${(height - center.top - (info.bounds.height - center.bottom)) * style.scale}px`; - } else { - if (bound instanceof Rect) { - layer.style.left = `${(bound.left - (info?.pivot.x ?? 0)) * style.scale}px`; - layer.style.top = `${(bound.top - (info?.pivot.y ?? 0)) * style.scale}px`; - layer.style.width = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px`; - layer.style.height = `${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; - if (info) { - layer.style.backgroundImage = `url(${await info.blobUrl()})`; + const left = rectBound.left; + const top = rectBound.top; + const width = rectBound.width; + const height = rectBound.height; + const infoLeft = info.bounds.left; + const infoTop = info.bounds.top; + const srcXs = [ + 0, + center.left, + center.right, + info.bounds.width + ]; + const srcYs = [ + 0, + center.top, + center.bottom, + info.bounds.height + ]; + const layers = []; + for (let y = 0; y < 3; y++) { + const srcTop = srcYs[y]; + const srcHeight = srcYs[y + 1] - srcYs[y]; + const dstTop = top + (y < 2 ? srcTop : height - (info.bounds.height - srcYs[y])); + const dstHeight = y === 1 ? height - center.top - (info.bounds.height - center.bottom) : srcHeight; + const heightScale = dstHeight / srcHeight; + for (let x = 0; x < 3; x++) { + const srcLeft = srcXs[x]; + const srcWidth = srcXs[x + 1] - srcXs[x]; + const dstLeft = left + (x < 2 ? srcLeft : width - (info.bounds.width - srcXs[x])); + const dstWidth = x === 1 ? width - center.left - (info.bounds.width - center.right) : srcWidth; + const widthScale = dstWidth / srcWidth; + if (backgroundRepeat && x === 1 && y === 1) { + for (let dstt = 0; dstt < dstHeight; dstt += srcHeight) { + const dsth = Math.min(srcHeight, dstHeight - dstt); + for (let dstl = 0; dstl < dstWidth; dstl += srcWidth) { + const dstw = Math.min(srcWidth, dstWidth - dstl); + const patchLayer = document.createElement("div"); + patchLayer.filterData = new FilterData(); + patchLayer.updateFilter = () => { + patchLayer.style.filter = patchLayer.filterData.getFilter(); + }; + patchLayer.style.position = "absolute"; + patchLayer.style.boxSizing = "content-box"; + patchLayer.style.backgroundClip = "content-box"; + patchLayer.style.backgroundImage = `url('${assetUrl}')`; + patchLayer.style.left = `${(dstLeft + dstl) * style.scale}px`; + patchLayer.style.top = `${(dstTop + dstt) * style.scale}px`; + patchLayer.style.width = `${dstw * style.scale}px`; + patchLayer.style.height = `${dsth * style.scale}px`; + patchLayer.style.backgroundPosition = `-${(infoLeft + srcLeft) * style.scale}px -${(infoTop + srcTop) * style.scale}px`; + patchLayer.style.backgroundSize = `${assetSize.width * style.scale}px ${assetSize.height * style.scale}px`; + layers.push(patchLayer); + } + } + } else { + const patchLayer = document.createElement("div"); + patchLayer.filterData = new FilterData(); + patchLayer.updateFilter = () => { + patchLayer.style.filter = patchLayer.filterData.getFilter(); + }; + patchLayer.style.position = "absolute"; + patchLayer.style.boxSizing = "content-box"; + patchLayer.style.backgroundClip = "content-box"; + patchLayer.style.backgroundImage = `url('${assetUrl}')`; + patchLayer.style.left = `${dstLeft * style.scale}px`; + patchLayer.style.top = `${dstTop * style.scale}px`; + patchLayer.style.width = `${dstWidth * style.scale}px`; + patchLayer.style.height = `${dstHeight * style.scale}px`; + patchLayer.style.backgroundPosition = `-${(infoLeft + srcLeft) * widthScale * style.scale}px -${(infoTop + srcTop) * heightScale * style.scale}px`; + patchLayer.style.backgroundSize = `${assetSize.width * widthScale * style.scale}px ${assetSize.height * heightScale * style.scale}px`; + layers.push(patchLayer); + } } - layer.style.backgroundSize = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px ${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; - } else { - layer.style.left = `${((bound?.x ?? 0) - (info?.pivot.x ?? 0)) * style.scale}px`; - layer.style.top = `${((bound?.y ?? 0) - (info?.pivot.y ?? 0)) * style.scale}px`; - layer.style.width = `${(info?.bounds.width ?? 0) * style.scale}px`; - layer.style.height = `${(info?.bounds.height ?? 0) * style.scale}px`; - if (info) { - layer.style.backgroundImage = `url(${await info.blobUrl()})`; - } - layer.style.backgroundSize = `${(info?.bounds.width ?? 0) * style.scale}px ${(info?.bounds.height ?? 0) * style.scale}px`; } - } - if (color && Color.White.equals(color) === false) { - layer.onColorChange = (color2) => { - if (!color2) { - return; - } - layer.filterData.color = color2; - layer.updateFilter(); - }; - layer.onColorChange(color); + if (color && Color.White.equals(color) === false) { + layers.forEach((layer) => { + layer.onColorChange = (color2) => { + if (!color2) { + return; + } + layer.filterData.color = color2; + layer.updateFilter(); + }; + layer.onColorChange(color); + }); + } else { + } + return layers; } else { + const pivotX = info.pivot.x ?? 0; + const pivotY = info.pivot.y ?? 0; + const layer = document.createElement("div"); + layer.filterData = new FilterData(); + layer.updateFilter = () => { + layer.style.filter = layer.filterData.getFilter(); + }; + layer.style.position = "absolute"; + layer.style.boxSizing = "content-box"; + layer.style.backgroundClip = "content-box"; + layer.style.backgroundImage = `url('${assetUrl}')`; + if (bound instanceof Rect) { + const left = bound.left; + const top = bound.top; + const width = bound.width; + const height = bound.height; + const infoLeft = info.bounds.left; + const infoTop = info.bounds.top; + layer.style.left = `${(left - pivotX) * style.scale}px`; + layer.style.top = `${(top - pivotY) * style.scale}px`; + layer.style.width = `${width * style.scale}px`; + layer.style.height = `${height * style.scale}px`; + layer.style.backgroundPosition = `-${infoLeft * style.scale}px -${infoTop * style.scale}px`; + layer.style.backgroundSize = `${assetSize.width * width * style.scale}px ${assetSize.height * height * style.scale}px`; + } else { + bound = bound ?? new Point(0, 0); + const left = bound.x; + const top = bound.y; + const width = info.bounds.width; + const height = info.bounds.height; + const infoLeft = info.bounds.left; + const infoTop = info.bounds.top; + layer.style.left = `${(left - pivotX) * style.scale}px`; + layer.style.top = `${(top - pivotY) * style.scale}px`; + layer.style.width = `${width * style.scale}px`; + layer.style.height = `${height * style.scale}px`; + layer.style.backgroundPosition = `-${infoLeft * style.scale}px -${infoTop * style.scale}px`; + layer.style.backgroundSize = `${assetSize.width * style.scale}px ${assetSize.height * style.scale}px`; + } + if (color && Color.White.equals(color) === false) { + layer.onColorChange = (color2) => { + if (!color2) { + return; + } + layer.filterData.color = color2; + layer.updateFilter(); + }; + layer.onColorChange(color); + } else { + } + return [ + layer + ]; } - return layer; } var colorMatrixIds = /* @__PURE__ */ new Map(); var colorMatrixCache = document.createElement("div"); @@ -778,7 +839,7 @@ function measureRDFontText(text) { } return len; } -async function createRDFontLayer(text, style, color) { +function createRDFontLayer(text, style, color) { const lineHead = new Point(0, -charHeight); const start = lineHead.clone(); const layer = document.createElement("div"); @@ -794,9 +855,9 @@ async function createRDFontLayer(text, style, color) { const charKey = `char_${charCode.toString(16).padStart(4, "0")}`; const charInfo = slices.get(charKey); if (charInfo) { - const charLayer = await createLayer(charKey, new Point(start.x, start.y), color, style); + const charLayer = createLayerFromBackground(charKey, new Point(start.x, start.y), color, style); start.x += charInfo.bounds.width * style.scale; - charLayers.push(charLayer); + charLayers.push(...charLayer); } } } @@ -813,21 +874,21 @@ async function createRDFontLayer(text, style, color) { function createBackLayer(size, color, style) { const outline = "event_outline"; const back = "event_back"; - const backLayer = createLayer(back, new Rect(1, 1, (size?.width ?? iconSize) - 2, (size?.height ?? iconSize) - 2), withState(color, style.active, style.enabled), style).then((layer) => { + const backLayer = createLayerFromBackground(back, new Rect(1, 1, (size?.width ?? iconSize) - 2, (size?.height ?? iconSize) - 2), withState(color, style.active, style.enabled), style); + backLayer.forEach((layer) => { if (layer.onColorChange) { layer.onStateChange = (style2) => layer.onColorChange(withState(color, style2.active, style2.enabled)); } - return layer; }); - const outlineLayer = createLayer(outline, size ? new Rect(size) : null, new Color(style.active ? 4294967295 : 4289243304), style).then((layer) => { + const outlineLayer = createLayerFromBackground(outline, size ? new Rect(size) : null, new Color(style.active ? 4294967295 : 4289243304), style); + outlineLayer.forEach((layer) => { if (layer.onColorChange) { layer.onStateChange = (style2) => layer.onColorChange(new Color(style2.active ? 4294967295 : 4289243304)); } - return layer; }); return [ - backLayer, - outlineLayer + ...backLayer, + ...outlineLayer ]; } function colorOf(tab) { @@ -890,7 +951,7 @@ function createHintLayer(hint, width, color) { }; return hintLayer; } -async function createElementEvent(obj, style) { +function createElementEvent(obj, style) { style = { ...new IconStyle(), ...style @@ -902,6 +963,7 @@ async function createElementEvent(obj, style) { } if (!slices.has(key0)) { if (!slices.has("event_Unknown")) { + console.log(slices); return null; } key0 = "event_Unknown"; @@ -926,6 +988,7 @@ async function createElementEvent(obj, style) { const evbarea = "event_beat_area"; const evbskip = "event_beat_skip"; const beatColor = new Color(4284539717); + let iconWidth = iconSize; const element = document.createElement("div"); element.eventStyle = { ...style @@ -943,25 +1006,27 @@ async function createElementEvent(obj, style) { syncoSwing: 0 }; const length = obj.length ?? 7; - const iconWidth = iconSize * (tick * (length - 1 - prexs.syncoSwing)); - const holdBar = hold > 0 ? createLayer(evbarea, new Rect(iconWidth, 0, iconSize * hold, iconSize), new Color(style.active ? 4291839731 : 4286462352), style).then((layer) => { + const iconWidth2 = iconSize * (tick * (length - 1 - prexs.syncoSwing)); + const holdBar = hold > 0 ? createLayerFromBackground(evbarea, new Rect(iconWidth2, 0, iconSize * hold, iconSize), new Color(style.active ? 4291839731 : 4286462352), style, true) : []; + holdBar.forEach((layer) => { layer.style.pointerEvents = "none"; return layer; - }) : null; - const backLayers2 = createBackLayer(new Size(iconWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); + }); + const backLayers2 = createBackLayer(new Size(iconWidth2, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); const pulses = []; for (let i = 0; i < length - 1; i++) { - const pulseLayer = createLayer(pulse, new Point(iconSize * (tick * (i + i % 2 * (1 - swing) - (i <= prexs.syncoBeat ? 0 : prexs.syncoSwing))), 0), null, style).then((layer) => { + const pulseLayer = createLayerFromBackground(pulse, new Point(iconSize * (tick * (i + i % 2 * (1 - swing) - (i <= prexs.syncoBeat ? 0 : prexs.syncoSwing))), 0), null, style); + pulseLayer.forEach((layer) => { layerHoverInit(layer); return layer; }); - pulses.push(pulseLayer); + pulses.push(...pulseLayer); } - const hitLayer = createLayer(hit, new Point(iconSize * (tick * (length - 1 - (prexs.syncoSwing ?? 0))) - 1, 0), null, style); - layersToAdd.push(holdBar); + const hitLayer = createLayerFromBackground(hit, new Point(iconSize * (tick * (length - 1 - (prexs.syncoSwing ?? 0))) - 1, 0), null, style); + layersToAdd.push(...holdBar); layersToAdd.push(...backLayers2); layersToAdd.push(...pulses); - layersToAdd.push(hitLayer); + layersToAdd.push(...hitLayer); } break; case EventType.AddOneshotBeat: @@ -979,52 +1044,60 @@ async function createElementEvent(obj, style) { const off = interval - tick; const backLayers2 = createBackLayer(new Size(eventWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); const holdWidth = hold ? iconSize * (interval - tick - delay) : 0; - const holdLayer = hold && holdWidth - subdivWidth > 0 ? createLayer(evbarea, new Rect(eventWidth + subdivWidth, 0, holdWidth - subdivWidth, iconSize), new Color(style.enabled ? 4291839731 : 4285493103), style).then((layer) => { + const holdLayer = hold && holdWidth - subdivWidth > 0 ? createLayerFromBackground(evbarea, new Rect(eventWidth + subdivWidth, 0, holdWidth - subdivWidth, iconSize), new Color(style.enabled ? 4291839731 : 4285493103), style, true) : []; + holdLayer.forEach((layer) => { layer.style.pointerEvents = "none"; return layer; - }) : null; - const subdivLayer = subdiv > 1 ? createLayer(evbarea, new Rect(eventWidth, 0, subdivWidth, iconSize), new Color(style.enabled ? 4279480353 : 4285493103), style).then((layer) => { + }); + const subdivLayer = subdiv > 1 ? createLayerFromBackground(evbarea, new Rect(eventWidth, 0, subdivWidth, iconSize), new Color(style.enabled ? 4279480353 : 4285493103), style, true) : []; + subdivLayer.forEach((layer) => { layer.style.pointerEvents = "none"; return layer; - }) : null; - const skipshotLayer = skip ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * (interval - delay) - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style).then((layer) => { + }); + const skipshotLayer = skip ? createLayerFromBackground(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * (interval - delay) - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style, true) : []; + skipshotLayer.forEach((layer) => { layer.style.pointerEvents = "none"; return layer; - }) : null; - const skipHitLayer = skip ? createLayer(evbskip, new Point(eventWidth + iconSize * (interval - delay) - 1, 0), null, style).then((layer) => { + }); + const skipHitLayer = skip ? createLayerFromBackground(evbskip, new Point(eventWidth + iconSize * (interval - delay) - 1, 0), null, style) : []; + skipHitLayer.forEach((layer) => { layer.style.pointerEvents = "none"; return layer; - }) : null; + }); const pulses = []; const crossLayers = []; const posx = -off * iconSize; const hittype = mode === "Freezeshot" ? hitf : mode === "Burnshot" ? hitb : null; for (let l = 0; l <= loop; l++) { for (let i = 0; i < subdiv; i++) { - const pulseLayer = createLayer(pulse, new Point(iconSize * (l * interval + i * tick / subdiv), 0), null, style).then((layer) => { + const pulseLayer = createLayerFromBackground(pulse, new Point(iconSize * (l * interval + i * tick / subdiv), 0), null, style); + pulseLayer.forEach((layer) => { layerHoverInit(layer); return layer; }); - pulses.push(pulseLayer); + pulses.push(...pulseLayer); } for (let i = 0; i < subdiv; i++) { - const hitLayer2 = createLayer(hit, new Point(iconSize * (l * interval + delay + tick + i * tick / subdiv) - 1, 0), null, style); - pulses.push(hitLayer2); + const hitLayer2 = createLayerFromBackground(hit, new Point(iconSize * (l * interval + delay + tick + i * tick / subdiv) - 1, 0), null, style); + pulses.push(...hitLayer2); } - const crossLayer1 = mode || hold ? createLayer(beatcross, new Point(iconSize * l * interval + posx - 1, 0), null, style).then((layer) => { + const crossLayer1 = mode || hold ? createLayerFromBackground(beatcross, new Point(iconSize * l * interval + posx - 1, 0), null, style) : []; + crossLayer1.forEach((layer) => { layerHoverInit(layer); return layer; - }) : null; - const crossLayer2 = mode ? createLayer(beatcross, new Point(iconSize * (l - (mode === "Freezeshot" ? 0 : 1)) * interval - 1, 0), null, style).then((layer) => { + }); + const crossLayer2 = mode ? createLayerFromBackground(beatcross, new Point(iconSize * (l - (mode === "Freezeshot" ? 0 : 1)) * interval - 1, 0), null, style) : []; + crossLayer2.forEach((layer) => { layerHoverInit(layer); return layer; - }) : null; - const hitLayer = hittype ? createLayer(hittype, new Point(iconSize * (l * interval + tick) - 1, 0), null, style) : null; - crossLayers.push(crossLayer1); - crossLayers.push(crossLayer2); - pulses.push(hitLayer); + }); + const hitLayer = hittype ? createLayerFromBackground(hittype, new Point(iconSize * (l * interval + tick) - 1, 0), null, style) : []; + crossLayers.push(...crossLayer1); + crossLayers.push(...crossLayer2); + pulses.push(...hitLayer); } - const loopLayer = createLayer("event_beat_loop", new Point(eventWidth, 0), null, style).then((loopLayer2) => { + const loopLayer = createLayerFromBackground("event_beat_loop", new Point(eventWidth, 0), null, style); + loopLayer.forEach((loopLayer2) => { loopLayer2.style.opacity = "0"; loopLayer2.style.zIndex = "5"; loopLayer2.onStateChange = (style2) => { @@ -1037,62 +1110,62 @@ async function createElementEvent(obj, style) { return loopLayer2; }); layersToAdd.push(...backLayers2); - layersToAdd.push(holdLayer); - layersToAdd.push(subdivLayer); - layersToAdd.push(skipshotLayer); - layersToAdd.push(skipHitLayer); + layersToAdd.push(...holdLayer); + layersToAdd.push(...subdivLayer); + layersToAdd.push(...skipshotLayer); + layersToAdd.push(...skipHitLayer); layersToAdd.push(...pulses); - layersToAdd.push(loopLayer); + layersToAdd.push(...loopLayer); layersToAdd.push(...crossLayers); } break; case EventType.AddFreeTimeBeat: { const hold = obj.hold ?? 0; - const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(slcinfo.bounds.width, 0, iconSize * hold - slcinfo.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style).then((layer) => { + const holdLayer = hold > 0 ? createLayerFromBackground(evbarea, new Rect(slcinfo.bounds.width, 0, iconSize * hold - slcinfo.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style, true) : []; + holdLayer.forEach((layer) => { layer.style.pointerEvents = "none"; return layer; - }) : null; - const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, iconSize), beatColor, style); - const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; - const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style, null).then((textLayer2) => { - textLayer2.style.left = `${1.5 * style.scale}px`; - textLayer2.style.top = `${10 * style.scale}px`; - return textLayer2; }); - layersToAdd.push(holdLayer); + const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, iconSize), beatColor, style); + const hitLayer = obj.pulse === 6 ? createLayerFromBackground(hit, new Point(0, 0), null, style) : []; + const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style, null); + textLayer.style.left = `${1.5 * style.scale}px`; + textLayer.style.top = `${10 * style.scale}px`; + layersToAdd.push(...holdLayer); layersToAdd.push(...backLayers2); - layersToAdd.push(hitLayer); + layersToAdd.push(...hitLayer); layersToAdd.push(textLayer); } break; case EventType.Comment: { const backLayers2 = createBackLayer(slcinfo.bounds.size, new Color(obj.color ?? "7d7d7d"), style); - const iconLayer = createLayer(key, null, null, style); + const iconLayer = createLayerFromBackground(key, null, null, style); layersToAdd.push(...backLayers2); - layersToAdd.push(iconLayer); + layersToAdd.push(...iconLayer); } break; case EventType.DesktopColor: { const backLayers2 = createBackLayer(slcinfo.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); - const iconColorLayer = createLayer(`${key}_0`, new Point(0, iconSize), new Color(obj.endColor ?? "ffffff"), style); - const iconLayer = createLayer(`${key}_1`, new Point(0, iconSize), null, style); + const iconColorLayer = createLayerFromBackground(`${key}_0`, new Point(0, iconSize), new Color(obj.endColor ?? "ffffff"), style); + const iconLayer = createLayerFromBackground(`${key}_1`, new Point(0, iconSize), null, style); layersToAdd.push(...backLayers2); - layersToAdd.push(iconColorLayer); - layersToAdd.push(iconLayer); + layersToAdd.push(...iconColorLayer); + layersToAdd.push(...iconLayer); } break; case EventType.PulseFreeTimeBeat: { const hold = obj.hold ?? 0; - const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(slcinfo.bounds.width, 0, iconSize * hold - slcinfo.bounds.width, slcinfo.bounds.height), new Color(style.active ? 4291839731 : 4286462352), style).then((layer) => { + const holdLayer = hold > 0 ? createLayerFromBackground(evbarea, new Rect(slcinfo.bounds.width, 0, iconSize * hold - slcinfo.bounds.width, slcinfo.bounds.height), new Color(style.active ? 4291839731 : 4286462352), style, true) : []; + holdLayer.forEach((layer) => { layer.style.pointerEvents = "none"; return layer; - }) : null; + }); const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, slcinfo.bounds.height), beatColor, style); - const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; + const hitLayer = obj.pulse === 6 ? createLayerFromBackground(hit, new Point(0, 0), null, style) : []; let text = ""; switch (obj.action) { case "Custom": @@ -1108,14 +1181,12 @@ async function createElementEvent(obj, style) { text = "x"; break; } - const textLayer = createRDFontLayer(text, style, null).then((textLayer2) => { - textLayer2.style.left = `${1.5 * style.scale}px`; - textLayer2.style.top = `${10 * style.scale}px`; - return textLayer2; - }); - layersToAdd.push(holdLayer); + const textLayer = createRDFontLayer(text, style, null); + textLayer.style.left = `${1.5 * style.scale}px`; + textLayer.style.top = `${10 * style.scale}px`; + layersToAdd.push(...holdLayer); layersToAdd.push(...backLayers2); - layersToAdd.push(hitLayer); + layersToAdd.push(...hitLayer); layersToAdd.push(textLayer); } break; @@ -1132,8 +1203,8 @@ async function createElementEvent(obj, style) { ]; for (let i = 0; i < order.length; i++) { { - const orderLayer = createLayer(`${key}_${order[i]}`, new Point(0, i * iconSize), null, style); - orderLayers.push(orderLayer); + const orderLayer = createLayerFromBackground(`${key}_${order[i]}`, new Point(0, i * iconSize), null, style); + orderLayers.push(...orderLayer); } } layersToAdd.push(...backLayers2); @@ -1144,6 +1215,7 @@ async function createElementEvent(obj, style) { { const wordInfo = WordInfos[obj.phraseToSay ?? SayReadyGetSetGoWords.JustSayGo]; const len = wordInfo.length * (obj.tick ?? 0) + 1; + iconWidth = len * iconSize; const stringToJoin = wordInfo.phrase.split(" "); const stringToDraw = [ stringToJoin[0] @@ -1171,11 +1243,9 @@ async function createElementEvent(obj, style) { const wordLayer = createRDFontLayer(line, { ...style, scale: style.scale / 2 - }, null).then((wordLayer2) => { - wordLayer2.style.left = `${p.x * style.scale}px`; - wordLayer2.style.top = `${p.y * style.scale}px`; - return wordLayer2; - }); + }, null); + wordLayer.style.left = `${p.x * style.scale}px`; + wordLayer.style.top = `${p.y * style.scale}px`; wordLayers.push(wordLayer); } layersToAdd.push(...backLayers2); @@ -1193,14 +1263,14 @@ async function createElementEvent(obj, style) { const patternLayers = []; const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, slcinfo.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style); for (let p of obj.pattern ?? "------") { - const beatxLayer = createLayer(p === "x" ? beatx : beatline, new Rect(left, top, width, iconBounds.height * s), null, style); - patternLayers.push(beatxLayer); + const beatxLayer = createLayerFromBackground(p === "x" ? beatx : beatline, new Rect(left, top, width, iconBounds.height * s), null, style); + patternLayers.push(...beatxLayer); left += width; } - const syncoBeatLayer = syncoBeat >= 0 ? createLayer(beatsynco, new Rect(width * syncoBeat, top, width, iconBounds.height * s), null, style) : null; + const syncoBeatLayer = syncoBeat >= 0 ? createLayerFromBackground(beatsynco, new Rect(width * syncoBeat, top, width, iconBounds.height * s), null, style) : []; layersToAdd.push(...backLayers2); layersToAdd.push(...patternLayers); - layersToAdd.push(syncoBeatLayer); + layersToAdd.push(...syncoBeatLayer); } break; case EventType.ShowRooms: @@ -1208,11 +1278,11 @@ async function createElementEvent(obj, style) { const backLayers2 = createBackLayer(new Size(iconSize, iconSize * 4), colorOf(obj.tab ?? evinfo.defaultTab), style); const roomLayers = []; for (let i = 0; i < 4; i++) { - const roomLayer = createLayer(`${key}_${(obj.rooms ?? []).indexOf(i) >= 0 ? "1" : "0"}`, new Point(0, i * iconSize * style.scale), null, { + const roomLayer = createLayerFromBackground(`${key}_${(obj.rooms ?? []).indexOf(i) >= 0 ? "1" : "0"}`, new Point(0, i * iconSize * style.scale), null, { ...style, scale: style.scale / 2 }); - roomLayers.push(roomLayer); + roomLayers.push(...roomLayer); } layersToAdd.push(...backLayers2); layersToAdd.push(...roomLayers); @@ -1223,30 +1293,39 @@ async function createElementEvent(obj, style) { layersToAdd.push(...backLayers); switch (evttype) { case EventType.CustomFlash: - const iconLayer = createLayer(key, null, null, style); - const startColorLayer = createLayer(`${key}_0`, null, new Color(obj.startColor ?? "000000").withAlpha((obj.startOpacity ?? 0) * 255), style); - const endColorLayer = createLayer(`${key}_1`, null, new Color(obj.endColor ?? "000000").withAlpha((obj.endOpacity ?? 0) * 255), style); - layersToAdd.push(iconLayer); - layersToAdd.push(startColorLayer); - layersToAdd.push(endColorLayer); + const iconLayer = createLayerFromBackground(key, null, null, style); + const startColorLayer = createLayerFromBackground(`${key}_0`, null, new Color(obj.startColor ?? "000000").withAlpha((obj.startOpacity ?? 0) * 255), style); + const endColorLayer = createLayerFromBackground(`${key}_1`, null, new Color(obj.endColor ?? "000000").withAlpha((obj.endOpacity ?? 0) * 255), style); + layersToAdd.push(...iconLayer); + layersToAdd.push(...startColorLayer); + layersToAdd.push(...endColorLayer); break; case EventType.FlipScreen: { const flip = (obj.flipX ? 1 : 0) | (obj.flipY ? 2 : 0); - const iconLayer2 = createLayer(flip === 0 ? `${key}_0` : `${key}_${flip - 1}`, null, null, style); - layersToAdd.push(iconLayer2); + const iconLayer2 = createLayerFromBackground(flip === 0 ? `${key}_0` : `${key}_${flip - 1}`, null, null, style); + layersToAdd.push(...iconLayer2); } break; case EventType.FloatingText: { - const backColorLayer = createLayer(`${key}_0`, null, Color.FromRgba(obj.color ?? "FFFFFFFF"), style); - const foreColorLayer = createLayer(`${key}_1`, null, Color.FromRgba(obj.outlineColor ?? "FFFFFFFF"), style); - layersToAdd.push(backColorLayer); - layersToAdd.push(foreColorLayer); + const backColorLayer = createLayerFromBackground(`${key}_0`, null, Color.FromRgba(obj.color ?? "FFFFFFFF"), style); + const foreColorLayer = createLayerFromBackground(`${key}_1`, null, Color.FromRgba(obj.outlineColor ?? "FFFFFFFF"), style); + layersToAdd.push(...backColorLayer); + layersToAdd.push(...foreColorLayer); } break; case EventType.MoveRoom: { + obj.scale ??= [ + null, + null + ]; + const hasPivot = obj.pivot !== void 0; + obj.pivot ??= [ + null, + null + ]; const degree = obj.angle ?? 0; const radius = -degree * Math.PI / 180; let width = (obj.scale ? obj.scale[0] ?? 0 : 100) / 100; @@ -1257,23 +1336,26 @@ async function createElementEvent(obj, style) { const uniform = Math.sqrt(width * width + height * height); width /= uniform; height /= uniform; - const roomLayer = createLayer(key, new Rect(iconSize / 2, iconSize / 2, iconSize * width, iconSize * height), null, style).then((roomLayer2) => { + const roomLayer = createLayerFromBackground(key, new Rect(iconSize / 2, iconSize / 2, iconSize * width, iconSize * height), null, style); + roomLayer.forEach((roomLayer2) => { roomLayer2.style.transform = `translate(-50%, -50%) rotate(${-degree}deg)`; return roomLayer2; }); - let pivotx = width * (1 - pleft * 2); - let pivoty = height * (1 - ptop * 2); - const widthrotated = pivotx * Math.cos(radius) + pivoty * Math.sin(radius); - const heightrotated = -pivotx * Math.sin(radius) + pivoty * Math.cos(radius); - const pointLayer = document.createElement("div"); - pointLayer.style.position = "absolute"; - pointLayer.style.width = `${style.scale}px`; - pointLayer.style.height = `${style.scale}px`; - pointLayer.style.left = `${iconSize * (1 - widthrotated) * style.scale / 2}px`; - pointLayer.style.top = `${iconSize * (1 + heightrotated) * style.scale / 2}px`; - pointLayer.style.backgroundColor = "#FF0000"; - layersToAdd.push(roomLayer); - layersToAdd.push(Promise.resolve(pointLayer)); + layersToAdd.push(...roomLayer); + if (hasPivot) { + let pivotx = width * (1 - pleft * 2); + let pivoty = height * (1 - ptop * 2); + const widthrotated = pivotx * Math.cos(radius) + pivoty * Math.sin(radius); + const heightrotated = -pivotx * Math.sin(radius) + pivoty * Math.cos(radius); + const pointLayer = document.createElement("div"); + pointLayer.style.position = "absolute"; + pointLayer.style.width = `${style.scale}px`; + pointLayer.style.height = `${style.scale}px`; + pointLayer.style.left = `${iconSize * (1 - widthrotated) * style.scale / 2}px`; + pointLayer.style.top = `${iconSize * (1 + heightrotated) * style.scale / 2}px`; + pointLayer.style.backgroundColor = "#FF0000"; + layersToAdd.push(pointLayer); + } } break; case EventType.PaintHands: @@ -1281,75 +1363,73 @@ async function createElementEvent(obj, style) { case EventType.TintRows: { const border = obj.border; - const backColorLayer = createLayer(key, null, Color.FromRgba(obj.tintColor ?? "FFFFFFFF"), style); - const foreColorLayer = border ? createLayer(border === "Outline" ? `${key}_0` : border === "Glow" ? `${key}_1` : "", null, Color.FromRgba(obj.borderColor ?? "FFFFFFFF"), style) : null; - layersToAdd.push(backColorLayer); - layersToAdd.push(foreColorLayer); + const backColorLayer = createLayerFromBackground(key, null, Color.FromRgba(obj.tintColor ?? "FFFFFFFF"), style); + const foreColorLayer = border ? createLayerFromBackground(border === "Outline" ? `${key}_0` : border === "Glow" ? `${key}_1` : "", null, Color.FromRgba(obj.borderColor ?? "FFFFFFFF"), style) : []; + layersToAdd.push(...backColorLayer); + layersToAdd.push(...foreColorLayer); } break; case EventType.SetBackgroundColor: { const backType = obj.backgroundType ?? "Color"; - const iconLayer2 = createLayer(key, null, null, style); + const iconLayer2 = createLayerFromBackground(key, null, null, style); const images = obj.image ?? []; const imagePath = images.length > 0 ? images[0] : ""; const contentInfo = slices.get(`${key}_1`); - const colorLayer = createLayer(`${key}_0`, null, Color.FromRgba((backType === "Color" ? obj.color : null) ?? "FFFFFF"), style); - const contentLayer = backType === "Image" ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style).then((contentLayer2) => { + const colorLayer = createLayerFromBackground(`${key}_0`, null, Color.FromRgba((backType === "Color" ? obj.color : null) ?? "FFFFFF"), style); + const contentLayer = backType === "Image" ? createLayerFromBackground("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : []; + contentLayer.forEach((contentLayer2) => { if (backType === "Image" && contentLayer2) { contentLayer2.style.backgroundImage = `url(${imagePath})`; contentLayer2.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; contentLayer2.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; } return contentLayer2; - }) : null; - layersToAdd.push(iconLayer2); - layersToAdd.push(colorLayer); - layersToAdd.push(contentLayer); + }); + layersToAdd.push(...iconLayer2); + layersToAdd.push(...colorLayer); + layersToAdd.push(...contentLayer); } break; case EventType.SetCrotchetsPerBar: { const cpb = obj.crotchetsPerBar ?? 0; - const iconLayer2 = createLayer(key, null, null, style); - const cpbLayer = createRDFontLayer(cpb > 9 ? "-" : cpb.toString(), style, Color.Black).then((cpbLayer2) => { - cpbLayer2.style.left = `${2 * style.scale}px`; - cpbLayer2.style.top = `${9 * style.scale}px`; - return cpbLayer2; - }); - const bLayer = createRDFontLayer("4", style, Color.Black).then((bLayer2) => { - bLayer2.style.left = `${8 * style.scale}px`; - bLayer2.style.top = `${14 * style.scale}px`; - return bLayer2; - }); - layersToAdd.push(iconLayer2); + const iconLayer2 = createLayerFromBackground(key, null, null, style); + const cpbLayer = createRDFontLayer(cpb > 9 ? "-" : cpb.toString(), style, Color.Black); + cpbLayer.style.left = `${2 * style.scale}px`; + cpbLayer.style.top = `${9 * style.scale}px`; + const bLayer = createRDFontLayer("4", style, Color.Black); + bLayer.style.left = `${8 * style.scale}px`; + bLayer.style.top = `${14 * style.scale}px`; + layersToAdd.push(...iconLayer2); layersToAdd.push(cpbLayer); layersToAdd.push(bLayer); } break; case EventType.SetForeground: { - const iconLayer2 = createLayer(key, null, null, style); + const iconLayer2 = createLayerFromBackground(key, null, null, style); const images = obj.image ?? []; const imagePath = images.length > 0 ? images[0] : ""; const contentInfo = slices.get(`${key}_1`); - const colorLayer = imagePath ? createLayer(`${key}_0`, null, Color.Black, style) : null; - const contentLayer = imagePath ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style).then((contentLayer2) => { + const colorLayer = imagePath ? createLayerFromBackground(`${key}_0`, null, Color.Black, style) : []; + const contentLayer = imagePath ? createLayerFromBackground("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : []; + contentLayer.forEach((contentLayer2) => { if (contentLayer2) { contentLayer2.style.backgroundImage = `url(${imagePath})`; contentLayer2.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; contentLayer2.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; } return contentLayer2; - }) : null; - layersToAdd.push(iconLayer2); - layersToAdd.push(colorLayer); - layersToAdd.push(contentLayer); + }); + layersToAdd.push(...iconLayer2); + layersToAdd.push(...colorLayer); + layersToAdd.push(...contentLayer); } break; default: - const layer = createLayer(hasType ? key : "event_Unknown", null, null, style); - layersToAdd.push(layer); + const layer = createLayerFromBackground(hasType ? key : "event_Unknown", null, null, style); + layersToAdd.push(...layer); break; } break; @@ -1357,12 +1437,13 @@ async function createElementEvent(obj, style) { if (evinfo.isDurationEvent) { const duration = obj[evinfo.durationKey] ?? 0; const durWidth = iconSize * duration; - const durationLayer = durWidth > slcinfo.bounds.width ? createLayer(evbarea, new Rect(slcinfo.bounds.width, 0, durWidth - slcinfo.bounds.width, slcinfo.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style).then((layer) => { + const durationLayer = durWidth > slcinfo.bounds.width ? createLayerFromBackground(evbarea, new Rect(slcinfo.bounds.width, 0, durWidth - slcinfo.bounds.width, slcinfo.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style, true) : []; + durationLayer.forEach((layer) => { layer.style.pointerEvents = "none"; layerHoverInit(layer); return layer; - }) : null; - layersToAdd.push(durationLayer); + }); + layersToAdd.push(...durationLayer); } const rooms = obj.rooms ?? []; const roomEnabled = new Color(4292392977); @@ -1370,32 +1451,27 @@ async function createElementEvent(obj, style) { if (evinfo.isRoomEvent) { const roomLayers = []; for (let i = 0; i < 4; i++) { - const roomLayer = createLayer(`room_${i}`, new Point(iconSize, 0), rooms.indexOf(i) > -1 ? roomEnabled : roomDisabled, style).then((roomLayer2) => { - if (roomLayer2) { - layerHoverInit(roomLayer2); - } - return roomLayer2; - }); - roomLayers.push(roomLayer); + const roomLayer = createLayerFromBackground(`room_${i}`, new Point(iconWidth, 0), rooms.indexOf(i) > -1 ? roomEnabled : roomDisabled, style); + roomLayers.push(...roomLayer); } - const roomTopLayer = rooms.indexOf(4) > -1 ? createLayer(`room_top`, new Point(iconSize, 0), roomEnabled, style).then((roomTopLayer2) => { - if (roomTopLayer2) { - layerHoverInit(roomTopLayer2); + const roomTopLayer = rooms.indexOf(4) > -1 ? createLayerFromBackground(`room_top`, new Point(iconWidth, 0), roomEnabled, style) : []; + roomLayers.push(...roomTopLayer); + roomLayers.forEach((roomLayer) => { + if (roomLayer) { + layerHoverInit(roomLayer); } - return roomTopLayer2; - }) : null; - roomLayers.push(roomTopLayer); + }); layersToAdd.push(...roomLayers); } const condition = obj.if ?? ""; if (condition.length > 0) { const positive = /(? layer?.then((layer2) => { - layer2.filterData.hue = hsb[0]; - layer2.filterData.saturation = hsb[1]; - layer2.filterData.brightness = hsb[2]; - })); + layersToAdd.forEach((layer) => { + layer.filterData.hue = hsb[0]; + layer.filterData.saturation = hsb[1]; + layer.filterData.brightness = hsb[2]; + }); } - layersToAdd.forEach((layer) => layer?.then((layer2) => { - layer2.updateFilter(); - })); + layersToAdd.forEach((layer) => { + layer.updateFilter(); + }); } element.onStateChange = (style2) => { style2 = { ...style2 }; - layersToAdd.forEach((layer) => layer?.then((layer2) => { - if (layer2.onStateChange) { - layer2.onStateChange(style2); + layersToAdd.forEach((layer) => { + if (layer.onStateChange) { + layer.onStateChange(style2); } - })); + }); }; element.moveTo = function(x, y) { this.style.left = `${x}px`; this.style.top = `${y}px`; }; - for await (const layer of layersToAdd) { + for (const layer of layersToAdd) { if (layer) { element.appendChild(layer); } diff --git a/script/rdtkview_render.js b/script/rdtkview_render.js new file mode 100644 index 0000000..8e0addc --- /dev/null +++ b/script/rdtkview_render.js @@ -0,0 +1,82 @@ +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 = + `
JSON解析错误:${e.message}
`; + 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); + console.log(obj, elem); + 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(() => { + console.log("hello"); + const pres = document.querySelectorAll("pre"); + pres.forEach((codeBlock) => { + const lang = codeBlock.getAttribute("data-lang") || ""; + console.log(codeBlock, 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); + } + }); + }); +}); diff --git a/script/special.js b/script/special.js index 536258a..5e8ce8d 100644 --- a/script/special.js +++ b/script/special.js @@ -366,12 +366,12 @@ function rdview2() { return elem; }); elemPromises.push(elem); - Promise.all(elemPromises).then((elems) => { - elems.forEach((elem) => { - rdcanvas.appendChild(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`; } From a14b4436f58b9f7c75004e1e557ff7b43cc47d6a Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Fri, 16 Jan 2026 20:14:42 +0800 Subject: [PATCH 15/16] =?UTF-8?q?[RDView]=20=E5=95=8A=E8=8D=89=E6=88=91=20?= =?UTF-8?q?degug=20=E6=80=8E=E4=B9=88=E8=BF=98=E5=9C=A8=E9=87=8C=E9=9D=A2?= =?UTF-8?q?=EF=BC=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/changelog.md | 3 +++ script/rdtkview_render.js | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pages/changelog.md b/pages/changelog.md index a3038ea..ceb0c08 100644 --- a/pages/changelog.md +++ b/pages/changelog.md @@ -1,5 +1,8 @@ # 更新信息 +#### 2026-01-16 +- RDTKView(~~RDView2~~) 已完成部署 + #### 2026-01-14 - 制作人员表增加了 - RDView 对正式版编辑器新特性的部分适配 diff --git a/script/rdtkview_render.js b/script/rdtkview_render.js index 8e0addc..5b0c074 100644 --- a/script/rdtkview_render.js +++ b/script/rdtkview_render.js @@ -15,7 +15,6 @@ export function render(data, width, height, scale = 2.0) { for (let obj of objs) { const style = { ...eventStyle, enabled: obj.active ?? true }; const elem = createElementEvent(obj, style); - console.log(obj, elem); if (!elem) continue; elem.eventStyle = style; elem.style.position = "absolute"; @@ -58,11 +57,9 @@ export function render(data, width, height, scale = 2.0) { window.$docsify.plugins = [].concat(window.$docsify.plugins, (hook) => { hook.doneEach(() => { - console.log("hello"); const pres = document.querySelectorAll("pre"); pres.forEach((codeBlock) => { const lang = codeBlock.getAttribute("data-lang") || ""; - console.log(codeBlock, lang); if (lang.startsWith("rdtkview")) { const code = codeBlock.querySelector("code").innerText || ""; const args = lang.slice(8).trim().split(" "); From 5aedbbfbe0c3a6ac104a81286e5e4f58857039d4 Mon Sep 17 00:00:00 2001 From: OLDREDSTONE Date: Fri, 16 Jan 2026 23:31:09 +0800 Subject: [PATCH 16/16] =?UTF-8?q?[RDView]=20=E4=BF=AE=E5=A4=8D=20hsb=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=AF=BB=E5=8F=96=E5=BC=82=E5=B8=B8=E5=92=8C?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/rdtkview.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/script/rdtkview.js b/script/rdtkview.js index be302b6..7f6a805 100644 --- a/script/rdtkview.js +++ b/script/rdtkview.js @@ -762,12 +762,15 @@ function createLayerFromBackground(key, bound, color, style, backgroundRepeat = const height = bound.height; const infoLeft = info.bounds.left; const infoTop = info.bounds.top; + const widthScale = width / info.bounds.width; + const heightScale = height / info.bounds.height; layer.style.left = `${(left - pivotX) * style.scale}px`; layer.style.top = `${(top - pivotY) * style.scale}px`; layer.style.width = `${width * style.scale}px`; layer.style.height = `${height * style.scale}px`; - layer.style.backgroundPosition = `-${infoLeft * style.scale}px -${infoTop * style.scale}px`; - layer.style.backgroundSize = `${assetSize.width * width * style.scale}px ${assetSize.height * height * style.scale}px`; + layer.style.backgroundPosition = `-${infoLeft * widthScale * style.scale}px -${infoTop * heightScale * style.scale}px`; + layer.style.backgroundSize = `${assetSize.width * widthScale * style.scale}px ${assetSize.height * heightScale * style.scale}px`; + console.log(layer.style.backgroundSize); } else { bound = bound ?? new Point(0, 0); const left = bound.x; @@ -963,7 +966,6 @@ function createElementEvent(obj, style) { } if (!slices.has(key0)) { if (!slices.has("event_Unknown")) { - console.log(slices); return null; } key0 = "event_Unknown"; @@ -1262,7 +1264,10 @@ function createElementEvent(obj, style) { const top = iconSize / 2 - iconBounds.height * s / 2; const patternLayers = []; const backLayers2 = createBackLayer(new Size(slcinfo.bounds.width, slcinfo.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style); - for (let p of obj.pattern ?? "------") { + if (typeof obj.pattern !== "string" || obj.pattern.length !== 6) { + obj.pattern = "------"; + } + for (let p of obj.pattern) { const beatxLayer = createLayerFromBackground(p === "x" ? beatx : beatline, new Rect(left, top, width, iconBounds.height * s), null, style); patternLayers.push(...beatxLayer); left += width; @@ -1511,18 +1516,19 @@ function createElementEvent(obj, style) { if (obj["$style"]) { const hsb = obj["$style"].hsb ?? [ 0, - 0, - 0 + 1, + 1 ]; - if (hsb[0] !== 0 || hsb[1] !== 0 || hsb[2] !== 0) { + if (hsb.length === 3 && (hsb[0] !== 0 || hsb[1] !== 0 || hsb[2] !== 0)) { layersToAdd.forEach((layer) => { + if (!layer.filterData) return; layer.filterData.hue = hsb[0]; layer.filterData.saturation = hsb[1]; layer.filterData.brightness = hsb[2]; }); } layersToAdd.forEach((layer) => { - layer.updateFilter(); + layer.updateFilter?.(); }); } element.onStateChange = (style2) => {