This commit is contained in:
Lani Aung
2021-10-17 13:24:24 -06:00
parent d1d891881f
commit 36e5726eaf
9 changed files with 207 additions and 93 deletions
-24
View File
@@ -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
View File
@@ -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() {
+15 -14
View File
@@ -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
+158
View File
@@ -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)
}
})
}
}
+10 -10
View File
@@ -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
}