refactor(stage.ts): change cordHist, isOpen, isAnimating, and active variables to instances of the watchable class to improve semantics and encapsulation

This commit is contained in:
Sped0n
2023-10-29 02:41:37 +08:00
parent a07b7bc1a0
commit 817b543ee0

View File

@@ -6,37 +6,29 @@ export type HistoryItem = { i: number; x: number; y: number }
let imgs: HTMLImageElement[] = [] let imgs: HTMLImageElement[] = []
class CordHist { class watchable<T> {
private obj: HistoryItem[] = [] constructor(private obj: T) {}
private watchers: (() => void)[] = []
get(): HistoryItem[] { get(): T {
return this.obj return this.obj
} }
set(e: HistoryItem[]): void { set(e: T): void {
this.obj = e this.obj = e
setPositions() this.watchers.forEach((watcher) => watcher())
}
}
class IsOpen {
private obj = false
get(): boolean {
return this.obj
} }
set(e: boolean): void { addWatcher(watcher: () => void): void {
this.obj = e this.watchers.push(watcher)
activeCallbacks.forEach((callback) => callback(getActive()))
} }
} }
let last = { x: 0, y: 0 } let last = { x: 0, y: 0 }
export let cordHist = new CordHist() export const cordHist = new watchable<HistoryItem[]>([])
export let isOpen = new IsOpen() export const isOpen = new watchable<boolean>(false)
let isAnimating = false export const isAnimating = new watchable<boolean>(false)
let activeCallbacks: ((active: boolean) => void)[] = [] export const active = new watchable<boolean>(false)
// getter // getter
@@ -58,30 +50,11 @@ function getElCurrent(): HTMLImageElement {
return elTrail[elTrail.length - 1] return elTrail[elTrail.length - 1]
} }
export function getIsAnimating(): boolean {
return isAnimating
}
export function getActive(): boolean {
return isOpen.get() && !getIsAnimating()
}
// setter
export function addActiveCallback(callback: (active: boolean) => void): void {
activeCallbacks.push(callback)
}
export function setIsAnimating(e: boolean): void {
isAnimating = e
activeCallbacks.forEach((callback) => callback(getActive()))
}
// main functions // main functions
// on mouse // on mouse
function onMouse(e: MouseEvent): void { function onMouse(e: MouseEvent): void {
if (isOpen.get() || getIsAnimating()) return if (isOpen.get() || isAnimating.get()) return
const cord = { x: e.clientX, y: e.clientY } const cord = { x: e.clientX, y: e.clientY }
const travelDist = Math.hypot(cord.x - last.x, cord.y - last.y) const travelDist = Math.hypot(cord.x - last.x, cord.y - last.y)
@@ -116,10 +89,10 @@ function setPositions(): void {
// open image into navigation // open image into navigation
function expandImage(): void { function expandImage(): void {
if (getIsAnimating()) return if (isAnimating.get()) return
isOpen.set(true) isOpen.set(true)
setIsAnimating(true) isAnimating.set(true)
const tl = gsap.timeline() const tl = gsap.timeline()
// move down and hide trail inactive // move down and hide trail inactive
@@ -147,16 +120,16 @@ function expandImage(): void {
}) })
// finished // finished
tl.then(() => { tl.then(() => {
setIsAnimating(false) isAnimating.set(false)
}) })
} }
// close navigation and back to stage // close navigation and back to stage
export function minimizeImage(): void { export function minimizeImage(): void {
if (isAnimating) return if (isAnimating.get()) return
isOpen.set(false) isOpen.set(false)
setIsAnimating(true) isAnimating.set(true)
const tl = gsap.timeline() const tl = gsap.timeline()
// shrink current // shrink current
@@ -183,7 +156,7 @@ export function minimizeImage(): void {
}) })
// finished // finished
tl.then(() => { tl.then(() => {
setIsAnimating(false) isAnimating.set(false)
}) })
} }
@@ -196,6 +169,9 @@ export function initStage(ijs: ImageJSON[]): void {
stage.addEventListener('click', () => expandImage()) stage.addEventListener('click', () => expandImage())
stage.addEventListener('keydown', () => expandImage()) stage.addEventListener('keydown', () => expandImage())
window.addEventListener('mousemove', onMouse) window.addEventListener('mousemove', onMouse)
isOpen.addWatcher(() => active.set(isOpen.get() && !isAnimating.get()))
isAnimating.addWatcher(() => active.set(isOpen.get() && !isAnimating.get()))
cordHist.addWatcher(() => setPositions())
} }
// hepler // hepler