Latest
This commit is contained in:
+11
-4
@@ -15,6 +15,16 @@ namespace fxl.codes.kisekae.Models
|
|||||||
internal CelModel(ILogger<ConfigurationReaderService> logger, string line)
|
internal CelModel(ILogger<ConfigurationReaderService> logger, string line)
|
||||||
{
|
{
|
||||||
logger.LogTrace($"Parsing cel line {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 matcher = new Regex(Regex);
|
||||||
var match = matcher.Match(line);
|
var match = matcher.Match(line);
|
||||||
|
|
||||||
@@ -26,12 +36,8 @@ namespace fxl.codes.kisekae.Models
|
|||||||
if (string.IsNullOrEmpty(group?.Value))
|
if (string.IsNullOrEmpty(group?.Value))
|
||||||
{
|
{
|
||||||
if (string.Equals(groupName, "Sets"))
|
if (string.Equals(groupName, "Sets"))
|
||||||
{
|
|
||||||
for (var index = 0; index < Sets.Length; index++)
|
for (var index = 0; index < Sets.Length; index++)
|
||||||
{
|
|
||||||
Sets[index] = true;
|
Sets[index] = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.LogWarning($"Unable to find regex group {groupName} in {line}");
|
logger.LogWarning($"Unable to find regex group {groupName} in {line}");
|
||||||
continue;
|
continue;
|
||||||
@@ -58,6 +64,7 @@ namespace fxl.codes.kisekae.Models
|
|||||||
public int PaletteId { get; init; }
|
public int PaletteId { get; init; }
|
||||||
public bool[] Sets { get; } = new bool[10];
|
public bool[] Sets { get; } = new bool[10];
|
||||||
public string Comment { get; init; }
|
public string Comment { get; init; }
|
||||||
|
public double Opacity { get; } = 1.0;
|
||||||
public Coordinate[] InitialPositions { get; } = new Coordinate[10];
|
public Coordinate[] InitialPositions { get; } = new Coordinate[10];
|
||||||
[JsonIgnore] public string DefaultImage => ImageByPalette.ContainsKey(PaletteId) ? ImageByPalette[PaletteId] : null;
|
[JsonIgnore] public string DefaultImage => ImageByPalette.ContainsKey(PaletteId) ? ImageByPalette[PaletteId] : null;
|
||||||
public Coordinate Offset { get; set; }
|
public Coordinate Offset { get; set; }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ namespace fxl.codes.kisekae.Models
|
|||||||
{
|
{
|
||||||
public class Coordinate
|
public class Coordinate
|
||||||
{
|
{
|
||||||
public Coordinate(int x, int y)
|
public Coordinate(int x = 0, int y = 0)
|
||||||
{
|
{
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
|
|||||||
@@ -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`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
+4
-33
@@ -1,8 +1,8 @@
|
|||||||
import {MDCLinearProgress} from "@material/linear-progress"
|
import {MDCLinearProgress} from "@material/linear-progress"
|
||||||
import {MDCRipple} from "@material/ripple"
|
import {MDCRipple} from "@material/ripple"
|
||||||
import {MDCTopAppBar} from "@material/top-app-bar"
|
import {MDCTopAppBar} from "@material/top-app-bar"
|
||||||
import {setPlayArea} from "./function"
|
|
||||||
import {Playset} from "./pto"
|
import {Playset} from "./pto"
|
||||||
|
import Tracker from "./tracker"
|
||||||
import Builder from "./utility"
|
import Builder from "./utility"
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@@ -30,39 +30,10 @@ export default class Main {
|
|||||||
|
|
||||||
public load(containerId: string, headerId: string, playset: Playset, set: number = 0): void {
|
public load(containerId: string, headerId: string, playset: Playset, set: number = 0): void {
|
||||||
let container = document.getElementById(containerId)
|
let container = document.getElementById(containerId)
|
||||||
let header = document.getElementById(headerId)
|
let menu = document.getElementById(headerId).querySelector("ul")
|
||||||
let menu = header.querySelector("ul")
|
|
||||||
|
|
||||||
let reset = header.querySelector(`button[data-rel="reset"]`)
|
let tracker = new Tracker(playset, menu, container)
|
||||||
reset.addEventListener("click", () => {
|
tracker.setPlayArea(set)
|
||||||
// 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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
|
|||||||
+15
-14
@@ -1,24 +1,25 @@
|
|||||||
export class Playset {
|
export interface Playset {
|
||||||
name: string
|
readonly name: string
|
||||||
height: number
|
readonly height: number
|
||||||
width: number
|
readonly width: number
|
||||||
|
readonly cels: Cel[]
|
||||||
cels: Cel[]
|
readonly enabledSets: boolean[]
|
||||||
enabledSets: boolean[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Cel {
|
export interface Cel {
|
||||||
defaultImage: string
|
readonly id: number
|
||||||
initialPositions: Coordinate[]
|
readonly fix: number
|
||||||
offset: Coordinate
|
readonly initialPositions: Coordinate[]
|
||||||
sets: boolean[]
|
readonly offset: Coordinate
|
||||||
|
readonly sets: boolean[]
|
||||||
|
|
||||||
currentPositions: Coordinate[]
|
currentPositions: Coordinate[]
|
||||||
|
currentFix: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Coordinate {
|
export class Coordinate {
|
||||||
x: number
|
readonly x: number
|
||||||
y: number
|
readonly y: number
|
||||||
|
|
||||||
constructor(x: number = 0, y: number = 0) {
|
constructor(x: number = 0, y: number = 0) {
|
||||||
this.x = x
|
this.x = x
|
||||||
|
|||||||
@@ -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<Element> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,12 +18,13 @@
|
|||||||
</header>
|
</header>
|
||||||
<article id="play_area" style="background-color: #@Model.BorderColor">
|
<article id="play_area" style="background-color: #@Model.BorderColor">
|
||||||
<div id="play_space" style="height: @(Model.Height)px; width: @(Model.Width)px">
|
<div id="play_space" style="height: @(Model.Height)px; width: @(Model.Width)px">
|
||||||
@foreach (var cel in Model.Cels)
|
@for (var index = 0; index < Model.Cels.Count; index++)
|
||||||
{
|
{
|
||||||
|
var cel = Model.Cels[index];
|
||||||
<div class="cel-image"
|
<div class="cel-image"
|
||||||
style="background-image: url('data:image/gif;base64,@cel.DefaultImage'); height: @(cel.Height)px; width: @(cel.Width)px; z-index: @cel.ZIndex;"
|
style="background-image: url('data:image/gif;base64,@cel.DefaultImage'); height: @(cel.Height)px; width: @(cel.Width)px; z-index: @cel.ZIndex; opacity: @cel.Opacity"
|
||||||
data-id="@cel.Id"
|
data-id="@cel.Id"
|
||||||
data-fix="@cel.Fix"></div>
|
data-index="@index"></div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<TypeScriptCompile Include="Scripts\function.ts" />
|
|
||||||
<TypeScriptCompile Include="Scripts\main.ts" />
|
<TypeScriptCompile Include="Scripts\main.ts" />
|
||||||
<TypeScriptCompile Include="Scripts\pto.ts" />
|
<TypeScriptCompile Include="Scripts\pto.ts" />
|
||||||
|
<TypeScriptCompile Include="Scripts\tracker.ts" />
|
||||||
<TypeScriptCompile Include="Scripts\utility.ts" />
|
<TypeScriptCompile Include="Scripts\utility.ts" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user