728 lines
25 KiB
JavaScript
728 lines
25 KiB
JavaScript
import { createElementEvent } from "./rdtkview.js";
|
|
function loadRDView() {
|
|
window.RDViewRender = RDViewRender;
|
|
}
|
|
class Color {
|
|
constructor(red, green, blue, alpha) {
|
|
this.red = red;
|
|
this.green = green;
|
|
this.blue = blue;
|
|
this.alpha = alpha;
|
|
}
|
|
;
|
|
}
|
|
var EventCondition;
|
|
(function (EventCondition) {
|
|
EventCondition["true"] = "true";
|
|
EventCondition["false"] = "false";
|
|
EventCondition["both"] = "both";
|
|
})(EventCondition || (EventCondition = {}));
|
|
class RDViewWindow {
|
|
constructor() {
|
|
this.Row = 4;
|
|
this.Column = 8;
|
|
this.Scale = 1;
|
|
}
|
|
}
|
|
class RDEvent {
|
|
constructor() {
|
|
this.Name = "";
|
|
this.PrefixTab = undefined;
|
|
this.Properties = [];
|
|
this.Style = { Beat: 0, Y: 0 };
|
|
}
|
|
}
|
|
class RDStyle {
|
|
constructor() {
|
|
this.Beat = 0;
|
|
this.Y = 0;
|
|
}
|
|
}
|
|
class RDGroup {
|
|
constructor() {
|
|
this.Width = 1;
|
|
this.Height = 1;
|
|
this.Outline = new Color(255, 0, 0, 255);
|
|
this.Style = new RDStyle();
|
|
this.ClickStyle = new RDStyle();
|
|
this.Children = [];
|
|
}
|
|
}
|
|
function RDViewRender(lang, code) {
|
|
const view = new RDViewWindow();
|
|
var objs = [];
|
|
try {
|
|
objs = ReadObjs(code);
|
|
}
|
|
catch (error) {
|
|
return ErrorElement(`${error}`);
|
|
}
|
|
const args = lang.split(/\s+/g);
|
|
if (1 < args.length && args.length <= 4) {
|
|
if (args[1]) {
|
|
view.Column = parseInt(args[1]);
|
|
}
|
|
if (args[2]) {
|
|
view.Row = parseInt(args[2]);
|
|
}
|
|
if (args[3]) {
|
|
view.Scale = parseFloat(args[3]);
|
|
}
|
|
}
|
|
return ConstructObjs(view, objs);
|
|
}
|
|
function ErrorElement(message = "") {
|
|
const el = document.createElement("div");
|
|
el.className = "rdtk-error";
|
|
el.textContent = message;
|
|
return el;
|
|
}
|
|
function PrefixToTab(prefix) {
|
|
switch (prefix) {
|
|
case "es": return "Sounds";
|
|
case "eb": return "Rows";
|
|
case "ea": return "Actions";
|
|
case "ed": return "Sprites";
|
|
case "er": return "Rooms";
|
|
case "ec": return "Unknown";
|
|
default: return undefined;
|
|
}
|
|
}
|
|
function ReadObjs(line) {
|
|
const objs = [];
|
|
var reader = new Reader(line);
|
|
while (!reader.IsEnd()) {
|
|
var event;
|
|
var name = "";
|
|
var prefix = "";
|
|
try {
|
|
name = reader.ReadSymbol();
|
|
if (reader.TestRead('.', false)) {
|
|
prefix = name;
|
|
name = reader.ReadSymbol();
|
|
}
|
|
}
|
|
catch (e) {
|
|
name = "";
|
|
}
|
|
if (name.toLowerCase() === 'g') {
|
|
event = new RDGroup();
|
|
}
|
|
else {
|
|
const ev = new RDEvent();
|
|
ev.Name = name;
|
|
ev.PrefixTab = PrefixToTab(prefix);
|
|
event = ev;
|
|
}
|
|
if (event instanceof RDEvent) {
|
|
try {
|
|
event.Style.Beat = reader.ReadFloat();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.Style.Y = reader.ReadInt();
|
|
}
|
|
catch (e) { }
|
|
if (reader.TestPeek('[')) {
|
|
const pairString = reader.ReadQuoted('[', ']');
|
|
const keyvalues = new Reader(pairString, reader).ReadPairs();
|
|
ReadProperties(reader, event, keyvalues);
|
|
}
|
|
reader.TestRead(';', true);
|
|
}
|
|
else if (event instanceof RDGroup) {
|
|
try {
|
|
event.Style.Beat = reader.ReadFloat();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.Style.Y = reader.ReadInt();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.Width = reader.ReadFloat();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.Height = reader.ReadInt();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.Outline = reader.ReadColor();
|
|
}
|
|
catch (e) { }
|
|
if (reader.TestPeek('[')) {
|
|
const pairString = reader.ReadQuoted('[', ']');
|
|
const keyvalues = new Reader(pairString, reader).ReadPairs();
|
|
ReadProperties(reader, event, keyvalues);
|
|
}
|
|
if (reader.TestPeek('{')) {
|
|
const pairString = reader.ReadQuoted('{', '}');
|
|
const objs2 = ReadObjs(pairString);
|
|
event.Children = objs2;
|
|
}
|
|
reader.TestRead(';', true);
|
|
}
|
|
objs.push(event);
|
|
}
|
|
return objs;
|
|
}
|
|
function IsEmptyOrSpace(string) {
|
|
return (string) ? /\s/.test(string) : false;
|
|
}
|
|
class Reader {
|
|
constructor(string, reader = undefined) {
|
|
this.position = 0;
|
|
this.line = 0;
|
|
this.offl = 0;
|
|
this.offp = 0;
|
|
this.string = string;
|
|
if (reader) {
|
|
this.offl = reader.line;
|
|
this.offp = reader.position;
|
|
}
|
|
}
|
|
;
|
|
IsEnd() {
|
|
this.JumpSpace();
|
|
return this.position >= this.string.length;
|
|
}
|
|
JumpSpace() {
|
|
while (IsEmptyOrSpace(this.string[this.position])) {
|
|
if (this.string[this.position] === '\n') {
|
|
this.line++;
|
|
}
|
|
this.position++;
|
|
}
|
|
}
|
|
Peek() {
|
|
this.JumpSpace();
|
|
return this.string[this.position];
|
|
}
|
|
TestPeek(str, allowThrow = false) {
|
|
this.JumpSpace();
|
|
var c = this.string.substring(this.position, this.position + str.length);
|
|
if (c === str) {
|
|
return true;
|
|
}
|
|
else {
|
|
if (allowThrow) {
|
|
throw new Error(`Expecting a string '${str}' but got '${c}': ${this.GetPositionDescription()}.`);
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
TestRead(str, allowThrow = false) {
|
|
this.JumpSpace();
|
|
var c = this.string.substring(this.position, this.position + str.length);
|
|
if (c === str) {
|
|
this.position++;
|
|
return true;
|
|
}
|
|
else {
|
|
if (allowThrow) {
|
|
throw new Error(`Expecting a char '${str}' but got '${c}': ${this.GetPositionDescription()}.`);
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
ReadChar() {
|
|
var c = this.string[this.position];
|
|
if (c === '\n') {
|
|
this.line++;
|
|
}
|
|
this.position++;
|
|
return c;
|
|
}
|
|
ReadSymbol() {
|
|
var _a;
|
|
this.JumpSpace();
|
|
var name = (_a = this.string.substring(this.position).match(/^\w+/)) === null || _a === void 0 ? void 0 : _a[0];
|
|
if (name) {
|
|
this.position += name.length;
|
|
return name;
|
|
}
|
|
throw new Error(`Expecting a key but missing: ${this.GetPositionDescription()}.`);
|
|
}
|
|
ReadColor() {
|
|
var _a;
|
|
this.JumpSpace();
|
|
var color = (_a = this.string.substring(this.position).match(/^#[0-9A-Fa-f]{3}([0-9A-Fa-f]{1}([0-9A-Fa-f]{2}([0-9A-Fa-f]{2})?)?)?/)) === null || _a === void 0 ? void 0 : _a[0].substring(1);
|
|
if (!color) {
|
|
throw new Error(`Expecting a color but missing: ${this.GetPositionDescription()}`);
|
|
}
|
|
var result;
|
|
switch (color.length) {
|
|
case 3:
|
|
result = new Color(parseInt(color.substring(0, 1), 16) * 16, parseInt(color.substring(1, 2), 16) * 16, parseInt(color.substring(2, 3), 16) * 16, 255);
|
|
break;
|
|
case 4:
|
|
result = new Color(parseInt(color.substring(0, 1), 16) * 16, parseInt(color.substring(1, 2), 16) * 16, parseInt(color.substring(2, 3), 16) * 16, parseInt(color.substring(3, 4), 16) * 16);
|
|
break;
|
|
case 6:
|
|
result = new Color(parseInt(color.substring(0, 2), 16), parseInt(color.substring(2, 4), 16), parseInt(color.substring(4, 6), 16), 255);
|
|
break;
|
|
case 8:
|
|
result = new Color(parseInt(color.substring(0, 2), 16), parseInt(color.substring(2, 4), 16), parseInt(color.substring(4, 6), 16), parseInt(color.substring(6, 8), 16));
|
|
break;
|
|
default:
|
|
result = new Color(255, 0, 0, 255);
|
|
break;
|
|
}
|
|
this.position += color.length + 1;
|
|
return result;
|
|
}
|
|
ReadInt() {
|
|
var _a;
|
|
this.JumpSpace();
|
|
var name = (_a = this.string.substring(this.position).match(/^[+-]?[0-9]+/)) === null || _a === void 0 ? void 0 : _a[0];
|
|
if (name) {
|
|
this.position += name.length;
|
|
return parseInt(name);
|
|
}
|
|
throw new Error(`Expecting an int but missing: ${this.GetPositionDescription()}.`);
|
|
}
|
|
ReadFloat() {
|
|
var _a;
|
|
this.JumpSpace();
|
|
var name = (_a = this.string.substring(this.position).match(/^[+-]?([0-9]*[.])?[0-9]+/)) === null || _a === void 0 ? void 0 : _a[0];
|
|
if (name) {
|
|
this.position += name.length;
|
|
return parseFloat(name);
|
|
}
|
|
throw new Error(`Expecting a float but missing: ${this.GetPositionDescription()}.`);
|
|
}
|
|
ReadPairs(separator = ',', equals = '=') {
|
|
var pairs = [];
|
|
var flag = !this.IsEnd();
|
|
while (flag) {
|
|
if (this.IsEnd()) {
|
|
break;
|
|
}
|
|
const index = this.position + this.offp;
|
|
const name = this.ReadSymbol();
|
|
this.TestRead(equals, true);
|
|
const value = this.ReadWhileNotEnd([separator]);
|
|
pairs.push({ Key: name, Value: value, Index: index });
|
|
if (flag = !this.IsEnd()) {
|
|
this.TestRead(separator, true);
|
|
}
|
|
}
|
|
return pairs;
|
|
}
|
|
ReadWhileNotEnd(ends = [',', ']']) {
|
|
var str = '';
|
|
while (!(this.position >= this.string.length) && !ends.find(i => this.string.startsWith(i, this.position))) {
|
|
str += this.string[this.position];
|
|
this.position++;
|
|
}
|
|
return str.trim();
|
|
}
|
|
ReadQuoted(left, right) {
|
|
this.JumpSpace();
|
|
var level = 0;
|
|
var result = '';
|
|
if (this.string.startsWith(left, this.position)) {
|
|
level++;
|
|
this.position += left.length;
|
|
}
|
|
else {
|
|
throw new Error(`Cannot find the left half "${left}": ${this.GetPositionDescription()}`);
|
|
}
|
|
while (!(this.position >= this.string.length) && level > 0) {
|
|
if (this.string.startsWith(left, this.position)) {
|
|
level++;
|
|
this.position += left.length;
|
|
result += left;
|
|
}
|
|
if (this.string.startsWith(right, this.position)) {
|
|
level--;
|
|
this.position += right.length;
|
|
if (level === 0) {
|
|
return result;
|
|
}
|
|
else {
|
|
result += right;
|
|
}
|
|
}
|
|
result += this.string[this.position];
|
|
this.position++;
|
|
}
|
|
throw new Error(`Cannot find the right half "${right}": ${this.GetPositionDescription()}`);
|
|
}
|
|
GetPositionDescription(position = undefined) {
|
|
const s = this.string.split('\n');
|
|
var curp = this.offp;
|
|
var line = this.offl;
|
|
if (position !== undefined) {
|
|
while (curp + s[line].length + 1 < position - this.offp) {
|
|
curp += s[line].length + 1;
|
|
line += 1;
|
|
}
|
|
}
|
|
else {
|
|
curp += s.slice(0, this.line).reduce((sum, i) => sum + i.length + 1, 0);
|
|
line += this.line;
|
|
position = this.position;
|
|
}
|
|
return `<br>at "${s[line]}".`;
|
|
}
|
|
}
|
|
function FindValue(pairs, key) {
|
|
const finded = pairs.find(i => i.Key === key);
|
|
if (finded) {
|
|
return finded;
|
|
}
|
|
return undefined;
|
|
}
|
|
function ReadProperties(reader, event, pairs) {
|
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
if (event instanceof RDGroup) {
|
|
var value;
|
|
if (value = FindValue(pairs, "hue")) {
|
|
event.Style.Hue = parseFloat(value.Value);
|
|
}
|
|
if (value = FindValue(pairs, "brightness")) {
|
|
event.Style.Brightness = parseFloat(value.Value);
|
|
}
|
|
if (value = FindValue(pairs, "grayscale")) {
|
|
event.Style.Grayscale = parseFloat(value.Value);
|
|
}
|
|
if (value = FindValue(pairs, "opacity")) {
|
|
event.Style.Opacity = parseFloat(value.Value);
|
|
}
|
|
if (value = FindValue(pairs, "offset")) {
|
|
reader = new Reader(value.Value);
|
|
(_a = event.ClickStyle) !== null && _a !== void 0 ? _a : (event.ClickStyle = new RDStyle());
|
|
try {
|
|
event.ClickStyle.Beat = reader.ReadFloat();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.ClickStyle.Y = reader.ReadInt();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.ClickOutline = reader.ReadColor();
|
|
}
|
|
catch (e) { }
|
|
}
|
|
if (value = FindValue(pairs, "offset_hue")) {
|
|
(_b = event.ClickStyle) !== null && _b !== void 0 ? _b : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Hue = parseFloat(value.Value);
|
|
}
|
|
if (value = FindValue(pairs, "offset_brightness")) {
|
|
(_c = event.ClickStyle) !== null && _c !== void 0 ? _c : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Brightness = parseFloat(value.Value);
|
|
}
|
|
if (value = FindValue(pairs, "offset_grayscale")) {
|
|
(_d = event.ClickStyle) !== null && _d !== void 0 ? _d : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Grayscale = parseFloat(value.Value);
|
|
}
|
|
if (value = FindValue(pairs, "offset_opacity")) {
|
|
(_e = event.ClickStyle) !== null && _e !== void 0 ? _e : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Opacity = parseFloat(value.Value);
|
|
}
|
|
}
|
|
else if (event instanceof RDEvent) {
|
|
for (const pair of pairs) {
|
|
const key = pair.Key;
|
|
const value = pair.Value;
|
|
switch (key) {
|
|
case "if":
|
|
if (["true", "false", "both"].find(i => i === value)) {
|
|
event.Condition = value === "true" ? EventCondition.true :
|
|
value === "false" ? EventCondition.false : EventCondition.both;
|
|
}
|
|
else {
|
|
throw new Error(`Expecting "true", "false" or "both", but find "${value}".`);
|
|
}
|
|
break;
|
|
case "tag":
|
|
event.Tag = value === "true";
|
|
break;
|
|
case "hue":
|
|
event.Style.Hue = parseFloat(value);
|
|
break;
|
|
case "brightness":
|
|
event.Style.Brightness = parseFloat(value);
|
|
break;
|
|
case "grayscale":
|
|
event.Style.Grayscale = parseFloat(value);
|
|
break;
|
|
case "opacity":
|
|
event.Style.Opacity = parseFloat(value);
|
|
break;
|
|
case "offset": {
|
|
const offsetReader = new Reader(value);
|
|
(_f = event.ClickStyle) !== null && _f !== void 0 ? _f : (event.ClickStyle = new RDStyle());
|
|
try {
|
|
event.ClickStyle.Beat = offsetReader.ReadFloat();
|
|
}
|
|
catch (e) { }
|
|
try {
|
|
event.ClickStyle.Y = offsetReader.ReadInt();
|
|
}
|
|
catch (e) { }
|
|
break;
|
|
}
|
|
case "offset_hue":
|
|
(_g = event.ClickStyle) !== null && _g !== void 0 ? _g : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Hue = parseFloat(value);
|
|
break;
|
|
case "offset_brightness":
|
|
(_h = event.ClickStyle) !== null && _h !== void 0 ? _h : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Brightness = parseFloat(value);
|
|
break;
|
|
case "offset_grayscale":
|
|
(_j = event.ClickStyle) !== null && _j !== void 0 ? _j : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Grayscale = parseFloat(value);
|
|
break;
|
|
case "offset_opacity":
|
|
(_k = event.ClickStyle) !== null && _k !== void 0 ? _k : (event.ClickStyle = new RDStyle());
|
|
event.ClickStyle.Opacity = parseFloat(value);
|
|
break;
|
|
default:
|
|
event.Properties.push(pair);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const CELL_SIZE = 28;
|
|
const RDTK_SCALE = 2;
|
|
const NUMERIC_KEYS = new Set([
|
|
"tick", "swing", "hold", "pulse", "customPulse", "interval", "delay", "loop",
|
|
"subdivision", "crotchetsPerBar", "syncoBeat", "duration", "angle", "bpm",
|
|
"beatsPerMinute", "volume", "speed", "startOpacity", "endOpacity", "subdivOffset",
|
|
]);
|
|
const SAY_PHRASES = new Set([
|
|
"SayReaDyGetSetGoNew", "SayReaDyGetSetOne", "SayGetSetGo", "SayGetSetOne",
|
|
"JustSayRea", "JustSayDy", "JustSayGet", "JustSaySet", "JustSayAnd",
|
|
"JustSayGo", "JustSayStop", "JustSayAndStop", "SaySwitch", "SayWatch",
|
|
"SayListen", "Count1", "Count2", "Count3", "Count4", "Count5", "Count6",
|
|
"Count7", "Count8", "Count9", "Count10", "SayReadyGetSetGo", "JustSayReady",
|
|
]);
|
|
function CoerceValue(key, value) {
|
|
if (value === "true") {
|
|
return true;
|
|
}
|
|
if (value === "false") {
|
|
return false;
|
|
}
|
|
if (NUMERIC_KEYS.has(key) && /^[+-]?(\d+(\.\d+)?|\.\d+)$/.test(value)) {
|
|
return Number(value);
|
|
}
|
|
return value;
|
|
}
|
|
function ToRDtkObject(ev) {
|
|
const obj = { type: ev.Name };
|
|
let tab = undefined;
|
|
for (const pair of ev.Properties) {
|
|
let key = pair.Key;
|
|
const value = pair.Value;
|
|
if (key === "tab") {
|
|
tab = value;
|
|
continue;
|
|
}
|
|
if (key === "tag") {
|
|
continue;
|
|
}
|
|
if (ev.Name === "AddOneshotBeat" && key === "type") {
|
|
const types = value.split(/\s+/).filter(i => i.length > 0);
|
|
for (const t of types) {
|
|
switch (t) {
|
|
case "freezeshot":
|
|
obj.freezeBurnMode = "Freezeshot";
|
|
break;
|
|
case "burnshot":
|
|
obj.freezeBurnMode = "Burnshot";
|
|
break;
|
|
case "skipshot":
|
|
obj.skipshot = true;
|
|
break;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
if (ev.Name === "AddOneshotBeat" && key === "hold") {
|
|
obj.hold = !(value === "false" || value === "0" || value === "0.0");
|
|
continue;
|
|
}
|
|
if (key === "rowxs") {
|
|
key = "pattern";
|
|
}
|
|
else if (ev.Name === "AddOneshotBeat" && key === "loop") {
|
|
key = "loops";
|
|
}
|
|
else if (ev.Name === "AddOneshotBeat" && key === "subdivision") {
|
|
key = "subdivisions";
|
|
}
|
|
if (ev.Name === "SayReadyGetSetGo" && key === "phraseToSay") {
|
|
if (SAY_PHRASES.has(value)) {
|
|
obj.phraseToSay = value;
|
|
}
|
|
continue;
|
|
}
|
|
obj[key] = CoerceValue(key, value);
|
|
}
|
|
if (tab !== undefined) {
|
|
obj.tab = tab;
|
|
}
|
|
else if (ev.PrefixTab !== undefined) {
|
|
obj.tab = ev.PrefixTab;
|
|
}
|
|
if (ev.Tag === true) {
|
|
obj.tag = true;
|
|
}
|
|
return obj;
|
|
}
|
|
function ConstructObjs(view, objs) {
|
|
const content = document.createElement("div");
|
|
content.className = "RDViewContent";
|
|
content.style.setProperty("--column", `${view.Column}`);
|
|
content.style.setProperty("--row", `${view.Row}`);
|
|
content.style.setProperty("--scale", `${view.Scale}`);
|
|
const canvas = document.createElement("div");
|
|
canvas.className = "RDView rdtk-rdview";
|
|
canvas.style.setProperty("--column", `${view.Column}`);
|
|
canvas.style.setProperty("--row", `${view.Row}`);
|
|
canvas.style.setProperty("--scale", `${view.Scale}`);
|
|
for (const obj of objs) {
|
|
const node = BuildObject(obj);
|
|
if (node) {
|
|
canvas.appendChild(node);
|
|
}
|
|
}
|
|
content.appendChild(canvas);
|
|
return content;
|
|
}
|
|
function BuildObject(obj) {
|
|
return obj instanceof RDGroup ? BuildGroup(obj) : BuildEvent(obj);
|
|
}
|
|
function BuildEvent(ev) {
|
|
var _a, _b, _c, _d;
|
|
const wrapper = document.createElement("div");
|
|
wrapper.className = "rdtk-event";
|
|
wrapper.style.left = `${ev.Style.Beat * CELL_SIZE}px`;
|
|
wrapper.style.top = `${ev.Style.Y * CELL_SIZE}px`;
|
|
const state = { enabled: true, active: false, hover: false, scale: RDTK_SCALE, showDuration: false };
|
|
const rdobj = ToRDtkObject(ev);
|
|
const inner = rdobj ? createElementEvent(rdobj, state) : null;
|
|
if (inner) {
|
|
inner.style.position = "absolute";
|
|
inner.style.left = "0px";
|
|
inner.style.top = "0px";
|
|
wrapper.appendChild(inner);
|
|
}
|
|
else {
|
|
wrapper.classList.add("rdtk-unknown");
|
|
wrapper.textContent = ev.Name || "unknown";
|
|
}
|
|
ApplyFilter(wrapper, ev.Style);
|
|
if (ev.Condition !== undefined) {
|
|
const condition = document.createElement("div");
|
|
condition.className = `rdtk-condition condition-${ev.Condition}`;
|
|
wrapper.appendChild(condition);
|
|
}
|
|
const offsetBeat = (_b = (_a = ev.ClickStyle) === null || _a === void 0 ? void 0 : _a.Beat) !== null && _b !== void 0 ? _b : 0;
|
|
const offsetY = (_d = (_c = ev.ClickStyle) === null || _c === void 0 ? void 0 : _c.Y) !== null && _d !== void 0 ? _d : 0;
|
|
const hasOffset = offsetBeat !== 0 || offsetY !== 0;
|
|
function setState(hover, active) {
|
|
state.hover = hover;
|
|
state.active = active;
|
|
inner === null || inner === void 0 ? void 0 : inner.onStateChange(state);
|
|
wrapper.classList.toggle("hover", hover);
|
|
wrapper.classList.toggle("active", active);
|
|
wrapper.style.transform = (active && hasOffset)
|
|
? `translate(${offsetBeat * CELL_SIZE}px, ${offsetY * CELL_SIZE}px)`
|
|
: "";
|
|
ApplyFilter(wrapper, active && ev.ClickStyle ? ev.ClickStyle : ev.Style);
|
|
}
|
|
wrapper.addEventListener("mouseover", (e) => {
|
|
if (!wrapper.contains(e.relatedTarget)) {
|
|
setState(true, state.active);
|
|
}
|
|
});
|
|
wrapper.addEventListener("mouseout", (e) => {
|
|
if (!wrapper.contains(e.relatedTarget)) {
|
|
setState(false, false);
|
|
}
|
|
});
|
|
wrapper.addEventListener("mousedown", () => setState(true, true));
|
|
wrapper.addEventListener("mouseup", () => setState(state.hover, false));
|
|
wrapper.__setRDtkState = setState;
|
|
return wrapper;
|
|
}
|
|
function BuildGroup(grp) {
|
|
var _a, _b, _c, _d;
|
|
const wrapper = document.createElement("div");
|
|
wrapper.className = "rdtk-group";
|
|
wrapper.style.left = `${grp.Style.Beat * CELL_SIZE}px`;
|
|
wrapper.style.top = `${grp.Style.Y * CELL_SIZE}px`;
|
|
wrapper.style.width = `${grp.Width * CELL_SIZE}px`;
|
|
wrapper.style.height = `${grp.Height * CELL_SIZE}px`;
|
|
wrapper.style.outlineColor = ToHex(grp.Outline);
|
|
ApplyFilter(wrapper, grp.Style);
|
|
for (const child of grp.Children) {
|
|
const node = BuildObject(child);
|
|
if (node) {
|
|
wrapper.appendChild(node);
|
|
}
|
|
}
|
|
const offsetBeat = (_b = (_a = grp.ClickStyle) === null || _a === void 0 ? void 0 : _a.Beat) !== null && _b !== void 0 ? _b : 0;
|
|
const offsetY = (_d = (_c = grp.ClickStyle) === null || _c === void 0 ? void 0 : _c.Y) !== null && _d !== void 0 ? _d : 0;
|
|
const hasOffset = offsetBeat !== 0 || offsetY !== 0;
|
|
function setState(hover, active) {
|
|
var _a;
|
|
wrapper.classList.toggle("hover", hover);
|
|
wrapper.classList.toggle("active", active);
|
|
wrapper.style.transform = (active && hasOffset)
|
|
? `translate(${offsetBeat * CELL_SIZE}px, ${offsetY * CELL_SIZE}px)`
|
|
: "";
|
|
wrapper.style.outlineColor = active ? ToHex((_a = grp.ClickOutline) !== null && _a !== void 0 ? _a : grp.Outline) : ToHex(grp.Outline);
|
|
ApplyFilter(wrapper, active && grp.ClickStyle ? grp.ClickStyle : grp.Style);
|
|
}
|
|
wrapper.addEventListener("mouseover", (e) => {
|
|
if (!wrapper.contains(e.relatedTarget)) {
|
|
setState(true, false);
|
|
}
|
|
});
|
|
wrapper.addEventListener("mouseout", (e) => {
|
|
if (!wrapper.contains(e.relatedTarget)) {
|
|
setState(false, false);
|
|
}
|
|
});
|
|
wrapper.addEventListener("mousedown", () => setState(true, true));
|
|
wrapper.addEventListener("mouseup", () => setState(true, false));
|
|
wrapper.__setRDtkState = setState;
|
|
return wrapper;
|
|
}
|
|
function ApplyFilter(el, style) {
|
|
const parts = [];
|
|
if (style.Hue !== undefined) {
|
|
parts.push(`hue-rotate(${style.Hue}deg)`);
|
|
}
|
|
if (style.Brightness !== undefined) {
|
|
parts.push(`brightness(${style.Brightness}%)`);
|
|
}
|
|
if (style.Grayscale !== undefined) {
|
|
parts.push(`grayscale(${style.Grayscale}%)`);
|
|
}
|
|
if (style.Opacity !== undefined) {
|
|
parts.push(`opacity(${style.Opacity}%)`);
|
|
}
|
|
el.style.filter = parts.join(" ");
|
|
}
|
|
function ToHex(color) {
|
|
const hex = parseInt(color.red.toFixed(0)).toString(16).padStart(2, '0') +
|
|
parseInt(color.green.toFixed(0)).toString(16).padStart(2, '0') +
|
|
parseInt(color.blue.toFixed(0)).toString(16).padStart(2, '0') +
|
|
parseInt(color.alpha.toFixed(0)).toString(16).padStart(2, '0');
|
|
return '#' + hex;
|
|
}
|
|
window.loadRDView = loadRDView;
|