diff --git a/index.html b/index.html index dfbf132..552e396 100644 --- a/index.html +++ b/index.html @@ -36,11 +36,6 @@ - + + @@ -134,10 +107,8 @@ - - - + > --> diff --git a/pages/appendix_tools.md b/pages/appendix_tools.md index 70e9acb..b9fe73d 100644 --- a/pages/appendix_tools.md +++ b/pages/appendix_tools.md @@ -20,4 +20,72 @@ g 1 1 5 4 #0ff{ }; +--- + +
+ --- \ No newline at end of file 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 - 调整目录结构 - 双人模式措辞更改 diff --git a/rdviewAssets/assets.bin b/rdviewAssets/assets.bin new file mode 100644 index 0000000..2c1e294 Binary files /dev/null and b/rdviewAssets/assets.bin differ diff --git a/rdviewAssets/assets.png b/rdviewAssets/assets.png index 0284372..7b9cbb9 100644 Binary files a/rdviewAssets/assets.png and b/rdviewAssets/assets.png differ diff --git a/script/Extensions.js b/script/Extensions.js deleted file mode 100644 index f8103b2..0000000 --- a/script/Extensions.js +++ /dev/null @@ -1,1176 +0,0 @@ -// RhythmBase.View/Assets/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 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 isEmpty() { - return this.width <= 0 || this.height <= 0; - } - constructor(arg0, arg1, arg2, arg3) { - if (arg0 !== void 0 && arg1 !== void 0) { - if (arg2 !== void 0 && arg3 !== void 0) { - this.left = arg0; - this.top = arg1; - this.right = arg0 + arg2; - this.bottom = arg1 + arg3; - return; - } - this.right = arg0; - this.bottom = arg1; - 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); - } - contains(point) { - return point.x >= 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 new file mode 100644 index 0000000..52c6413 --- /dev/null +++ b/script/View.js @@ -0,0 +1,1412 @@ +// 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) { + 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})`; + } + 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 = "./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; + }); +} +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 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["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; + 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), + 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"), + 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 | EventAttriblte.RoomEvent, "duration"), + 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, "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, "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), + 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 | 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), + 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), + ShowHands: new EventInfo(Tab.Actions), + 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), + TagAction: new EventInfo(Tab.Actions), + TextExplosion: new EventInfo(Tab.Actions), + 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 +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 { + 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); + 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 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"); + 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); + 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; +} +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.style.opacity = "0"; + layer.onStateChange = (style) => { + if (style.hover) { + layer.style.opacity = "1.0"; + } else { + layer.style.opacity = "0"; + } + }; +} +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 ?? EventType.ForwardEvent; + let key0 = `event_${obj.type}`; + if (!slices.has(key0)) { + 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 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.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 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 = 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 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.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 + ]); + } + 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); + const iconLayer = createLayer(key, null, null, style); + addLayers([ + ...backLayers2, + iconLayer + ]); + } + break; + case EventType.DesktopColor: + { + 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, + iconColorLayer, + 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 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, null); + 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; + 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([ + iconLayer, + startColorLayer, + 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 + ]); + } + 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 = 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 + }; + internalLayers.forEach((layer) => { + if (layer.onStateChange) { + layer.onStateChange(style2); + } + }); + }; + return element; +} +export { + createElementEvent +}; 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 930c5cf..1bf3445 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; @@ -21,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"); @@ -61,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%"; @@ -112,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() { @@ -129,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; @@ -154,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) { @@ -173,8 +211,8 @@ function rdview() { lineNumbers.push(i); if (numLinesOfSentence > 1) { Array(numLinesOfSentence - 1) - .fill('') - .forEach((_) => lineNumbers.push('')); + .fill("") + .forEach((_) => lineNumbers.push("")); } i++; } @@ -184,24 +222,166 @@ 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() { + 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() { + let objs = []; + try { + objs = JSON.parse(`[${textarea.value}]`); + rdcanvas.innerHTML = ""; + } 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 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); + } + } + } + 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(() => { +}); 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%; }