feat: animation system
This commit is contained in:
parent
406e71575f
commit
7534a613cb
22 changed files with 19733 additions and 19122 deletions
1
README.md
Normal file
1
README.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|

|
||||||
|
|
@ -17,16 +17,18 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Asaki Yuki",
|
"author": "Asaki Yuki",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/js/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/types/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"dev": "tsc --watch",
|
"dev": "tsc --watch",
|
||||||
|
"test": "bun test/app.ts",
|
||||||
"prefetch": "bun scripts/prefetch",
|
"prefetch": "bun scripts/prefetch",
|
||||||
"vanilla:defs": "bun scripts/vanilladefs",
|
"vanilla:defs": "bun scripts/vanilladefs",
|
||||||
"gen:enums": "bun scripts/enum",
|
"gen:enums": "bun scripts/enum",
|
||||||
"gen:items": "bun scripts/items",
|
"gen:items": "bun scripts/items",
|
||||||
"gen:autocomplete": "bun scripts/autocomplete-build"
|
"gen:autocomplete": "bun scripts/autocomplete-build",
|
||||||
|
"full-build": "bun run prefetch;\nbun run vanilla:defs;\nbun run gen:enums;\nbun run gen:items;\nbun run gen:autocomplete;\nbun run build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^25.0.3",
|
"@types/node": "^25.0.3",
|
||||||
|
|
|
||||||
BIN
resources/logo.png
Normal file
BIN
resources/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -10,7 +10,12 @@ const intelliSense: string[] = [
|
||||||
'import { Type as T } from "../enums/Type.js"\n',
|
'import { Type as T } from "../enums/Type.js"\n',
|
||||||
"export type Namespace = keyof IntelliSense;",
|
"export type Namespace = keyof IntelliSense;",
|
||||||
"export type Element<T extends Namespace> = Extract<keyof IntelliSense[T], string>",
|
"export type Element<T extends Namespace> = Extract<keyof IntelliSense[T], string>",
|
||||||
"export type VanillaType<T extends Namespace, K extends Element<T>> = IntelliSense[T][K]\n",
|
"export type VanillaElementInfo<T extends Namespace, K extends Element<T>> = IntelliSense[T][K]",
|
||||||
|
"// @ts-ignore",
|
||||||
|
'export type VanillaType<T extends Namespace, K extends Element<T>> = VanillaElementInfo<T, K>["type"]',
|
||||||
|
"// @ts-ignore",
|
||||||
|
'export type VanillaElementChilds<T extends Namespace, K extends Element<T>> = VanillaElementInfo<T, K>["children"]',
|
||||||
|
"\n",
|
||||||
"export type IntelliSense = {",
|
"export type IntelliSense = {",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -27,9 +32,12 @@ for (const [namespace, element] of Object.entries(data)) {
|
||||||
ePaths: string[] = [` "${namespace}": {`]
|
ePaths: string[] = [` "${namespace}": {`]
|
||||||
|
|
||||||
for (const [ePath, info] of Object.entries(<any>element)) {
|
for (const [ePath, info] of Object.entries(<any>element)) {
|
||||||
const { file, type, extend } = <any>info
|
const { file, type, extend, children } = <any>info
|
||||||
|
|
||||||
|
const childType = children?.map((v: string) => `'${v}'`).join(" | ") || "string"
|
||||||
|
|
||||||
eType.push(`"${ePath}"`)
|
eType.push(`"${ePath}"`)
|
||||||
eType3.push(` "${ePath}": T.${type.toUpperCase()},`)
|
eType3.push(` "${ePath}": { type: T.${type.toUpperCase()}, children: ${childType} },`)
|
||||||
ePaths.push(` "${ePath}": "${file}",`)
|
ePaths.push(` "${ePath}": "${file}",`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ const vanilla: NamespaceMap = new Map()
|
||||||
function readControls(namespace: string, file: string, elements: ElementMap, data: any[], prefix: string) {
|
function readControls(namespace: string, file: string, elements: ElementMap, data: any[], prefix: string) {
|
||||||
prefix += "/"
|
prefix += "/"
|
||||||
|
|
||||||
|
const childs: string[] = []
|
||||||
|
|
||||||
for (const element of data) {
|
for (const element of data) {
|
||||||
const [fullname, properties] = Object.entries(element)[0]
|
const [fullname, properties] = Object.entries(element)[0]
|
||||||
|
|
||||||
|
|
@ -17,6 +19,7 @@ function readControls(namespace: string, file: string, elements: ElementMap, dat
|
||||||
const [name, $2] = fullname.split("@")
|
const [name, $2] = fullname.split("@")
|
||||||
|
|
||||||
if (name.startsWith("$")) continue
|
if (name.startsWith("$")) continue
|
||||||
|
childs.push(name)
|
||||||
|
|
||||||
if ($2 && !$2.startsWith("$")) {
|
if ($2 && !$2.startsWith("$")) {
|
||||||
const [$3, $4] = $2.split(".")
|
const [$3, $4] = $2.split(".")
|
||||||
|
|
@ -37,9 +40,12 @@ function readControls(namespace: string, file: string, elements: ElementMap, dat
|
||||||
|
|
||||||
const controls = (<any>properties).controls
|
const controls = (<any>properties).controls
|
||||||
if (controls) {
|
if (controls) {
|
||||||
readControls(namespace, file, elements, controls, prefix + name)
|
const childs = readControls(namespace, file, elements, controls, prefix + name)
|
||||||
|
if (childs.length) data.children = childs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return childs
|
||||||
}
|
}
|
||||||
|
|
||||||
function readData(namespace: string, file: string, elements: ElementMap, data: any) {
|
function readData(namespace: string, file: string, elements: ElementMap, data: any) {
|
||||||
|
|
@ -73,7 +79,8 @@ function readData(namespace: string, file: string, elements: ElementMap, data: a
|
||||||
|
|
||||||
const controls = (<any>properties).controls
|
const controls = (<any>properties).controls
|
||||||
if (controls) {
|
if (controls) {
|
||||||
readControls(namespace, file, elements, controls, name)
|
const childs = readControls(namespace, file, elements, controls, name)
|
||||||
|
if (childs.length) data.children = childs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -148,6 +155,7 @@ interface VanillaElement {
|
||||||
namespace: string
|
namespace: string
|
||||||
}
|
}
|
||||||
anim_type?: string
|
anim_type?: string
|
||||||
|
children?: string[]
|
||||||
type: string
|
type: string
|
||||||
file: string
|
file: string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { AnimationKeyframe } from "../components/AnimationKeyframe.js"
|
||||||
|
import { AnimType } from "../types/enums/AnimType.js"
|
||||||
|
import { KeyframeAnimationProperties } from "../types/properties/element/Animation.js"
|
||||||
import { Binding } from "../types/properties/value.js"
|
import { Binding } from "../types/properties/value.js"
|
||||||
|
|
||||||
export function FormatProperties(properties: any) {
|
export function FormatProperties(properties: any) {
|
||||||
|
|
@ -27,3 +30,11 @@ export function FormatProperties(properties: any) {
|
||||||
|
|
||||||
return properties
|
return properties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function FormatAnimationProperties(properties: KeyframeAnimationProperties<AnimType>) {
|
||||||
|
if (properties.next instanceof AnimationKeyframe) {
|
||||||
|
properties.next = `${properties.next}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
import { AnimationKeyframe } from "../components/AnimationKeyframe.js"
|
||||||
import { Class } from "../components/Class.js"
|
import { Class } from "../components/Class.js"
|
||||||
import { UI } from "../components/UI.js"
|
import { UI } from "../components/UI.js"
|
||||||
|
import { AnimType } from "../types/enums/AnimType.js"
|
||||||
import { Renderer } from "../types/enums/Renderer.js"
|
import { Renderer } from "../types/enums/Renderer.js"
|
||||||
import { Type } from "../types/enums/Type.js"
|
import { Type } from "../types/enums/Type.js"
|
||||||
|
|
||||||
type Element = UI<Type, Renderer | null>
|
type Element = UI<Type, Renderer | null> | AnimationKeyframe<AnimType>
|
||||||
interface FileInterface {
|
interface FileInterface {
|
||||||
namespace: string
|
namespace: string
|
||||||
elements: Element[]
|
elements: Element[]
|
||||||
|
|
@ -13,7 +15,7 @@ type Files = Map<string, FileInterface>
|
||||||
export class Memory extends Class {
|
export class Memory extends Class {
|
||||||
protected static files: Files = new Map<string, FileInterface>()
|
protected static files: Files = new Map<string, FileInterface>()
|
||||||
|
|
||||||
public static add(element: UI<Type, Renderer | null>) {
|
public static add(element: UI<Type, Renderer | null> | AnimationKeyframe<AnimType>) {
|
||||||
let file = Memory.files.get(element.path)
|
let file = Memory.files.get(element.path)
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
import { Memory } from "./Memory.js"
|
import { Memory } from "./Memory.js"
|
||||||
|
|
||||||
|
const isBuildMode = process.argv.includes("--build")
|
||||||
|
|
||||||
|
if (isBuildMode) {
|
||||||
process.on("beforeExit", () => {
|
process.on("beforeExit", () => {
|
||||||
// console.log(Memory.build())
|
console.log(JSON.stringify(Memory.build(), null, 2))
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,63 @@
|
||||||
|
import { AnimType } from "../types/enums/AnimType.js"
|
||||||
|
import { AnimationProperties } from "../types/properties/element/Animation.js"
|
||||||
import { Class } from "./Class.js"
|
import { Class } from "./Class.js"
|
||||||
|
import { KeyframeController } from "./KeyframeController.js"
|
||||||
|
|
||||||
export class Animation extends Class {}
|
export class Animation<T extends AnimType> extends Class {
|
||||||
|
protected keyframes: KeyframeController<AnimType>[] = []
|
||||||
|
protected loop = false
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly type: T,
|
||||||
|
...keyframes: (AnimationProperties<T> | number)[]
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
if (type === AnimType.WAIT) console.warn("Why are you create a wait animation?")
|
||||||
|
this.addKeyframes(...keyframes)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected lastKey() {
|
||||||
|
return this.keyframes[this.keyframes.length - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstKey() {
|
||||||
|
return this.keyframes[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
addKeyframes(...keyframes: (AnimationProperties<T> | number)[]) {
|
||||||
|
for (const $ of keyframes) {
|
||||||
|
let keyframe: AnimationProperties<AnimType>, animType: AnimType
|
||||||
|
|
||||||
|
if (typeof $ === "number") {
|
||||||
|
keyframe = { duration: $ }
|
||||||
|
animType = AnimType.WAIT
|
||||||
|
} else {
|
||||||
|
keyframe = $
|
||||||
|
animType = this.type
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyframeController = new KeyframeController(animType, keyframe as AnimationProperties<T>)
|
||||||
|
|
||||||
|
const prevKeyframe = this.lastKey()
|
||||||
|
if (prevKeyframe) prevKeyframe.setNext(keyframeController)
|
||||||
|
|
||||||
|
if (this.loop) keyframeController.setNext(this.firstKey() as KeyframeController<T>)
|
||||||
|
|
||||||
|
this.keyframes.push(keyframeController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoop(boolean: boolean) {
|
||||||
|
this.loop = boolean
|
||||||
|
|
||||||
|
if (this.loop) {
|
||||||
|
const prevKeyframe = this.lastKey()
|
||||||
|
if (prevKeyframe) prevKeyframe.setNext(this.firstKey() as KeyframeController<T>)
|
||||||
|
} else {
|
||||||
|
const prevKeyframe = this.lastKey()
|
||||||
|
if (prevKeyframe) prevKeyframe.clearNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,61 @@
|
||||||
|
import { FormatAnimationProperties } from "../compilers/FormatProperties.js"
|
||||||
|
import { Memory } from "../compilers/Memory.js"
|
||||||
|
import { AnimType } from "../types/enums/AnimType.js"
|
||||||
|
import { KeyframeAnimationProperties } from "../types/properties/element/Animation.js"
|
||||||
import { Class } from "./Class.js"
|
import { Class } from "./Class.js"
|
||||||
|
import { RandomString } from "./Utils.js"
|
||||||
|
|
||||||
export class AnimationKeyframe extends Class {}
|
import util from "node:util"
|
||||||
|
|
||||||
|
export class AnimationKeyframe<T extends AnimType> extends Class {
|
||||||
|
readonly path: string
|
||||||
|
readonly name: string
|
||||||
|
readonly namespace: string
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly type: T,
|
||||||
|
readonly properties: KeyframeAnimationProperties<T>,
|
||||||
|
name?: string,
|
||||||
|
namespace?: string,
|
||||||
|
path?: string,
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
|
||||||
|
if (name === "namespace") {
|
||||||
|
console.error("The 'namespace' cannot be used as a name")
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namespace && !/^\w+$/.test(namespace)) {
|
||||||
|
console.error(`The '${namespace}' cannot be used as a namespace`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = name || RandomString(16)
|
||||||
|
this.namespace = namespace || RandomString(16)
|
||||||
|
this.path = path || `@/${this.namespace}`
|
||||||
|
|
||||||
|
Memory.add(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected toJsonUI() {
|
||||||
|
return FormatAnimationProperties(this.properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected toJSON() {
|
||||||
|
return {
|
||||||
|
anim_type: this.type,
|
||||||
|
...this.toJsonUI(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected toString() {
|
||||||
|
return `@${this.namespace}.${this.name}`
|
||||||
|
}
|
||||||
|
|
||||||
|
protected [util.inspect.custom]($: any, opts: any) {
|
||||||
|
return `\x1b[33mAnimationKeyFrame\x1b[0m<\x1b[92m${
|
||||||
|
this.type
|
||||||
|
}\x1b[0m> \x1b[92m"${this}\x1b[92m"\x1b[0m ${util.inspect(this.toJsonUI(), opts)}\n`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
19
src/components/KeyframeController.ts
Normal file
19
src/components/KeyframeController.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { AnimType } from "../types/enums/AnimType.js"
|
||||||
|
import { KeyframeAnimationProperties } from "../types/properties/element/Animation.js"
|
||||||
|
import { AnimationKeyframe } from "./AnimationKeyframe.js"
|
||||||
|
|
||||||
|
export class KeyframeController<T extends AnimType> extends AnimationKeyframe<T> {
|
||||||
|
constructor(type: T, properties: KeyframeAnimationProperties<T>, name?: string, namespace?: string, path?: string) {
|
||||||
|
super(type, properties, name, namespace, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
setNext(keyframe: AnimationKeyframe<AnimType>) {
|
||||||
|
this.properties.next = keyframe
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
clearNext() {
|
||||||
|
delete this.properties.next
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,30 +1,31 @@
|
||||||
import { isCompileBinding } from "../compilers/bindings/Checker.js"
|
|
||||||
import { Parser } from "../compilers/bindings/Parser.js"
|
|
||||||
import { FormatProperties } from "../compilers/FormatProperties.js"
|
import { FormatProperties } from "../compilers/FormatProperties.js"
|
||||||
import { Memory } from "../compilers/Memory.js"
|
import { Memory } from "../compilers/Memory.js"
|
||||||
import { BindingType } from "../types/enums/BindingType.js"
|
import { ArrayName } from "../types/enums/ArrayName.js"
|
||||||
|
import { Operation } from "../types/enums/Operation.js"
|
||||||
import { Renderer } from "../types/enums/Renderer.js"
|
import { Renderer } from "../types/enums/Renderer.js"
|
||||||
import { Type } from "../types/enums/Type.js"
|
import { Type } from "../types/enums/Type.js"
|
||||||
import { Properties } from "../types/properties/components.js"
|
import { Properties } from "../types/properties/components.js"
|
||||||
import { BindingItem } from "../types/properties/value.js"
|
import { BindingItem, ButtonMapping, ModificationItem, VariableItem, Variables } from "../types/properties/value.js"
|
||||||
import { Class } from "./Class.js"
|
import { Class } from "./Class.js"
|
||||||
import { ExtendsOf, RandomString } from "./Utils.js"
|
import { ExtendsOf, RandomString, ResolveBinding } from "./Utils.js"
|
||||||
|
|
||||||
import util from "node:util"
|
import util from "node:util"
|
||||||
|
|
||||||
export class UI<T extends Type, K extends Renderer | null = null> extends Class {
|
export class UI<T extends Type, K extends Renderer | null = null> extends Class {
|
||||||
readonly path: string
|
readonly path: string
|
||||||
|
|
||||||
readonly name: string
|
readonly name: string
|
||||||
readonly namespace: string
|
readonly namespace: string
|
||||||
readonly extend?: UI<Type, Renderer | null>
|
|
||||||
|
|
||||||
|
readonly extend?: UI<Type, Renderer | null>
|
||||||
readonly extendable: boolean
|
readonly extendable: boolean
|
||||||
|
|
||||||
readonly controls = new Map<string, [UI<Type, Renderer | null>, Properties<Type, Renderer | null>]>()
|
protected readonly controls = new Map<string, [UI<Type, Renderer | null>, Properties<Type, Renderer | null>]>()
|
||||||
readonly bindings: BindingItem[] = []
|
protected readonly bindings: BindingItem[] = []
|
||||||
readonly extendType?: Type
|
protected readonly variables: VariableItem[] = []
|
||||||
properties: Properties<T, K> = <any>{}
|
protected readonly buttonMappings: ButtonMapping[] = []
|
||||||
|
protected readonly extendType?: Type
|
||||||
|
|
||||||
|
protected properties: Properties<T, K> = <any>{}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public type?: T,
|
public type?: T,
|
||||||
|
|
@ -55,60 +56,72 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
|
||||||
Memory.add(this)
|
Memory.add(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UI_JSON() {
|
/**
|
||||||
const obj: any = {
|
* Set properties for this element
|
||||||
...FormatProperties(this.properties),
|
* @param properties
|
||||||
}
|
* @returns
|
||||||
|
*/
|
||||||
if (this.type) {
|
|
||||||
obj.type = this.type
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.bindings.length) {
|
|
||||||
obj.bindings = this.bindings
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.controls.size) {
|
|
||||||
obj.controls = []
|
|
||||||
this.controls.forEach((e, key) => obj.controls.push({ [key + e[0]]: e[1] }))
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
setProperties(properties: Properties<T, K>) {
|
setProperties(properties: Properties<T, K>) {
|
||||||
this.properties = { ...this.properties, ...properties }
|
this.properties = { ...this.properties, ...properties }
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind data (coming from the code) to this UI element to use.
|
||||||
|
* @param bindings
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
addBindings(...bindings: BindingItem[]) {
|
addBindings(...bindings: BindingItem[]) {
|
||||||
for (const binding of bindings) {
|
this.bindings.push(...ResolveBinding(...bindings))
|
||||||
if (binding.source_property_name) {
|
return this
|
||||||
if (isCompileBinding(binding.source_property_name)) {
|
|
||||||
const { gen, out } = new Parser(binding.source_property_name.slice(1, -1)).out()
|
|
||||||
if (gen) this.bindings.push(...gen)
|
|
||||||
binding.source_property_name = out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.binding_type = BindingType.VIEW
|
/**
|
||||||
|
* Changes variables values if conditions are met.
|
||||||
if (!binding.target_property_name) throw new Error("Binding must have a target property name")
|
* @param variables
|
||||||
}
|
* @returns
|
||||||
this.bindings.push(binding)
|
*/
|
||||||
}
|
addVariables(variables: Variables) {
|
||||||
|
Object.entries(variables).forEach(([key, value]) => {
|
||||||
|
this.variables.push({
|
||||||
|
requires: key,
|
||||||
|
...value,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
addChild<T extends Type, K extends Renderer | null>(child: UI<T, K>, properties?: Properties<T, K>, name?: string) {
|
/**
|
||||||
if (this === <any>child) {
|
* Add button mappings for this element
|
||||||
throw new Error("Cannot add a child to itself")
|
* @param mappings
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
addButtonMappings(...mappings: ButtonMapping[]) {
|
||||||
|
this.buttonMappings.push(...mappings)
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Children of the UI element.
|
||||||
|
* @param child
|
||||||
|
* @param properties
|
||||||
|
* @param name
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
addChild<T extends Type, K extends Renderer | null>(child: UI<T, K>, properties?: Properties<T, K>, name?: string) {
|
||||||
|
if (this === <any>child) throw new Error("Cannot add a child to itself")
|
||||||
this.controls.set(name || RandomString(16), [child, properties || {}])
|
this.controls.set(name || RandomString(16), [child, properties || {}])
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a extend of this element
|
||||||
|
* @param properties
|
||||||
|
* @param name
|
||||||
|
* @param namespace
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
clone(properties?: Properties<T, K>, name?: string, namespace?: string) {
|
clone(properties?: Properties<T, K>, name?: string, namespace?: string) {
|
||||||
return ExtendsOf(this, properties, name, namespace)
|
return ExtendsOf(this, properties, name, namespace)
|
||||||
}
|
}
|
||||||
|
|
@ -117,40 +130,264 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
|
||||||
return `@${this.namespace}.${this.name}`
|
return `@${this.namespace}.${this.name}`
|
||||||
}
|
}
|
||||||
|
|
||||||
protected toJSON() {
|
protected toJsonUI() {
|
||||||
return this.UI_JSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected [util.inspect.custom]($: any, opts: any) {
|
|
||||||
const obj: any = {
|
const obj: any = {
|
||||||
...FormatProperties(this.properties),
|
...FormatProperties(this.properties),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.bindings.length) {
|
if (this.type) obj.type = this.type
|
||||||
obj.bindings = this.bindings
|
|
||||||
}
|
if (this.bindings.length) obj.bindings = this.bindings
|
||||||
|
if (this.variables.length) obj.variables = this.variables
|
||||||
|
if (this.buttonMappings.length) obj.button_mappings = this.buttonMappings
|
||||||
|
|
||||||
if (this.controls.size) {
|
if (this.controls.size) {
|
||||||
obj.controls = []
|
obj.controls = []
|
||||||
this.controls.forEach((e, key) => obj.controls.push({ [key + e[0]]: e[1] }))
|
this.controls.forEach((e, key) => obj.controls.push({ [key + e[0]]: e[1] }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const elementType = this.type || (this.extend ? `${this.extendType || "unknown"}:${this.extend}` : "unknown")
|
return obj
|
||||||
|
|
||||||
return `\x1b[33mUI\x1b[0m<\x1b[92m${
|
|
||||||
elementType
|
|
||||||
}\x1b[0m> \x1b[92m"${this}\x1b[92m"\x1b[0m ${util.inspect(obj, opts)}\n`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ModifyUI<T extends Type> extends UI<T, null> {
|
|
||||||
constructor(namespace: string, name: string, path: string) {
|
|
||||||
if (!path) throw new Error("ModifyUI cannot have a path")
|
|
||||||
super(undefined, name, namespace, path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected toJSON() {
|
protected toJSON() {
|
||||||
const obj = this.UI_JSON()
|
return this.toJsonUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected [util.inspect.custom]($: any, opts: any) {
|
||||||
|
return `\x1b[33mUI\x1b[0m<\x1b[92m${
|
||||||
|
this.type || (this.extend ? `${this.extendType || "unknown"}:${this.extend}` : "unknown")
|
||||||
|
}\x1b[0m> \x1b[92m"${this}\x1b[92m"\x1b[0m ${util.inspect(this.toJsonUI(), opts)}\n`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ModifyUI<T extends Type = Type.PANEL, S extends string = string> extends UI<T, null> {
|
||||||
|
private isClearBinding: boolean = false
|
||||||
|
private isClearVariables: boolean = false
|
||||||
|
private isClearButtonMappings: boolean = false
|
||||||
|
|
||||||
|
protected modifications: ModificationItem[] = []
|
||||||
|
|
||||||
|
constructor(namespace: string, name: string, path: string) {
|
||||||
|
super(undefined, name, namespace, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all bindings of this modify element
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
clearBinding() {
|
||||||
|
this.isClearBinding = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all variables of this modfy element
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
clearVariables() {
|
||||||
|
this.isClearVariables = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all button mappings of this element
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
clearButtonMappings() {
|
||||||
|
this.isClearButtonMappings = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to modify the UI elements from resource packs below this one
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
addModifications(...modifications: ModificationItem[]) {
|
||||||
|
this.modifications.push(...modifications)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
insertBackChild<T extends Type, K extends Renderer | null>(
|
||||||
|
child: UI<T, K>,
|
||||||
|
properties?: Properties<T, K>,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
if (this === <any>child) throw new Error("Cannot add a child to itself")
|
||||||
|
if (!name) name = RandomString(16)
|
||||||
|
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.CONTROLS,
|
||||||
|
operation: Operation.INSERT_BACK,
|
||||||
|
value: {
|
||||||
|
[`${name}${child}`]: properties || {},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertFrontChild<T extends Type, K extends Renderer | null>(
|
||||||
|
child: UI<T, K>,
|
||||||
|
properties?: Properties<T, K>,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
if (this === <any>child) throw new Error("Cannot add a child to itself")
|
||||||
|
if (!name) name = RandomString(16)
|
||||||
|
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.CONTROLS,
|
||||||
|
operation: Operation.INSERT_FRONT,
|
||||||
|
value: {
|
||||||
|
[`${name}${child}`]: properties || {},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertAfterChild<T extends Type, K extends Renderer | null>(
|
||||||
|
where: S,
|
||||||
|
child: UI<T, K>,
|
||||||
|
properties?: Properties<T, K>,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
if (this === <any>child) throw new Error("Cannot add a child to itself")
|
||||||
|
if (!name) name = RandomString(16)
|
||||||
|
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.CONTROLS,
|
||||||
|
operation: Operation.INSERT_AFTER,
|
||||||
|
control_name: where!,
|
||||||
|
value: {
|
||||||
|
[`${name}${child}`]: properties || {},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertBeforeChild<T extends Type, K extends Renderer | null>(
|
||||||
|
where: S,
|
||||||
|
child: UI<T, K>,
|
||||||
|
properties?: Properties<T, K>,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
if (this === <any>child) throw new Error("Cannot add a child to itself")
|
||||||
|
if (!name) name = RandomString(16)
|
||||||
|
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.CONTROLS,
|
||||||
|
operation: Operation.INSERT_BEFORE,
|
||||||
|
control_name: where!,
|
||||||
|
value: {
|
||||||
|
[`${name}${child}`]: properties || {},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertChild<T extends Type, K extends Renderer | null>(child: UI<T, K>, properties?: Properties<T, K>) {
|
||||||
|
return this.insertBackChild(child, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceChild<T extends Type, K extends Renderer | null>(where: S, child: UI<T, K>, properties?: Properties<T, K>) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.CONTROLS,
|
||||||
|
operation: Operation.REPLACE,
|
||||||
|
control_name: where!,
|
||||||
|
value: properties || {},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a child of this element
|
||||||
|
* @param name
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
removeChild(name: S) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.CONTROLS,
|
||||||
|
operation: Operation.REMOVE,
|
||||||
|
control_name: name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertBackBindings(...bindings: BindingItem[]) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.BINDINGS,
|
||||||
|
operation: Operation.INSERT_BACK,
|
||||||
|
value: ResolveBinding(...bindings),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertFrontBindings(...bindings: BindingItem[]) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.BINDINGS,
|
||||||
|
operation: Operation.INSERT_FRONT,
|
||||||
|
value: ResolveBinding(...bindings),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertBindings(...bindings: BindingItem[]) {
|
||||||
|
return this.insertBackBindings(...bindings)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a binding of this element
|
||||||
|
* @param binding
|
||||||
|
*/
|
||||||
|
removeBinding(binding: BindingItem) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.BINDINGS,
|
||||||
|
operation: Operation.REMOVE,
|
||||||
|
where: binding,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertBackButtonMappings(...buttonMappings: ButtonMapping[]) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.BUTTON_MAPPINGS,
|
||||||
|
operation: Operation.INSERT_BACK,
|
||||||
|
value: buttonMappings,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertFrontButtonMappings(...buttonMappings: ButtonMapping[]) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.BUTTON_MAPPINGS,
|
||||||
|
operation: Operation.INSERT_FRONT,
|
||||||
|
value: buttonMappings,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
insertButtonMappings(...buttonMappings: ButtonMapping[]) {
|
||||||
|
return this.insertBackButtonMappings(...buttonMappings)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a button mapping of this element
|
||||||
|
* @param buttonMapping
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
removeButtonMapping(buttonMapping: ButtonMapping) {
|
||||||
|
return this.addModifications({
|
||||||
|
array_name: ArrayName.BUTTON_MAPPINGS,
|
||||||
|
operation: Operation.REMOVE,
|
||||||
|
where: buttonMapping,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
protected toJsonUIModify() {
|
||||||
|
const obj = this.toJsonUI()
|
||||||
|
|
||||||
|
if (this.isClearBinding) obj.bindings = []
|
||||||
|
if (this.isClearVariables) obj.variables = []
|
||||||
|
if (this.isClearButtonMappings) obj.button_mappings = []
|
||||||
|
|
||||||
|
if (this.modifications.length) obj.modifications = this.modifications
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected toJSON() {
|
||||||
|
const obj = this.toJsonUIModify()
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
protected [util.inspect.custom]($: any, opts: any) {
|
||||||
|
return `\x1b[33mUI\x1b[0m<\x1b[92mmodify\x1b[0m> \x1b[92m"${this}\x1b[92m"\x1b[0m ${util.inspect(this.toJsonUIModify(), opts)}\n`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Type } from "../types/enums/Type.js"
|
import { Type } from "../types/enums/Type.js"
|
||||||
import { Array3, Binding } from "../types/properties/value.js"
|
import { Array3, Binding, BindingItem } from "../types/properties/value.js"
|
||||||
import { ModifyUI, UI } from "./UI.js"
|
import { ModifyUI, UI } from "./UI.js"
|
||||||
|
|
||||||
import { Renderer } from "../types/enums/Renderer.js"
|
import { Renderer } from "../types/enums/Renderer.js"
|
||||||
|
|
@ -27,8 +27,14 @@ import {
|
||||||
SliderBox,
|
SliderBox,
|
||||||
} from "../types/properties/components.js"
|
} from "../types/properties/components.js"
|
||||||
import { ItemAuxID } from "../types/enums/Items.js"
|
import { ItemAuxID } from "../types/enums/Items.js"
|
||||||
import { Element, Namespace, VanillaType } from "../types/vanilla/intellisense.js"
|
import { Element, Namespace, VanillaElementChilds, VanillaType } from "../types/vanilla/intellisense.js"
|
||||||
import { paths } from "../types/vanilla/paths.js"
|
import { paths } from "../types/vanilla/paths.js"
|
||||||
|
import { isCompileBinding } from "../compilers/bindings/Checker.js"
|
||||||
|
import { Parser } from "../compilers/bindings/Parser.js"
|
||||||
|
import { BindingType } from "../types/enums/BindingType.js"
|
||||||
|
import { AnimType } from "../types/enums/AnimType.js"
|
||||||
|
import { AnimationKeyframe } from "./AnimationKeyframe.js"
|
||||||
|
import { KeyframeAnimationProperties } from "../types/properties/element/Animation.js"
|
||||||
|
|
||||||
const CHARS = "0123456789abcdefghijklmnopqrstuvwxyz"
|
const CHARS = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||||
type CompileBinding = `[${string}]`
|
type CompileBinding = `[${string}]`
|
||||||
|
|
@ -60,6 +66,27 @@ export function Color(hex: string | number): Array3<number> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ResolveBinding(...bindings: BindingItem[]) {
|
||||||
|
const result: BindingItem[] = []
|
||||||
|
|
||||||
|
for (const binding of bindings) {
|
||||||
|
if (binding.source_property_name) {
|
||||||
|
if (isCompileBinding(binding.source_property_name)) {
|
||||||
|
const { gen, out } = new Parser(binding.source_property_name.slice(1, -1)).out()
|
||||||
|
if (gen) result.push(...gen)
|
||||||
|
binding.source_property_name = out
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.binding_type = BindingType.VIEW
|
||||||
|
|
||||||
|
if (!binding.target_property_name) throw new Error("Binding must have a target property name")
|
||||||
|
}
|
||||||
|
result.push(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
export function RandomString(length: number, base: number = 32) {
|
export function RandomString(length: number, base: number = 32) {
|
||||||
const chars = CHARS.slice(0, base)
|
const chars = CHARS.slice(0, base)
|
||||||
const out = new Array<string>(length)
|
const out = new Array<string>(length)
|
||||||
|
|
@ -112,7 +139,7 @@ export function b(input: string): CompileBinding {
|
||||||
// Quick Elements
|
// Quick Elements
|
||||||
export function Modify<T extends Namespace, K extends Element<T>>(namespace: T, name: K) {
|
export function Modify<T extends Namespace, K extends Element<T>>(namespace: T, name: K) {
|
||||||
// @ts-ignore -- TS cannot prove this, but runtime guarantees it
|
// @ts-ignore -- TS cannot prove this, but runtime guarantees it
|
||||||
return new ModifyUI<VanillaType<T, K>>(name, namespace, paths[namespace][name])
|
return new ModifyUI<VanillaType<T, K>, VanillaElementChilds<T, K>>(namespace, name, paths[namespace][name])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Panel(properties?: Panel, namespace?: string, name?: string) {
|
export function Panel(properties?: Panel, namespace?: string, name?: string) {
|
||||||
|
|
@ -219,3 +246,72 @@ export function ExtendsOf<T extends Type, K extends Renderer | null>(
|
||||||
ui.extendType = element.type || element.extendType
|
ui.extendType = element.type || element.extendType
|
||||||
return ui as typeof element
|
return ui as typeof element
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick Keyframe
|
||||||
|
export function KeyframeOffset(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.OFFSET>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.OFFSET, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeSize(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.SIZE>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.SIZE, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeUV(properties?: KeyframeAnimationProperties<AnimType.UV>, namespace?: string, name?: string) {
|
||||||
|
return new AnimationKeyframe(AnimType.UV, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeClip(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.CLIP>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.CLIP, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeColor(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.COLOR>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.COLOR, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeAlpha(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.ALPHA>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.ALPHA, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeWait(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.WAIT>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.WAIT, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeFlipBook(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.FLIP_BOOK>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.FLIP_BOOK, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function KeyframeAsepriteFlipBook(
|
||||||
|
properties?: KeyframeAnimationProperties<AnimType.ASEPRITE_FLIP_BOOK>,
|
||||||
|
namespace?: string,
|
||||||
|
name?: string,
|
||||||
|
) {
|
||||||
|
return new AnimationKeyframe(AnimType.ASEPRITE_FLIP_BOOK, properties || {}, name, namespace)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import "./compilers/PreCompile.js"
|
import "./compilers/PreCompile.js"
|
||||||
import "./compilers/RunEnd.js"
|
import "./compilers/RunEnd.js"
|
||||||
|
|
||||||
export * from "./components/Animation.js"
|
export { Animation } from "./components/Animation.js"
|
||||||
export * from "./components/UI.js"
|
export { AnimationKeyframe } from "./components/AnimationKeyframe.js"
|
||||||
|
export { ModifyUI, UI } from "./components/UI.js"
|
||||||
export * from "./components/Utils.js"
|
export * from "./components/Utils.js"
|
||||||
|
|
||||||
export * from "./types/enums/index.js"
|
export * from "./types/enums/index.js"
|
||||||
|
|
|
||||||
5
src/types/enums/ArrayName.ts
Normal file
5
src/types/enums/ArrayName.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export enum ArrayName {
|
||||||
|
CONTROLS = "controls",
|
||||||
|
BINDINGS = "bindings",
|
||||||
|
BUTTON_MAPPINGS = "button_mappings",
|
||||||
|
}
|
||||||
13
src/types/enums/Operation.ts
Normal file
13
src/types/enums/Operation.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
export enum Operation {
|
||||||
|
INSERT_BACK = "insert_back",
|
||||||
|
INSERT_FRONT = "insert_front",
|
||||||
|
INSERT_AFTER = "insert_after",
|
||||||
|
INSERT_BEFORE = "insert_before",
|
||||||
|
MOVE_BACK = "move_back",
|
||||||
|
MOVE_FRONT = "move_front",
|
||||||
|
MOVE_AFTER = "move_after",
|
||||||
|
MOVE_BEFORE = "move_before",
|
||||||
|
SWAP = "swap",
|
||||||
|
REMOVE = "remove",
|
||||||
|
REPLACE = "replace",
|
||||||
|
}
|
||||||
|
|
@ -3,22 +3,59 @@ import { AnimType } from "../../enums/AnimType.js"
|
||||||
import { Easing } from "../../enums/Easing.js"
|
import { Easing } from "../../enums/Easing.js"
|
||||||
import { Array2, Array3, Value } from "../value.js"
|
import { Array2, Array3, Value } from "../value.js"
|
||||||
|
|
||||||
export interface Animation {
|
export interface DurationAnimation {
|
||||||
anim_type?: Value<string | AnimType>
|
|
||||||
duration?: Value<number>
|
duration?: Value<number>
|
||||||
next?: Value<string | AnimationKeyframe>
|
}
|
||||||
|
|
||||||
|
export interface EasingAnimation extends DurationAnimation {
|
||||||
|
easing?: Value<string | Easing>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NumberAnimation extends DurationAnimation, EasingAnimation {
|
||||||
|
from: Value<number>
|
||||||
|
to: Value<number>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Array2Animation extends DurationAnimation, EasingAnimation {
|
||||||
|
from: Array2<number | string>
|
||||||
|
to: Array2<number | string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Array3Animation extends DurationAnimation, EasingAnimation {
|
||||||
|
from: Array3<number | string>
|
||||||
|
to: Array3<number | string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AsepriteFlipBookAnimation {
|
||||||
|
initial_uv?: Value<Array2<number>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FlipbookAnimation extends AsepriteFlipBookAnimation {
|
||||||
|
frame_count?: Value<number>
|
||||||
|
frame_step?: Value<number>
|
||||||
|
fps?: Value<number>
|
||||||
|
easing?: Value<string | Easing>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AnimationValueType {
|
||||||
|
[AnimType.OFFSET]: Array2Animation
|
||||||
|
[AnimType.SIZE]: Array2Animation
|
||||||
|
[AnimType.UV]: Array2Animation
|
||||||
|
[AnimType.CLIP]: Array2Animation
|
||||||
|
[AnimType.COLOR]: Array3Animation
|
||||||
|
[AnimType.ALPHA]: NumberAnimation
|
||||||
|
[AnimType.WAIT]: DurationAnimation
|
||||||
|
[AnimType.FLIP_BOOK]: FlipbookAnimation
|
||||||
|
[AnimType.ASEPRITE_FLIP_BOOK]: AsepriteFlipBookAnimation
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AnimationPropertiesItem {
|
||||||
destroy_at_end?: Value<string>
|
destroy_at_end?: Value<string>
|
||||||
play_event?: Value<string>
|
play_event?: Value<string>
|
||||||
end_event?: Value<string>
|
end_event?: Value<string>
|
||||||
start_event?: Value<string>
|
start_event?: Value<string>
|
||||||
reset_event?: Value<string>
|
reset_event?: Value<string>
|
||||||
easing?: Value<string | Easing>
|
|
||||||
from?: Value<number | string | Array3<number> | Array2<string>>
|
|
||||||
to?: Value<number | string | Array3<number> | Array2<string>>
|
|
||||||
initial_uv?: Value<Array2<number>>
|
|
||||||
fps?: Value<number>
|
|
||||||
frame_count?: Value<number>
|
|
||||||
frame_step?: Value<number>
|
|
||||||
reversible?: Value<boolean>
|
reversible?: Value<boolean>
|
||||||
resettable?: Value<boolean>
|
resettable?: Value<boolean>
|
||||||
scale_from_starting_alpha?: Value<boolean>
|
scale_from_starting_alpha?: Value<boolean>
|
||||||
|
|
@ -26,3 +63,13 @@ export interface Animation {
|
||||||
looping?: Value<boolean>
|
looping?: Value<boolean>
|
||||||
wait_until_rendered_to_play?: Value<boolean>
|
wait_until_rendered_to_play?: Value<boolean>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface KeyframeAnimationPropertiesItem extends AnimationPropertiesItem {
|
||||||
|
next?: Value<string | AnimationKeyframe<AnimType>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type KeyframeAnimationProperties<T extends keyof AnimationValueType> = Partial<AnimationValueType[T]> &
|
||||||
|
KeyframeAnimationPropertiesItem
|
||||||
|
|
||||||
|
export type AnimationProperties<T extends keyof AnimationValueType> = Partial<AnimationValueType[T]> &
|
||||||
|
AnimationPropertiesItem
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
export * as ElementProperties from "./element/index.js"
|
export * as ElementProperties from "./element/index.js"
|
||||||
export * as ComponentProperties from "./components.js"
|
export * as ComponentProperties from "./components.js"
|
||||||
export * as Value from "./value.js"
|
export * as Value from "./value.js"
|
||||||
|
|
||||||
|
export { ArrayName } from "../enums/ArrayName.js"
|
||||||
|
export { Operation } from "../enums/Operation.js"
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import { ButtonId } from "../enums/ButtonId.js"
|
||||||
import { MappingType } from "../enums/MappingType.js"
|
import { MappingType } from "../enums/MappingType.js"
|
||||||
import { InputModeCondition } from "../enums/InputModeCondition.js"
|
import { InputModeCondition } from "../enums/InputModeCondition.js"
|
||||||
import { Scope } from "../enums/Scope.js"
|
import { Scope } from "../enums/Scope.js"
|
||||||
|
import { ArrayName } from "../enums/ArrayName.js"
|
||||||
|
import { Operation } from "../enums/Operation.js"
|
||||||
|
|
||||||
export type Variable = `$${string}`
|
export type Variable = `$${string}`
|
||||||
export type Binding = `#${string}`
|
export type Binding = `#${string}`
|
||||||
|
|
@ -34,6 +36,15 @@ export type BindingItem = {
|
||||||
resolve_ancestor_scope?: Value<boolean>
|
resolve_ancestor_scope?: Value<boolean>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type VariableItem = {
|
||||||
|
requires: string
|
||||||
|
[key: Variable]: Value<any>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Variables = {
|
||||||
|
[key: Variable | `(${string})`]: Record<Variable, unknown>
|
||||||
|
}
|
||||||
|
|
||||||
export type FocusContainerCustom = Array<{
|
export type FocusContainerCustom = Array<{
|
||||||
other_focus_container_name?: Value<string>
|
other_focus_container_name?: Value<string>
|
||||||
focus_id_inside?: Value<string>
|
focus_id_inside?: Value<string>
|
||||||
|
|
@ -56,3 +67,13 @@ export type ButtonMapping = {
|
||||||
export type PropertyBags = {
|
export type PropertyBags = {
|
||||||
[key: Binding]: Value<any>
|
[key: Binding]: Value<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ModificationItem = {
|
||||||
|
array_name?: ArrayName
|
||||||
|
control_name?: string
|
||||||
|
where?: BindingItem | object
|
||||||
|
target?: object
|
||||||
|
target_control?: string
|
||||||
|
value?: object | (object | BindingItem)[]
|
||||||
|
operation?: Operation
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
11
test/app.ts
11
test/app.ts
|
|
@ -1 +1,10 @@
|
||||||
import { Modify, Panel, StackPanel, Toggle, GetItemByAuxID, ItemAuxID } from ".."
|
import { Animation, AnimType } from ".."
|
||||||
|
|
||||||
|
const animation = new Animation(
|
||||||
|
AnimType.OFFSET,
|
||||||
|
{
|
||||||
|
from: [0, 0],
|
||||||
|
to: [100, 100],
|
||||||
|
},
|
||||||
|
123,
|
||||||
|
).setLoop(false)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
"target": "esnext",
|
"target": "esnext",
|
||||||
"module": "nodenext",
|
"module": "nodenext",
|
||||||
"moduleResolution": "nodenext",
|
"moduleResolution": "nodenext",
|
||||||
"outDir": "dist",
|
"outDir": "dist/js",
|
||||||
|
"declarationDir": "dist/types",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
|
||||||
Reference in a new issue