[RDView2] DOM 渲染基本完工,进入可行性测试阶段

This commit is contained in:
OLDREDSTONE 2026-01-14 22:20:06 +08:00
parent 76b48c3b95
commit d125e827f3
6 changed files with 483 additions and 1416 deletions

View File

@ -19,8 +19,8 @@
<link rel="stylesheet" href="/style/special.css">
</head>
<body style="background-color: #1f1f1f;">
<div id="app" style="color: white;">加载中...</div>
<body>
<div id="app">加载中...</div>
<script>
$docsify = {
name: "节奏医生编辑器教程",

File diff suppressed because it is too large Load Diff

View File

@ -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 = /(?<!~)\d(?!$)/g.test(condition);
const negative = /~\d(?!$)/g.test(condition);
const conditionLayer = createLayer(evtag, null, positive ? negative ? new Color(4294967040) : new Color(4278255615) : negative ? new Color(4294901760) : null, style);
addLayers([
conditionLayer
]);
}
const tagLayer = obj.tag ? createLayer(`${evtag}_0`, new Point(0, info.bounds.height), new Color(4294952838), style) : null;
addLayers([
tagLayer
]);
switch (evttype) {
case EventType.Comment:
addLayers([
createHintLayer(obj.text ?? "", info.bounds.width * style.scale, new Color(obj.color ?? "7d7d7d"))
]);
break;
case EventType.FloatingText:
case EventType.AdvanceText:
case EventType.ShowStatusSign:
case EventType.TextExplosion:
case EventType.ShowDialogue:
case EventType.ReadNarration:
case EventType.RenameWindow:
addLayers([
createHintLayer(obj.text ?? "", info.bounds.width * style.scale, colorOf(obj.tab ?? evinfo.defaultTab))
]);
break;
case EventType.PlaySong:
addLayers([
createHintLayer(obj.song?.filename ?? "", info.bounds.width * style.scale, colorOf(obj.tab ?? evinfo.defaultTab))
]);
break;
case EventType.CallCustomMethod:
addLayers([
createHintLayer(obj.methodName ?? "", info.bounds.width * style.scale, colorOf(obj.tab ?? evinfo.defaultTab))
]);
break;
case EventType.TagAction:
addLayers([
createHintLayer(obj.Tag ?? "", info.bounds.width * style.scale, colorOf(obj.tab ?? evinfo.defaultTab))
]);
break;
case EventType.PlayAnimation:
case EventType.PlayExpression:
addLayers([
createHintLayer(obj.expression ?? "", info.bounds.width * style.scale, colorOf(obj.tab ?? evinfo.defaultTab))
]);
break;
}
element.onStateChange = (style2) => {
style2 = {
...style2

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -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();
});
});