diff --git a/index.html b/index.html index 8dc7901..552e396 100644 --- a/index.html +++ b/index.html @@ -19,8 +19,8 @@ - -
加载中...
+ +
加载中...
- diff --git a/pages/appendix_tools.md b/pages/appendix_tools.md index 3d1ea8b..b9fe73d 100644 --- a/pages/appendix_tools.md +++ b/pages/appendix_tools.md @@ -23,22 +23,69 @@ g 1 1 5 4 #0ff{ ---
--- \ No newline at end of file diff --git a/script/assets.bin b/rdviewAssets/assets.bin similarity index 66% rename from script/assets.bin rename to rdviewAssets/assets.bin index 92ef748..2c1e294 100644 Binary files a/script/assets.bin 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 index 57d27c6..52c6413 100644 --- a/script/View.js +++ b/script/View.js @@ -213,7 +213,22 @@ var Color = class _Color { return new _Color(this.argb); } static FromRgba(r, g, b, a) { - return new _Color(a, r, g, b); + if (typeof r === "string" && g === void 0 && b === void 0 && a === void 0) { + r = r.trim(); + if (r[0] === "#") r = r.slice(1); + if (r.length === 8) { + return new _Color(r.slice(6, 8) + r.slice(0, 6)); + } else if (r.length === 6) return new _Color(r); + else if (r.length === 4) { + return new _Color(r[3] + r[3] + r.slice(0, 3).split("").map((i) => i + i).join("")); + } else if (r.length === 3) { + return new _Color("FF" + r.split("").map((i) => i + i).join("")); + } else return new _Color(); + } else if (typeof r === "number" && typeof g === "number" && typeof b === "number" && typeof a === "number") { + return new _Color(a, r, g, b); + } else { + return new _Color(); + } } toRgbaString() { return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a / 255})`; @@ -263,7 +278,7 @@ var SliceInfo = class { }; var assetFilePath = "assets.png"; var slicesFilePath = "assets.bin"; -var directoryPath = "./script"; +var directoryPath = "./rdviewAssets"; async function loadAssetFile() { const pngPath = directoryPath + "/" + assetFilePath; return await new Promise((resolve, reject) => { @@ -351,6 +366,36 @@ var Tab = /* @__PURE__ */ function(Tab2) { Tab2["Unknown"] = "unknown"; return Tab2; }({}); +var SayReadyGetSetGoWords = /* @__PURE__ */ function(SayReadyGetSetGoWords2) { + SayReadyGetSetGoWords2["SayReaDyGetSetGoNew"] = "SayReaDyGetSetGoNew"; + SayReadyGetSetGoWords2["SayReaDyGetSetOne"] = "SayReaDyGetSetOne"; + SayReadyGetSetGoWords2["SayGetSetGo"] = "SayGetSetGo"; + SayReadyGetSetGoWords2["SayGetSetOne"] = "SayGetSetOne"; + SayReadyGetSetGoWords2["JustSayRea"] = "JustSayRea"; + SayReadyGetSetGoWords2["JustSayDy"] = "JustSayDy"; + SayReadyGetSetGoWords2["JustSayGet"] = "JustSayGet"; + SayReadyGetSetGoWords2["JustSaySet"] = "JustSaySet"; + SayReadyGetSetGoWords2["JustSayAnd"] = "JustSayAnd"; + SayReadyGetSetGoWords2["JustSayGo"] = "JustSayGo"; + SayReadyGetSetGoWords2["JustSayStop"] = "JustSayStop"; + SayReadyGetSetGoWords2["JustSayAndStop"] = "JustSayAndStop"; + SayReadyGetSetGoWords2["SaySwitch"] = "SaySwitch"; + SayReadyGetSetGoWords2["SayWatch"] = "SayWatch"; + SayReadyGetSetGoWords2["SayListen"] = "SayListen"; + SayReadyGetSetGoWords2["Count1"] = "Count1"; + SayReadyGetSetGoWords2["Count2"] = "Count2"; + SayReadyGetSetGoWords2["Count3"] = "Count3"; + SayReadyGetSetGoWords2["Count4"] = "Count4"; + SayReadyGetSetGoWords2["Count5"] = "Count5"; + SayReadyGetSetGoWords2["Count6"] = "Count6"; + SayReadyGetSetGoWords2["Count7"] = "Count7"; + SayReadyGetSetGoWords2["Count8"] = "Count8"; + SayReadyGetSetGoWords2["Count9"] = "Count9"; + SayReadyGetSetGoWords2["Count10"] = "Count10"; + SayReadyGetSetGoWords2["SayReadyGetSetGo"] = "SayReadyGetSetGo"; + SayReadyGetSetGoWords2["JustSayReady"] = "JustSayReady"; + return SayReadyGetSetGoWords2; +}({}); var EventType = /* @__PURE__ */ function(EventType2) { EventType2["AddClassicBeat"] = "AddClassicBeat"; EventType2["AddFreeTimeBeat"] = "AddFreeTimeBeat"; @@ -455,9 +500,7 @@ var EventInfo = class { constructor(tab, enumAttriblte, durationKey) { this.defaultTab = tab; this.attr = enumAttriblte ?? EventAttriblte.None; - if (durationKey !== void 0) { - this.durationKey = durationKey; - } + this.durationKey = durationKey ?? "duration"; } }; var WordInfo = class { @@ -501,20 +544,20 @@ var EventInfos = { AddClassicBeat: new EventInfo(Tab.Rows), AddFreeTimeBeat: new EventInfo(Tab.Rows), AddOneshotBeat: new EventInfo(Tab.Rows), - AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + AdvanceText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), BassDrop: new EventInfo(Tab.Actions), Blend: new EventInfo(Tab.Decorations), CallCustomMethod: new EventInfo(Tab.Actions), ChangeCharacter: new EventInfo(Tab.Actions), ChangePlayersRows: new EventInfo(Tab.Actions), Comment: new EventInfo(Tab.Unknown), - CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), - FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + CustomFlash: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + DesktopColor: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), + FadeRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), FinishLevel: new EventInfo(Tab.Actions), Flash: new EventInfo(Tab.Actions), FlipScreen: new EventInfo(Tab.Actions), - FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + FloatingText: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), ForwardDecorationEvent: new EventInfo(Tab.Decorations), ForwardEvent: new EventInfo(Tab.Unknown), ForwardRowEvent: new EventInfo(Tab.Rows), @@ -523,13 +566,13 @@ var EventInfos = { InvertColors: new EventInfo(Tab.Actions), MacroEvent: new EventInfo(Tab.Unknown), MaskRoom: new EventInfo(Tab.Rooms), - Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + Move: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + MoveCamera: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + MoveRoom: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + MoveRow: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), NarrateRowInfo: new EventInfo(Tab.Sounds), - NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + NewWindowDance: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + PaintHands: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), PlayAnimation: new EventInfo(Tab.Decorations), PlayExpression: new EventInfo(Tab.Actions), PlaySong: new EventInfo(Tab.Sounds), @@ -543,13 +586,13 @@ var EventInfos = { ReorderSprite: new EventInfo(Tab.Decorations), ReorderWindows: new EventInfo(Tab.Windows), SayReadyGetSetGo: new EventInfo(Tab.Sounds), - SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetBackgroundColor: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetBeatSound: new EventInfo(Tab.Sounds), SetBeatsPerMinute: new EventInfo(Tab.Sounds), SetClapSounds: new EventInfo(Tab.Sounds), SetCountingSound: new EventInfo(Tab.Sounds), SetCrotchetsPerBar: new EventInfo(Tab.Sounds), - SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetForeground: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetGameSound: new EventInfo(Tab.Sounds), SetHandOwner: new EventInfo(Tab.Actions), SetHeartExplodeInterval: new EventInfo(Tab.Sounds), @@ -558,28 +601,28 @@ var EventInfos = { SetOneshotWave: new EventInfo(Tab.Rows), SetPlayStyle: new EventInfo(Tab.Actions), SetRoomContentMode: new EventInfo(Tab.Rooms), - SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), + SetRoomPerspective: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), SetRowXs: new EventInfo(Tab.Rows), - SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetSpeed: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), + SetTheme: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + SetVFXPreset: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), SetVisible: new EventInfo(Tab.Decorations), - SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent), - ShakeScreen: new EventInfo(Tab.Actions), - ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SetWindowContent: new EventInfo(Tab.Windows, EventAttriblte.DurationEvent, "duration"), + ShakeScreen: new EventInfo(Tab.Actions, EventAttriblte.RoomEvent), + ShakeScreenCustom: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), ShowDialogue: new EventInfo(Tab.Actions), ShowHands: new EventInfo(Tab.Actions), - ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent), - ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + ShowRooms: new EventInfo(Tab.Rooms, EventAttriblte.DurationEvent, "duration"), + ShowStatusSign: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), ShowSubdivisionsRows: new EventInfo(Tab.Actions), - SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), + SpinningRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration"), Stutter: new EventInfo(Tab.Actions), TagAction: new EventInfo(Tab.Actions), TextExplosion: new EventInfo(Tab.Actions), - Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent), - TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent), - WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent) + Tile: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + Tint: new EventInfo(Tab.Decorations, EventAttriblte.DurationEvent, "duration"), + TintRows: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent | EventAttriblte.RoomEvent, "duration"), + WindowResize: new EventInfo(Tab.Actions, EventAttriblte.DurationEvent, "duration") }; // View.ts @@ -600,8 +643,8 @@ function createLayer(key, bound, color, style) { const layer = document.createElement("div"); const info = slices.get(key); layer.style.position = "absolute"; - layer.style.boxSizing = "content-box"; - if (info.isNinePatch) { + layer.style.boxSizing = "content-box"; + if (info?.isNinePatch) { const center = info.center; const width = bound?.width ?? info.bounds.width; const height = bound?.height ?? info.bounds.height; @@ -617,12 +660,25 @@ function createLayer(key, bound, color, style) { layer.style.width = `${(width - center.left - (info.bounds.width - center.right)) * style.scale}px`; layer.style.height = `${(height - center.top - (info.bounds.height - center.bottom)) * style.scale}px`; } else { - layer.style.left = `${((bound?.left ?? bound?.x ?? 0) - info.pivot.x) * style.scale}px`; - layer.style.top = `${((bound?.top ?? bound?.y ?? 0) - info.pivot.y) * style.scale}px`; - layer.style.width = `${(bound?.width ?? info.bounds.width) * style.scale}px`; - layer.style.height = `${(bound?.height ?? info.bounds.height) * style.scale}px`; - layer.style.backgroundImage = `url(${info.blobUrl})`; - layer.style.backgroundSize = `${bound?.width ?? info.bounds.width * style.scale}px ${bound?.height ?? info.bounds.height * style.scale}px`; + if (bound instanceof Rect) { + layer.style.left = `${(bound.left - (info?.pivot.x ?? 0)) * style.scale}px`; + layer.style.top = `${(bound.top - (info?.pivot.y ?? 0)) * style.scale}px`; + layer.style.width = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px`; + layer.style.height = `${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; + if (info) { + layer.style.backgroundImage = `url(${info.blobUrl})`; + } + layer.style.backgroundSize = `${(bound.width ?? info?.bounds.width ?? 0) * style.scale}px ${(bound.height ?? info?.bounds.height ?? 0) * style.scale}px`; + } else { + layer.style.left = `${((bound?.x ?? 0) - (info?.pivot.x ?? 0)) * style.scale}px`; + layer.style.top = `${((bound?.y ?? 0) - (info?.pivot.y ?? 0)) * style.scale}px`; + layer.style.width = `${(info?.bounds.width ?? 0) * style.scale}px`; + layer.style.height = `${(info?.bounds.height ?? 0) * style.scale}px`; + if (info) { + layer.style.backgroundImage = `url(${info.blobUrl})`; + } + layer.style.backgroundSize = `${(info?.bounds.width ?? 0) * style.scale}px ${(info?.bounds.height ?? 0) * style.scale}px`; + } } if (color && Color.White.equals(color) === false) { const filterId = getColorMatrixId(color); @@ -663,7 +719,22 @@ function getColorMatrixId(rgba) { colorMatrixIds.set(rgba.toUint32(), filter.getAttribute("id")); return filter.getAttribute("id"); } -function createRDFontLayer(text, style) { +function measureRDFontText(text) { + let len = 0; + for (let i = 0; i < text.length; i++) { + const char = text.charAt(i); + if (char === "\n") { + len = 0; + } else { + const charCode = char.charCodeAt(0); + const charKey = `char_${charCode.toString(16).padStart(4, "0")}`; + const charInfo = slices.get(charKey); + len += charInfo?.bounds.width ?? 0; + } + } + return len; +} +function createRDFontLayer(text, style, color) { const lineHead = new Point(0, -charHeight); const start = lineHead.clone(); const layer = document.createElement("div"); @@ -677,9 +748,11 @@ function createRDFontLayer(text, style) { const charCode = char.charCodeAt(0); const charKey = `char_${charCode.toString(16).padStart(4, "0")}`; const charInfo = slices.get(charKey); - const charLayer = createLayer(charKey, new Point(start.x, start.y), null, style); - start.x += (charInfo?.bounds.width ?? charHeight) * style.scale; - layer.appendChild(charLayer); + if (charInfo) { + const charLayer = createLayer(charKey, new Point(start.x, start.y), color, style); + start.x += charInfo.bounds.width * style.scale; + layer.appendChild(charLayer); + } } } return layer; @@ -719,6 +792,7 @@ function colorOf(tab) { } } function layerHoverInit(layer) { + layer.style.opacity = "0"; layer.onStateChange = (style) => { if (style.hover) { layer.style.opacity = "1.0"; @@ -727,15 +801,46 @@ function layerHoverInit(layer) { } }; } +function createHintLayer(hint, width, color) { + const hintLayer = document.createElement("div"); + hintLayer.style.position = "absolute"; + hintLayer.style.left = `${width}px`; + hintLayer.style.width = `max-content`; + hintLayer.innerHTML = hint; + hintLayer.style.fontSize = `${18}px`; + hintLayer.style.fontFamily = "d9, Arial, sans-serif"; + hintLayer.style.color = color.toRgbaString(); + hintLayer.style.fontWeight = "bold"; + hintLayer.style.textShadow = ` + 2px 2px 0 black, + 2px 0px 0 black, + 2px -2px 0 black, + 0px -2px 0 black, + -2px -2px 0 black, + -2px 0px 0 black, + -2px 2px 0 black, + 0px 2px 0 black + `; + hintLayer.style.pointerEvents = "none"; + hintLayer.style.opacity = "0"; + hintLayer.style.zIndex = "10"; + hintLayer.onStateChange = (style) => { + if (style.hover) { + hintLayer.style.opacity = "1.0"; + } else { + hintLayer.style.opacity = "0"; + } + }; + return hintLayer; +} function createElementEvent(obj, style) { style = { ...new IconStyle(), ...style }; - const evttype = obj.type; + const evttype = obj.type ?? EventType.ForwardEvent; let key0 = `event_${obj.type}`; if (!slices.has(key0)) { - console.warn(`Slice for event type ${evttype} not found, using Unknown.`); if (!slices.has("event_Unknown")) { return null; } @@ -759,9 +864,13 @@ function createElementEvent(obj, style) { const beatline = "event_beat_line"; const evtag = "event_tag"; const evbarea = "event_beat_area"; + const evbskip = "event_beat_skip"; const beatColor = new Color(4284539717); const element = document.createElement("div"); const internalLayers = []; + if (evttype === EventType.NewWindowDance) { + obj.tab = obj.customTab ?? Tab.Windows; + } function addLayers(layers) { for (const layer of layers) { if (layer) { @@ -811,19 +920,22 @@ function createElementEvent(obj, style) { const loop = obj.loops ?? 0; const subdiv = obj.subdivisions ?? 1; const hold = obj.hold ?? false; + const skip = obj.skipshot ?? false; const mode = obj.freezeBurnMode ?? null; const delay = obj.freezeBurnMode === "Freezeshot" ? obj.delay ?? 0 : 0; const subdivWidth = iconSize * (subdiv - 1) / subdiv * tick; const eventWidth = iconSize * (interval * loop + tick + delay); const off = interval - tick; const backLayers2 = createBackLayer(new Size(eventWidth, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); - const holdWidth = iconSize * (interval - tick - delay); + const holdWidth = hold ? iconSize * (interval - tick - delay) : 0; const holdLayer = hold && holdWidth - subdivWidth > 0 ? createLayer(evbarea, new Rect(eventWidth + subdivWidth, 0, holdWidth - subdivWidth, iconSize), new Color(style.enabled ? 4291839731 : 4285493103), style) : null; const subdivLayer = subdiv > 1 ? createLayer(evbarea, new Rect(eventWidth, 0, subdivWidth, iconSize), new Color(style.enabled ? 4279480353 : 4285493103), style) : null; - const skipshotLayer = obj.skipshot ?? false ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * interval - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style) : null; + const skipshotLayer = skip ? createLayer(evbarea, new Rect(eventWidth + Math.max(subdivWidth, holdWidth), 0, iconSize * (interval - delay) - Math.max(subdivWidth, holdWidth), iconSize), new Color(style.enabled ? 4291115835 : 4285493103), style) : null; + const skipHitLayer = skip ? createLayer(evbskip, new Point(eventWidth + iconSize * (interval - delay) - 1, 0), null, style) : null; if (holdLayer) holdLayer.style.pointerEvents = "none"; if (subdivLayer) subdivLayer.style.pointerEvents = "none"; if (skipshotLayer) skipshotLayer.style.pointerEvents = "none"; + if (skipHitLayer) skipHitLayer.style.pointerEvents = "none"; const pulses = []; const crossLayers = []; const posx = -off * iconSize; @@ -853,6 +965,7 @@ function createElementEvent(obj, style) { } const loopLayer = createLayer("event_beat_loop", new Point(eventWidth, 0), null, style); loopLayer.style.opacity = "0"; + loopLayer.style.zIndex = "5"; loopLayer.onStateChange = (style2) => { if (style2.hover) { loopLayer.style.opacity = "1.0"; @@ -865,12 +978,33 @@ function createElementEvent(obj, style) { holdLayer, subdivLayer, skipshotLayer, + skipHitLayer, ...pulses, loopLayer, ...crossLayers ]); } break; + case EventType.AddFreeTimeBeat: + { + const hold = obj.hold ?? 0; + const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; + if (holdLayer) { + holdLayer.style.pointerEvents = "none"; + } + const backLayers2 = createBackLayer(new Size(info.bounds.width, iconSize), beatColor, style); + const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; + const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style, null); + textLayer.style.left = `${1.5 * style.scale}px`; + textLayer.style.top = `${10 * style.scale}px`; + addLayers([ + holdLayer, + ...backLayers2, + hitLayer, + textLayer + ]); + } + break; case EventType.Comment: { const backLayers2 = createBackLayer(info.bounds.size, new Color(obj.color ?? "7d7d7d"), style); @@ -881,38 +1015,16 @@ function createElementEvent(obj, style) { ]); } break; - case EventType.AddFreeTimeBeat: - { - const hold = obj.hold ?? 0; - const holdLayer = hold > 0 ? createLayer(evbarea, new Rect(info.bounds.width, 0, iconSize * hold - info.bounds.width, iconSize), new Color(style.active ? 4291839731 : 4286462352), style) : null; - if (holdLayer) { - holdLayer.style.pointerEvents = "none"; - } - const backLayers2 = createBackLayer(new Size(info.bounds.width, iconSize), beatColor, style); - const hitLayer = obj.pulse === 6 ? createLayer(hit, new Point(0, 0), null, style) : null; - const textLayer = createRDFontLayer(((obj.pulse ?? 0) + 1).toString(), style); - textLayer.style.left = `${1.5 * style.scale}px`; - textLayer.style.top = `${10 * style.scale}px`; - addLayers([ - holdLayer, - ...backLayers2, - hitLayer, - textLayer - ]); - } - break; case EventType.DesktopColor: { - const duration = obj.duration ?? 0; - const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height * 4), colorOf(obj.tab ?? evinfo.defaultTab), style); - const iconLayer = createLayer(`${key}_0`, new Point(0, info.bounds.height), null, style); - const iconColorLayer = createLayer(key, new Point(0, info.bounds.height), null, style); - const durationLayer = obj.duration > 1 ? createLayer(evbarea, new Rect(iconSize, 0, (duration - 1) * iconSize, info.bounds.height * 4), new Color(4283471790), style) : null; + const backLayers2 = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); + console.log(info.bounds.size); + const iconColorLayer = createLayer(`${key}_0`, new Point(0, iconSize), new Color(obj.endColor ?? "ffffff"), style); + const iconLayer = createLayer(`${key}_1`, new Point(0, iconSize), null, style); addLayers([ ...backLayers2, - durationLayer, - iconLayer, - iconColorLayer + iconColorLayer, + iconLayer ]); } break; @@ -940,7 +1052,7 @@ function createElementEvent(obj, style) { text = "x"; break; } - const textLayer = createRDFontLayer(text, style); + const textLayer = createRDFontLayer(text, style, null); textLayer.style.left = `${1.5 * style.scale}px`; textLayer.style.top = `${10 * style.scale}px`; addLayers([ @@ -974,41 +1086,315 @@ function createElementEvent(obj, style) { ]); } break; + case EventType.SayReadyGetSetGo: + { + const wordInfo = WordInfos[obj.phraseToSay ?? SayReadyGetSetGoWords.JustSayGo]; + const len = wordInfo.length * (obj.tick ?? 0) + 1; + const stringToJoin = wordInfo.phrase.split(" "); + const stringToDraw = [ + stringToJoin[0] + ]; + let lw = measureRDFontText(stringToJoin[0]); + const sw = measureRDFontText(" "); + const backLayers2 = createBackLayer(new Size(len * iconSize, iconSize), colorOf(obj.tab ?? evinfo.defaultTab), style); + const wordLayers = []; + for (let i = 1; i < stringToJoin.length; i++) { + const part = stringToJoin[i]; + const w = measureRDFontText(part); + if (lw + sw + w > len * iconSize * style.scale) { + lw = w; + stringToDraw.push(part); + } else { + lw += sw + w; + stringToDraw[stringToDraw.length - 1] += " " + part; + } + } + const c = Math.min(stringToDraw.length, 3); + let top = iconSize / 2 - charHeight * c / 4 + 1; + for (let i = 0; i < c; i++) { + const line = stringToDraw[i]; + const p = new Point((len * iconSize - measureRDFontText(line) / 2) / 2, top + (i * charHeight + lineHeight) / 2); + const wordLayer = createRDFontLayer(line, { + ...style, + scale: style.scale / 2 + }, null); + wordLayer.style.left = `${p.x * style.scale}px`; + wordLayer.style.top = `${p.y * style.scale}px`; + wordLayers.push(wordLayer); + } + addLayers([ + ...backLayers2, + ...wordLayers + ]); + } + break; + case EventType.SetRowXs: + { + const syncoBeat = obj.syncoBeat ?? -1; + const width = info.bounds.width / 6; + const iconBounds = slices.get(beatx).bounds; + const s = width / iconBounds.width; + let left = 0; + const top = iconSize / 2 - iconBounds.height * s / 2; + const patternLayers = []; + const backLayers2 = createBackLayer(new Size(info.bounds.width, info.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style); + for (let p of obj.pattern) { + const beatxLayer = createLayer(p === "x" ? beatx : beatline, new Rect(left, top, width, iconBounds.height * s), null, style); + patternLayers.push(beatxLayer); + left += width; + } + const syncoBeatLayer = syncoBeat >= 0 ? createLayer(beatsynco, new Rect(width * syncoBeat, top, width, iconBounds.height * s), null, style) : null; + addLayers([ + ...backLayers2, + ...patternLayers, + syncoBeatLayer + ]); + } + break; + case EventType.ShowRooms: + { + const backLayers2 = createBackLayer(new Size(iconSize, iconSize * 4), colorOf(obj.tab ?? evinfo.defaultTab), style); + const roomLayers = []; + for (let i = 0; i < 4; i++) { + const roomLayer = createLayer(`${key}_${obj.rooms.indexOf(i) >= 0 ? "1" : "0"}`, new Point(0, i * iconSize * style.scale), null, { + ...style, + scale: style.scale / 2 + }); + roomLayers.push(roomLayer); + } + addLayers([ + ...backLayers2, + ...roomLayers + ]); + } + break; default: const backLayers = createBackLayer(info.bounds.size, colorOf(obj.tab ?? evinfo.defaultTab), style); addLayers(backLayers); switch (evttype) { case EventType.CustomFlash: + const iconLayer = createLayer(key, null, null, style); + const startColorLayer = createLayer(`${key}_0`, null, new Color(obj.startColor ?? "000000").withAlpha((obj.startOpacity ?? 0) * 255), style); + const endColorLayer = createLayer(`${key}_1`, null, new Color(obj.endColor ?? "000000").withAlpha((obj.endOpacity ?? 0) * 255), style); addLayers([ - createLayer(`${key}_0`, null, new Color(obj.startColor ?? "000000"), style), - createLayer(`${key}_1`, null, new Color(obj.endColor ?? "000000"), style) + iconLayer, + startColorLayer, + endColorLayer ]); break; case EventType.FlipScreen: - const flip = (obj.flipX ? 1 : 0) | (obj.flipY ? 1 : 0); - if (flip === 0) { + { + const flip = (obj.flipX ? 1 : 0) | (obj.flipY ? 2 : 0); + const iconLayer2 = createLayer(flip === 0 ? `${key}_0` : `${key}_${flip - 1}`, null, null, style); addLayers([ - createLayer(key, null, null, style) - ]); - } else { - addLayers([ - createLayer(`${key}_${flip - 1}`, null, null, style) + iconLayer2 ]); } + break; + case EventType.FloatingText: + { + const backColorLayer = createLayer(`${key}_0`, null, Color.FromRgba(obj.color ?? "FFFFFFFF"), style); + const foreColorLayer = createLayer(`${key}_1`, null, Color.FromRgba(obj.outlineColor ?? "FFFFFFFF"), style); + addLayers([ + backColorLayer, + foreColorLayer + ]); + } + break; + case EventType.MoveRoom: + { + const degree = obj.angle ?? 0; + const radius = -degree * Math.PI / 180; + let width = (obj.scale ? obj.scale[0] ?? 0 : 100) / 100; + let height = (obj.scale ? obj.scale[1] ?? 0 : 100) / 100; + const pleft = (obj.pivot ? obj.pivot[0] ?? 0 : 50) / 100; + const ptop = (obj.pivot ? obj.pivot[1] ?? 0 : 50) / 100; + if (width === 0 || height === 0) break; + const uniform = Math.sqrt(width * width + height * height); + width /= uniform; + height /= uniform; + const roomLayer = createLayer(key, new Rect(iconSize / 2, iconSize / 2, iconSize * width, iconSize * height), null, style); + let pivotx = width * (1 - pleft * 2); + let pivoty = height * (1 - ptop * 2); + const widthrotated = pivotx * Math.cos(radius) + pivoty * Math.sin(radius); + const heightrotated = -pivotx * Math.sin(radius) + pivoty * Math.cos(radius); + const pointLayer = document.createElement("div"); + pointLayer.style.position = "absolute"; + pointLayer.style.width = `${style.scale}px`; + pointLayer.style.height = `${style.scale}px`; + pointLayer.style.left = `${iconSize * (1 - widthrotated) * style.scale / 2}px`; + pointLayer.style.top = `${iconSize * (1 + heightrotated) * style.scale / 2}px`; + pointLayer.style.backgroundColor = "#FF0000"; + roomLayer.style.transform = `translate(-50%, -50%) rotate(${-degree}deg)`; + addLayers([ + roomLayer, + pointLayer + ]); + } + break; + case EventType.PaintHands: + case EventType.Tint: + case EventType.TintRows: + { + const border = obj.border; + const backColorLayer = createLayer(key, null, Color.FromRgba(obj.tintColor ?? "FFFFFFFF"), style); + const foreColorLayer = border ? createLayer(border === "Outline" ? `${key}_0` : border === "Glow" ? `${key}_1` : "", null, Color.FromRgba(obj.borderColor ?? "FFFFFFFF"), style) : null; + addLayers([ + backColorLayer, + foreColorLayer + ]); + } + break; + case EventType.SetBackgroundColor: + { + const backType = obj.backgroundType ?? "Color"; + const iconLayer2 = createLayer(key, null, null, style); + const images = obj.image ?? []; + const imagePath = images.length > 0 ? images[0] : ""; + const contentInfo = slices.get(`${key}_1`); + const colorLayer = createLayer(`${key}_0`, null, Color.FromRgba((backType === "Color" ? obj.color : null) ?? "FFFFFF"), style); + const contentLayer = backType === "Image" ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : null; + if (backType === "Image" && contentLayer) { + contentLayer.style.backgroundImage = `url(${imagePath})`; + contentLayer.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; + contentLayer.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; + } + addLayers([ + iconLayer2, + colorLayer, + contentLayer + ]); + } + break; + case EventType.SetCrotchetsPerBar: + { + const cpb = obj.crotchetsPerBar ?? 0; + const iconLayer2 = createLayer(key, null, null, style); + const cpbLayer = createRDFontLayer(cpb > 9 ? "-" : cpb.toString(), style, Color.Black); + const bLayer = createRDFontLayer("4", style, Color.Black); + cpbLayer.style.left = `${2 * style.scale}px`; + cpbLayer.style.top = `${9 * style.scale}px`; + bLayer.style.left = `${8 * style.scale}px`; + bLayer.style.top = `${14 * style.scale}px`; + addLayers([ + iconLayer2, + cpbLayer, + bLayer + ]); + } + break; + case EventType.SetForeground: + { + const iconLayer2 = createLayer(key, null, null, style); + const images = obj.image ?? []; + const imagePath = images.length > 0 ? images[0] : ""; + const contentInfo = slices.get(`${key}_1`); + const colorLayer = imagePath ? createLayer(`${key}_0`, null, Color.Black, style) : null; + const contentLayer = imagePath ? createLayer("", contentInfo?.bounds ? new Rect(contentInfo?.bounds.size) : null, null, style) : null; + if (contentLayer) { + contentLayer.style.backgroundImage = `url(${imagePath})`; + contentLayer.style.left = `${-(contentInfo?.pivot.x ?? 0) * style.scale}px`; + contentLayer.style.top = `${-(contentInfo?.pivot.y ?? 0) * style.scale}px`; + } + addLayers([ + iconLayer2, + colorLayer, + contentLayer + ]); + } + break; default: - const layer = document.createElement("div"); - layer.style.position = "absolute"; - layer.style.left = "0"; - layer.style.top = "0"; - layer.style.width = `${info.bounds.width * style.scale}px`; - layer.style.height = `${info.bounds.height * style.scale}px`; - layer.style.backgroundSize = `${info.bounds.width * style.scale}px ${info.bounds.height * style.scale}px`; - layer.style.backgroundImage = `url(${info.blobUrl})`; - element.appendChild(layer); + const layer = createLayer(key, null, null, style); + addLayers([ + layer + ]); break; } break; } + if (evinfo.isDurationEvent) { + const duration = obj[evinfo.durationKey] ?? 0; + const durWidth = iconSize * duration; + const durationLayer = durWidth > info.bounds.width ? createLayer(evbarea, new Rect(info.bounds.width, 0, durWidth - info.bounds.width, info.bounds.height), colorOf(obj.tab ?? evinfo.defaultTab), style) : null; + if (durationLayer) { + durationLayer.style.pointerEvents = "none"; + layerHoverInit(durationLayer); + } + addLayers([ + durationLayer + ]); + } + const rooms = obj.rooms ?? []; + const roomEnabled = new Color(4292392977); + const roomDisabled = new Color(4284177243); + if (evinfo.isRoomEvent) { + const roomLayers = []; + for (let i = 0; i < 4; i++) { + const roomLayer = createLayer(`room_${i}`, new Point(iconSize, 0), rooms.indexOf(i) > -1 ? roomEnabled : roomDisabled, style); + if (roomLayer) { + layerHoverInit(roomLayer); + } + roomLayers.push(roomLayer); + } + const roomTopLayer = rooms.indexOf(4) > -1 ? createLayer(`room_top`, new Point(iconSize, 0), roomEnabled, style) : null; + if (roomTopLayer) { + layerHoverInit(roomTopLayer); + } + roomLayers.push(roomTopLayer); + addLayers(roomLayers); + } + const condition = obj.if ?? ""; + if (condition.length > 0) { + const positive = /(? { style2 = { ...style2 diff --git a/script/assets.png b/script/assets.png deleted file mode 100644 index e4d0538..0000000 Binary files a/script/assets.png and /dev/null differ diff --git a/script/rdview2.js b/script/rdview2.js deleted file mode 100644 index a3f2c52..0000000 --- a/script/rdview2.js +++ /dev/null @@ -1,143 +0,0 @@ -import { Extensions, IconStyle } from "/script/Extensions.js"; -function rend() { - const codeBlocks = document.querySelectorAll("canvas.rdview2-canvas"); - codeBlocks.forEach((block) => { - // 清理旧的实例 - if (block.cleanup) { - block.cleanup(); - } - - const width = block.getAttribute("data-width") || 8; - const height = block.getAttribute("data-height") || 4; - const scale = block.getAttribute("data-scale") || 2; - const data = block.getAttribute("data"); - const ctx = block.getContext("2d", { alpha: false, desynchronized: true }); - block.width = width * scale * 14; - block.height = height * scale * 14; - if (!data) { - return; - } - const jsonData = JSON.parse(`[${JSON.parse(data)}]`); - - let lastActive = false; - let evtId = 0; - let frameId = null; - let cachedRect = null; - let mdown = false; - - const eventPositions = jsonData.map(evt => ({ - evt, - x: ((evt.beat ?? 1) - 1) * scale * 14, - y: (evt.y ?? 0) * scale * 14 - })); - - const style = new IconStyle(); - style.Scale = scale; - - const updateRect = () => { - cachedRect = block.getBoundingClientRect(); - }; - updateRect(); - - let rectTimeout; - const debouncedUpdateRect = () => { - clearTimeout(rectTimeout); - rectTimeout = setTimeout(updateRect, 100); - }; - - const observer = new ResizeObserver(debouncedUpdateRect); - observer.observe(block); - - window.addEventListener("resize", debouncedUpdateRect, { passive: true }); - window.addEventListener("scroll", debouncedUpdateRect, { passive: true }); - - block.render = (x, y, active) => { - const point = { x, y }; - let currentEvtId = null; - for (let i = 0; i < eventPositions.length; i++) { - const { evt } = eventPositions[i]; - if (evt.area?.contains(point)) { - currentEvtId = i; - break; - } - } - - if (currentEvtId === evtId && active === lastActive) { - return; - } - evtId = currentEvtId; - lastActive = active; - - ctx.clearRect(0, 0, block.width, block.height); - - for (const { evt, x: posX, y: posY } of eventPositions) { - const isHovered = evt.area?.contains(point) ?? false; - style.Hover = isHovered; - style.Active = isHovered ? active : false; - evt.area = Extensions.DrawEventIcon(ctx, evt, { x: posX, y: posY }, style); - } - } - - const throttledRender = (x, y, active) => { - if (frameId !== null) { - return; - } - frameId = requestAnimationFrame(() => { - block.render(x, y, active); - frameId = null; - }); - } - - const getMousePos = (e) => ({ - x: e.clientX - cachedRect.left, - y: e.clientY - cachedRect.top - }); - - block.addEventListener("mousemove", (e) => { - const { x, y } = getMousePos(e); - console.log(x, y); - throttledRender(x, y, mdown); - }, { passive: true }); - - block.addEventListener("mousedown", (e) => { - const { x, y } = getMousePos(e); - mdown = true; - block.render(x, y, mdown); - }); - - block.addEventListener("mouseup", (e) => { - const { x, y } = getMousePos(e); - mdown = false; - block.render(x, y, mdown); - }); - - block.addEventListener("mouseleave", () => { - if (frameId !== null) { - cancelAnimationFrame(frameId); - frameId = null; - } - mdown = false; - evtId = null; - lastActive = false; - block.render(-1, -1, mdown); - }, { passive: true }); - - block.cleanup = () => { - observer.disconnect(); - window.removeEventListener("resize", debouncedUpdateRect); - window.removeEventListener("scroll", debouncedUpdateRect); - clearTimeout(rectTimeout); - if (frameId !== null) { - cancelAnimationFrame(frameId); - } - }; - - block.render(-1, -1, mdown); - }); -} - -window.$docsify.plugins = [].concat(window.$docsify.plugins, function (hook) { - hook.doneEach(function () { - rend(); - }); -}); diff --git a/script/special.js b/script/special.js index aeddffd..1bf3445 100644 --- a/script/special.js +++ b/script/special.js @@ -311,17 +311,10 @@ function rdview2() { number.innerHTML = lineDoms.join(""); } function initCanvas() { - // const lang = textarea.value.split('\n')[0] - // const code = textarea.value.split('\n').slice(1).join('\n') - // rdcanvas.innerHTML = RDViewRender(lang, code) - // try { - // JSON.parse(`[${textarea.value}]`); - // } catch (e) { - // rdcanvas.innerHTML = `
JSON解析错误:${e.message}
`; - // } let objs = []; try { objs = JSON.parse(`[${textarea.value}]`); + rdcanvas.innerHTML = ""; } catch (e) { rdcanvas.innerHTML = `
JSON解析错误:${e.message}
`; @@ -376,7 +369,6 @@ function rdview2() { } } } - //rdcanvas.innerHTML = RDView2Render(json); initCanvas(); initLineNumbers(); textarea.addEventListener("input", initLineNumbers);