diff --git a/README.md b/README.md index 541aee0..eb6af48 100644 --- a/README.md +++ b/README.md @@ -47,28 +47,11 @@ To generate the latest charword_table.json ``` ### Webpage & JavaScript -Add query string `settings` to bring up the settings panel to adjust your settings. Then use appropriate JavaScript code to load your settings +Add query string `aklive2d` to bring up the settings panel to adjust your settings. +Settings can be adjusted under `window.aklive2d` or by dispatching custom events (under `window.aklive2d.events`) to `document`. +Examples can be found at `showcase/src/libs/wallpaper_engine.js`. -``` javascript -settings.setFPS(integer) // set FPS -settings.setLogoDisplay(boolean) // display logo or not -settings.setLogoRatio(float) // the ratio of the logo -settings.setLogoOpacity(float) // the opacity of the logo -settings.setLogo(url) // change the logo, url: image url, removeInvert: boolean -settings.resetLogoImage() // reset to the default logo -settings.setDefaultBackground(url) // change the default background, url: image filename from `background` folder -settings.setBackgoundImage(url) // change the background, url: image url -settings.resetBackground() // reset to the default background -settings.positionPadding("left", integer) // left padding -settings.positionPadding("right", integer) // right padding -settings.positionPadding("top", integer) // top padding -settings.positionPadding("bottom", integer) // bottom padding -settings.positionReset() // reset the position - -settings.open() // open settings panel -settings.close() // close settings panel -settings.reset() // reset settings -``` +Using JS events to change settings is recommended. ## Config ### General Config diff --git a/showcase/src/components/aklive2d.js b/showcase/src/components/aklive2d.js index e1fd86c..d9653ed 100644 --- a/showcase/src/components/aklive2d.js +++ b/showcase/src/components/aklive2d.js @@ -5,6 +5,7 @@ import Player from "@/components/player"; import Background from "@/components/background"; import Logo from "@/components/logo"; import Insight from "@/components/insight"; +import * as Event from "@/components/event"; import { isWebGLSupported, insertHTMLChild, @@ -17,11 +18,11 @@ export default class AKLive2D { #el = document.createElement("div") #appEl #queries = new URLSearchParams(window.location.search) - #voice = new Voice() - #music = new Music() - #player = new Player() - #background = new Background() - #logo = new Logo() + #voice + #music + #player + #background + #logo #insight = new Insight() constructor(appEl) { @@ -32,18 +33,16 @@ export default class AKLive2D { document.addEventListener("gesturestart", e => e.preventDefault()); this.#appEl = appEl - } - - init() { - this.#logo.init(this.#appEl); - this.#background.init(this.#appEl); - this.#voice.init(this.#appEl); - this.#music.init(this.#appEl); + this.#logo = new Logo(this.#appEl) + this.#background = new Background(this.#appEl) + this.#voice = new Voice(this.#appEl) + this.#music = new Music(this.#appEl) if (isWebGLSupported()) { - this.#player.init(this.#appEl); + this.#player = new Player(this.#appEl) } else { - (new Fallback()).init(this.#appEl) + new Fallback(this.#appEl) } + this.#el.id = "settings-box" this.#el.hidden = true this.#el.innerHTML = ` @@ -63,15 +62,8 @@ export default class AKLive2D { insertHTMLChild(this.#appEl, this.#el) addEventListeners([ { - event: "player-ready", handler: () => this.success() - }, - ...this.#logo.listeners, - ...this.#background.listeners, - ...this.#player.listeners, - ...this.#voice.listeners, - ...this.#music.listeners, - ...this.#insight.listeners, - { + event: "player-ready", handler: () => this.#success() + }, { id: "settings-reset", event: "click", handler: () => this.reset() }, { id: "settings-close", event: "click", handler: () => this.close() @@ -79,10 +71,54 @@ export default class AKLive2D { id: "settings-to-directory", event: "click", handler: () => { window.location.href = '/'; } - } + }, + ...this.#logo.listeners, + ...this.#background.listeners, + ...this.#player.listeners, + ...this.#voice.listeners, + ...this.#music.listeners, + ...this.#insight.listeners, ]) } + get voice() { + return this.#voice + } + + get music() { + return this.#music + } + + get player() { + return this.#player + } + + get background() { + return this.#background + } + + get logo() { + return this.#logo + } + + get events() { + return Event + } + + get config() { + return { + player: this.#player.config, + background: this.#background.config, + logo: this.#logo.config, + music: this.#music.config, + voice: this.#voice.config + } + } + + get configStr() { + return JSON.stringify(this.config, null) + } + open() { this.#el.hidden = false; } @@ -96,59 +132,36 @@ export default class AKLive2D { this.#background.reset() this.#logo.reset() this.#voice.reset() + this.#music.reset() } - success() { + #success() { this.#music.link(this.#background) this.#background.link(this.#music) this.#voice.link(this.#player) + this.#player.success() this.#voice.success() this.#music.success() this.#insight.success() - if (this.#queries.has("settings") || this.#queries.has("aklive2d") || import.meta.env.MODE === 'development') { + if (this.#queries.has("aklive2d") || import.meta.env.MODE === 'development') { this.open() } - this.#backCompatibility() + this.#registerBackCompatibilityFns() } - #backCompatibility() { - window.voice = this.#voice - window.music = this.#music + #registerBackCompatibilityFns() { + const _this = this + window.voice = _this.#voice + window.music = _this.#music window.settings = { - spinePlayer: this.#player.spine, - setFPS: this.#player.setFPS, - setLogoDisplay: this.#logo.setLogoDisplay, - setLogo: this.#logo.setLogo, - setLogoImage: this.#logo.setLogoImage, - resetLogoImage: this.#logo.resetLogoImage, - setLogoRatio: this.#logo.setLogoRatio, - setLogoOpacity: this.#logo.setLogoOpacity, - setBackgoundImage: this.#background.setBackgroundImage, - currentBackground: this.#background.currentBackground, - setDefaultBackground: this.#background.setDefaultBackground, - setBackground: this.#background.setBackground, - resetBackground: this.#background.resetBackground, - loadViewport: this.#player.loadViewport, - setScale: this.#player.setScale, - scale: this.#player.scale, - positionPadding: this.#player.positionPadding, - positionReset: this.#player.positionReset, - scaleReset: this.#player.scaleReset, elementPosition: updateElementPosition, - logoPadding: this.#logo.logoPadding, - logoReset: this.#logo.logoReset, - useStartAnimation: this.#player.useStartAnimation, - open: this.open, - close: this.close, - reset: this.reset, - setMusicFromWE: this.#music.setMusicFromWE, - setMusic: this.#music.setMusic, - resetMusic: this.#music.resetMusic, - setVideo: this.#background.setVideo, - setVideoVolume: this.#background.setVideoVolume, - getVideoVolume: this.#background.getVideoVolume, - setVideoFromWE: this.#background.setVideoFromWE, - resetVideo: this.#background.resetVideo + open: _this.open, + close: _this.close, + reset: _this.reset, + ..._this.#player.backCompatibilityFns, + ..._this.#logo.backCompatibilityFns, + ..._this.#music.backCompatibilityFns, + ..._this.#background.backCompatibilityFns } } } \ No newline at end of file diff --git a/showcase/src/components/background.js b/showcase/src/components/background.js index 53b5dca..a84bfa3 100644 --- a/showcase/src/components/background.js +++ b/showcase/src/components/background.js @@ -16,11 +16,16 @@ export default class Background { image: "operator_bg.png" } #config = { - image: null + video: { + name: null, + volume: 100, + }, + useVideo: false, + name: null } #musicObj - init(el) { + constructor(el) { this.#parentEl = el this.#el.id = "background-box" this.image = this.#default.location + this.#default.image @@ -31,119 +36,20 @@ export default class Background { this.#videoEl = document.getElementById("video-src") } - set image(v) { - this.#el.style.backgroundImage = `url("${v}")` - } - - set video(v) { - const update = (url) => { - this.#videoEl.src = url - this.#videoEl.load() - document.getElementById("custom-video-background-clear").disabled = false - } - if (typeof v === "object") { - readFile( - v, - (blobURL) => update(blobURL) - ) - } else { - update(v) - } - } - - get volume() { - return this.#videoEl.volume * 100 - } - - set volume(v) { - this.#videoEl.volume = parseInt(v) / 100 - } - - get current() { - return this.#config.image || this.#default.image - } - - set default(v) { - this.#default.image = v - if (!this.#config.image) { - this.image = this.#default.location + this.#default.image - } - } - - set custom(v) { - const update = (url) => { - this.#config.image = v - this.image = url - document.getElementById("custom-background-clear").disabled = false - } - if (typeof v === "object") { - readFile( - v, - (blobURL) => update(blobURL) - ) - } else { - update(v) - } - } - - setVideoFromWE(url) { - // Note: Back Compatibility - this.video = url - } - - get currentBackground() { - // Note: Back Compatibility - return this.current - } - resetImage() { document.getElementById("custom-background").value = "" document.getElementById("custom-background-clear").disabled = true - this.#config.image = null + this.#config.name = null this.image = this.#default.location + this.#default.image } resetVideo() { + this.#config.video.name = null this.#videoEl.src = "" document.getElementById("custom-video-background").value = "" document.getElementById("custom-video-background-clear").disabled = true } - setBackgroundImage(v) { - // Note: Back Compatibility - this.image = v - } - - setDefaultBackground(v) { - // Note: Back Compatibility - this.default = v - } - - setBackground(v) { - // Note: Back Compatibility - this.custom = v - } - - resetBackground() { - // Note: Back Compatibility - this.resetImage() - } - - setVideo(e) { - // Note: Back Compatibility - this.video = e.target.files[0] - } - - getVideoVolume() { - // Note: Back Compatibility - return this.volume - } - - setVideoVolume(v) { - // Note: Back Compatibility - this.volume = v - } - reset() { this.resetImage() this.resetVideo() @@ -153,6 +59,100 @@ export default class Background { this.#musicObj = musicObj } + get useVideo() { + return this.#config.useVideo + } + + set useVideo(v) { + this.#config.useVideo = v + } + + set image(v) { + this.#el.style.backgroundImage = `url("${v}")` + } + + set video(v) { + const update = (url, v = null) => { + this.#config.video.name = { + isLocalFile: v !== null, + value: v ? v.name : url + } + this.#videoEl.src = url + this.#videoEl.load() + document.getElementById("custom-video-background-clear").disabled = false + } + if (typeof v === "object") { + readFile( + v, + (blobURL) => update(blobURL, v) + ) + } else { + update(v) + } + } + + get volume() { + return this.#config.video.volume + } + + set volume(v) { + v = parseInt(v) + this.#config.video.volume = v + this.#videoEl.volume = v / 100 + } + + get current() { + return this.#config.name || this.#default.image + } + + set default(v) { + this.#default.image = v + this.#musicObj.music = v + this.image = this.#default.location + this.#default.image + } + + set custom(v) { + const update = (url, v = null) => { + this.#config.name = { + isLocalFile: v !== null, + value: v ? v.name : url + } + this.image = url + document.getElementById("custom-background-clear").disabled = false + } + if (typeof v === "object") { + readFile( + v, + (blobURL) => update(blobURL, v) + ) + } else { + update(v) + } + } + + get config() { + return { + default: this.#default.image, + ...this.#config + } + } + + get backCompatibilityFns() { + const _this = this + return { + currentBackground: _this.current, + setBackgoundImage: (v) => _this.image = v, + setDefaultBackground: (v) => _this.default = v, + setBackground: (v) => _this.custom = v, + resetBackground: _this.resetImage, + setVideo: (e) => _this.video = e.target.files[0], + getVideoVolume: () => _this.volume, + setVideoVolume: (v) => _this.volume = v, + setVideoFromWE: (url) => _this.video = url, + resetVideo: _this.resetVideo + } + } + get HTML() { return `
@@ -163,19 +163,29 @@ export default class Background {
- + - + +
+
+ + +
- -