From 36e5726eaf40dc4a43c5efab5eca3ee9eb20ad71 Mon Sep 17 00:00:00 2001 From: Lani Aung Date: Sun, 17 Oct 2021 13:24:24 -0600 Subject: [PATCH] Latest --- Models/CelModel.cs | 19 +++-- Models/Coordinate.cs | 2 +- Scripts/function.ts | 24 ------ Scripts/main.ts | 37 +-------- Scripts/pto.ts | 29 +++---- Scripts/tracker.ts | 158 +++++++++++++++++++++++++++++++++++++++ Scripts/utility.ts | 20 ++--- Views/Home/Play.cshtml | 9 ++- fxl.codes.kisekae.csproj | 2 +- 9 files changed, 207 insertions(+), 93 deletions(-) delete mode 100644 Scripts/function.ts create mode 100644 Scripts/tracker.ts diff --git a/Models/CelModel.cs b/Models/CelModel.cs index b9ef193..bfa57eb 100644 --- a/Models/CelModel.cs +++ b/Models/CelModel.cs @@ -15,6 +15,16 @@ namespace fxl.codes.kisekae.Models internal CelModel(ILogger logger, string line) { logger.LogTrace($"Parsing cel line {line}"); + + if (line.Contains("%t")) + { + var opacity = line[line.IndexOf("%t")..].Trim(); + opacity = opacity.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)[0]; + opacity = opacity.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)[0]; + opacity = opacity.Replace("%t", ""); + Opacity = 1.0 - double.Parse(opacity) / 255; + } + var matcher = new Regex(Regex); var match = matcher.Match(line); @@ -26,13 +36,9 @@ namespace fxl.codes.kisekae.Models if (string.IsNullOrEmpty(group?.Value)) { if (string.Equals(groupName, "Sets")) - { for (var index = 0; index < Sets.Length; index++) - { Sets[index] = true; - } - } - + logger.LogWarning($"Unable to find regex group {groupName} in {line}"); continue; } @@ -42,7 +48,7 @@ namespace fxl.codes.kisekae.Models if (property.PropertyType == typeof(int)) property.SetValue(this, int.Parse(value)); if (property.PropertyType != Sets.GetType()) continue; - + foreach (var id in value.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { var success = int.TryParse(id, out var result); @@ -58,6 +64,7 @@ namespace fxl.codes.kisekae.Models public int PaletteId { get; init; } public bool[] Sets { get; } = new bool[10]; public string Comment { get; init; } + public double Opacity { get; } = 1.0; public Coordinate[] InitialPositions { get; } = new Coordinate[10]; [JsonIgnore] public string DefaultImage => ImageByPalette.ContainsKey(PaletteId) ? ImageByPalette[PaletteId] : null; public Coordinate Offset { get; set; } diff --git a/Models/Coordinate.cs b/Models/Coordinate.cs index 6e6c94d..a5b1d1a 100644 --- a/Models/Coordinate.cs +++ b/Models/Coordinate.cs @@ -2,7 +2,7 @@ namespace fxl.codes.kisekae.Models { public class Coordinate { - public Coordinate(int x, int y) + public Coordinate(int x = 0, int y = 0) { X = x; Y = y; diff --git a/Scripts/function.ts b/Scripts/function.ts deleted file mode 100644 index b8f5e8a..0000000 --- a/Scripts/function.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {Playset} from "./pto" - -const cssClass = "active-set" - -export function setPlayArea(header: HTMLElement, container: HTMLElement, playset: Playset, set: number): void { - header.querySelectorAll("button").forEach(button => { - button.classList.remove(cssClass) - }) - - header.querySelector(`button[data-set="${set}"]`).classList.add(cssClass) - let elements = container.querySelectorAll(".cel-image") - - playset.cels.forEach((cel, index) => { - let element = elements[index] as HTMLDivElement - element.style.visibility = "hidden" - - if (cel.sets[set]) { - let position = cel.currentPositions[set] - element.style.visibility = "visible" - element.style.left = `${position.x}px` - element.style.top = `${position.y}px` - } - }) -} \ No newline at end of file diff --git a/Scripts/main.ts b/Scripts/main.ts index 828819f..f29d462 100644 --- a/Scripts/main.ts +++ b/Scripts/main.ts @@ -1,8 +1,8 @@ import {MDCLinearProgress} from "@material/linear-progress" import {MDCRipple} from "@material/ripple" import {MDCTopAppBar} from "@material/top-app-bar" -import {setPlayArea} from "./function" import {Playset} from "./pto" +import Tracker from "./tracker" import Builder from "./utility" declare global { @@ -30,39 +30,10 @@ export default class Main { public load(containerId: string, headerId: string, playset: Playset, set: number = 0): void { let container = document.getElementById(containerId) - let header = document.getElementById(headerId) - let menu = header.querySelector("ul") + let menu = document.getElementById(headerId).querySelector("ul") - let reset = header.querySelector(`button[data-rel="reset"]`) - reset.addEventListener("click", () => { - // TODO reset positions - setPlayArea(header, container, playset, set) - }) - - playset.enabledSets.forEach((enabled, index) => { - if (enabled) { - let button = new Builder("li") - .addChildren(new Builder("button") - .addClass("mdc-button") - .addAttributes({"data-set": index}) - .addChildren( - new Builder("span").addClass("mdc-button__ripple"), - new Builder("span").addClass("mdc-button__label").setText(index.toString()) - )).build() - - button.addEventListener("click", () => { - setPlayArea(header, container, playset, index) - }) - - menu.appendChild(button) - } - }) - - playset.cels.forEach(cel => { - cel.currentPositions = [...cel.initialPositions] - }) - - setPlayArea(header, container, playset, set) + let tracker = new Tracker(playset, menu, container) + tracker.setPlayArea(set) } private init() { diff --git a/Scripts/pto.ts b/Scripts/pto.ts index fa41f17..ce709a5 100644 --- a/Scripts/pto.ts +++ b/Scripts/pto.ts @@ -1,24 +1,25 @@ -export class Playset { - name: string - height: number - width: number - - cels: Cel[] - enabledSets: boolean[] +export interface Playset { + readonly name: string + readonly height: number + readonly width: number + readonly cels: Cel[] + readonly enabledSets: boolean[] } -export class Cel { - defaultImage: string - initialPositions: Coordinate[] - offset: Coordinate - sets: boolean[] +export interface Cel { + readonly id: number + readonly fix: number + readonly initialPositions: Coordinate[] + readonly offset: Coordinate + readonly sets: boolean[] currentPositions: Coordinate[] + currentFix: number } export class Coordinate { - x: number - y: number + readonly x: number + readonly y: number constructor(x: number = 0, y: number = 0) { this.x = x diff --git a/Scripts/tracker.ts b/Scripts/tracker.ts new file mode 100644 index 0000000..4b02550 --- /dev/null +++ b/Scripts/tracker.ts @@ -0,0 +1,158 @@ +import {Cel, Coordinate, Playset} from "./pto" +import Builder from "./utility" + +const cssClass = "active-set" + +export default class Tracker { + set: number = 0 + setPalettes: number[] = [] + + private playset: Playset + private menu: HTMLElement + private playSpace: HTMLElement + private maxFixById: { [key: number]: number } = {} + + constructor(playset: Playset, menu: HTMLElement, playSpace: HTMLElement) { + this.playset = playset + this.menu = menu + this.playSpace = playSpace + + this.addEvents() + this.reset() + this.setMenu() + } + + private static adjustPlacement(cel: Cel, set: number, movement: Coordinate): Coordinate { + let x = cel.currentPositions[set].x + movement.x + let y = cel.currentPositions[set].y + movement.y + cel.currentPositions[set] = new Coordinate(x, y) + + return Tracker.getCoordinate(cel, set) + } + + private static getCoordinate(cel: Cel, set: number): Coordinate { + let position = cel.currentPositions[set] + if (!position) return new Coordinate() + + if (!cel.offset) return position + + return new Coordinate(position.x + cel.offset.x, position.y + cel.offset.y) + } + + setPlayArea(set: number): void { + this.set = set + + this.menu.querySelectorAll("button").forEach(button => { + button.classList.remove(cssClass) + }) + this.menu.querySelector(`button[data-set="${set}"]`).classList.add(cssClass) + + let elements = this.playSpace.querySelectorAll(".cel-image") + this.playset.cels.forEach((cel, index) => { + let element = elements[index] as HTMLDivElement + element.style.visibility = "hidden" + + if (cel.sets[set]) { + element.style.visibility = "visible" + let position = Tracker.getCoordinate(cel, set) + element.style.left = `${position.x}px` + element.style.top = `${position.y}px` + } + }) + } + + private addEvents() { + let previousEvent: MouseEvent | null = null + + let elements = this.playSpace.querySelectorAll(".cel-image") + elements.forEach((element: HTMLElement) => { + let mousemove = (move: MouseEvent) => { + let movement = new Coordinate(move.clientX - previousEvent.clientX, move.clientY - previousEvent.clientY) + previousEvent = move + + let group = this.getGroup(element) + group.forEach((item: HTMLElement) => { + let index = parseInt(item.attributes.getNamedItem("data-index").value) + let cel = this.playset.cels[index] + + if (cel.currentFix == 0) { + let position = Tracker.adjustPlacement(cel, this.set, movement) + item.style.left = `${position.x}px` + item.style.top = `${position.y}px` + } + }) + } + + element.addEventListener("mousedown", (down: MouseEvent) => { + previousEvent = down + this.getGroup(element).forEach(item => { + let index = parseInt(item.attributes.getNamedItem("data-index").value) + let cel = this.playset.cels[index] + + if (cel.currentFix > 0) cel.currentFix-- + }) + + window.addEventListener("mousemove", mousemove) + window.addEventListener("mouseup", () => { + previousEvent = null + window.removeEventListener("mousemove", mousemove) + }) + }) + }) + } + + private getGroup(element: Element): NodeListOf { + let id = element.attributes.getNamedItem("data-id").value + return this.playSpace.querySelectorAll(`.cel-image[data-id="${id}"]`) + } + + private reset(): void { + this.playSpace.querySelectorAll(".cel-image").forEach((element: HTMLElement) => { + element.style.visibility = "hidden" + element.style.left = "0" + element.style.top = "0" + }) + + this.playset.cels.forEach(cel => { + if (!this.maxFixById[cel.id]) { + this.maxFixById[cel.id] = 0 + } + + if (this.maxFixById[cel.id] < cel.fix) { + this.maxFixById[cel.id] = cel.fix + } + }) + + this.playset.cels.forEach(cel => { + cel.currentFix = this.maxFixById[cel.id] + cel.currentPositions = cel.initialPositions.map(position => position ? new Coordinate(position.x, position.y) : null) + }) + } + + private setMenu(): void { + let reset = this.menu.querySelector(`button[data-rel="reset"]`) + reset.addEventListener("click", () => { + this.reset() + this.setPlayArea(this.set) + }) + + this.playset.enabledSets.forEach((enabled, index) => { + if (enabled) { + let button = new Builder("li") + .addChildren(new Builder("button") + .addClass("mdc-button") + .addAttributes({"data-set": index}) + .addChildren( + new Builder("span").addClass("mdc-button__ripple"), + new Builder("span").addClass("mdc-button__label").setText(index.toString()) + )).build() + + button.addEventListener("click", () => { + this.setPlayArea(index) + }) + + this.menu.appendChild(button) + } + }) + } +} \ No newline at end of file diff --git a/Scripts/utility.ts b/Scripts/utility.ts index d72e084..7f78ca5 100644 --- a/Scripts/utility.ts +++ b/Scripts/utility.ts @@ -1,31 +1,31 @@ export default class Builder { element: HTMLElement - + constructor(tag: string) { this.element = document.createElement(tag) } - addAttributes(attributes: {[key: string]: string | number}): Builder { + addAttributes(attributes: { [key: string]: string | number }): Builder { for (let key of Object.keys(attributes)) { this.addAttribute(key, attributes[key]) } - + return this } - + addAttribute(name: string, value: string | number): Builder { let attribute = document.createAttribute(name) attribute.value = value.toString() - + this.element.attributes.setNamedItem(attribute) return this } - + addClass(...classes: string[]): Builder { this.element.classList.add(...classes) return this } - + addChildren(...children: HTMLElement[] | Builder[]): Builder { children.forEach(child => { if (child instanceof HTMLElement) { @@ -34,15 +34,15 @@ export default class Builder { this.element.appendChild(child.build()) } }) - + return this } - + setText(text: string): Builder { this.element.textContent = text return this } - + build(): HTMLElement { return this.element } diff --git a/Views/Home/Play.cshtml b/Views/Home/Play.cshtml index 24a3d2e..ba9eef0 100644 --- a/Views/Home/Play.cshtml +++ b/Views/Home/Play.cshtml @@ -18,12 +18,13 @@
- @foreach (var cel in Model.Cels) + @for (var index = 0; index < Model.Cels.Count; index++) { + var cel = Model.Cels[index];
+ data-index="@index">
}
@@ -32,4 +33,4 @@ -} +} \ No newline at end of file diff --git a/fxl.codes.kisekae.csproj b/fxl.codes.kisekae.csproj index 620ee0b..a34c364 100644 --- a/fxl.codes.kisekae.csproj +++ b/fxl.codes.kisekae.csproj @@ -6,9 +6,9 @@ - +