Add fadeIn/fadeOut for bg, sprites and audio
This commit is contained in:
parent
60f5efdace
commit
cc3e39c6b9
62
src/utils/UIUtils.ts
Normal file
62
src/utils/UIUtils.ts
Normal file
@ -0,0 +1,62 @@
|
||||
export class UIUtils {
|
||||
|
||||
public static removeElement(el: HTMLElement): void {
|
||||
el.parentNode.removeChild(el)
|
||||
}
|
||||
|
||||
public static fadeIn(
|
||||
element: HTMLElement,
|
||||
duration = 200,
|
||||
onFinish: () => void = () => {}
|
||||
): void {
|
||||
return UIUtils.fade(element, duration, 0, 1, onFinish);
|
||||
}
|
||||
|
||||
public static fadeOut(
|
||||
element: HTMLElement,
|
||||
duration = 200,
|
||||
onFinish: () => void = () => {}
|
||||
): void {
|
||||
return UIUtils.fade(element, duration, 1, 0, onFinish);
|
||||
}
|
||||
|
||||
public static fade(
|
||||
element: HTMLElement,
|
||||
duration = 200,
|
||||
fromValue = 0, toValue = 1,
|
||||
onFinish: () => void = () => {}
|
||||
): void {
|
||||
const setter = (v: number) => element.style.opacity = v.toString();
|
||||
return UIUtils.animate(setter, duration, fromValue, toValue, onFinish);
|
||||
}
|
||||
|
||||
public static animate(
|
||||
setter: (value: number) => void,
|
||||
duration = 200,
|
||||
fromValue = 0,
|
||||
toValue = 1,
|
||||
onFinish: () => void = () => {}
|
||||
): void {
|
||||
if (duration <= 0) {
|
||||
setter(toValue);
|
||||
onFinish()
|
||||
return;
|
||||
}
|
||||
|
||||
setter(fromValue);
|
||||
const startTime = Date.now();
|
||||
const callback = () => {
|
||||
const currentTime = Date.now();
|
||||
const timeDiff = Math.min((currentTime - startTime) / duration, 1);
|
||||
const value = fromValue - (fromValue - toValue) * timeDiff;
|
||||
if (timeDiff >= 1) {
|
||||
setter(toValue)
|
||||
onFinish()
|
||||
} else {
|
||||
setter(value)
|
||||
requestAnimationFrame(callback)
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(callback);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { PathResolver } from "../utils/PathResolver";
|
||||
import { TextUtils } from "../utils/TextUtils";
|
||||
import { UIUtils } from "../utils/UIUtils";
|
||||
import { Characters } from "./model/Characters";
|
||||
import { FadeInfo } from "./model/FadeInfo";
|
||||
import { MapPlaces } from "./model/MapPlaces";
|
||||
@ -15,9 +16,12 @@ export class MainView implements ViewModel {
|
||||
private places: MapPlaces;
|
||||
private characters: Characters;
|
||||
|
||||
private windowTag: HTMLElement;
|
||||
private textAuthorTag: HTMLElement;
|
||||
private textContentTag: HTMLElement;
|
||||
private readonly elWindow = document.getElementById('window');
|
||||
private readonly elTextAuthor = document.getElementById('textAuthor');
|
||||
private readonly elTextContent = document.getElementById('textContent');
|
||||
private readonly elBackground1 = document.getElementById('background1');
|
||||
private readonly elBackground2 = document.getElementById('background2');
|
||||
private readonly elMenu = document.getElementById('menu');
|
||||
|
||||
private musicPlayerAudio: HTMLAudioElement;
|
||||
private soundPlayerAudio: HTMLAudioElement;
|
||||
@ -37,10 +41,6 @@ export class MainView implements ViewModel {
|
||||
private nextCommandRunnable: () => void;
|
||||
|
||||
constructor(private debug: boolean = false) {
|
||||
this.windowTag = document.getElementById('window');
|
||||
this.textAuthorTag = document.getElementById('textAuthor');
|
||||
this.textContentTag = document.getElementById('textContent');
|
||||
|
||||
this.musicPlayerAudio = new Audio();
|
||||
this.soundPlayerAudio = new Audio();
|
||||
this.soundLoopPlayerAudio = new Audio();
|
||||
@ -65,7 +65,7 @@ export class MainView implements ViewModel {
|
||||
this.places = places;
|
||||
this.characters = characters;
|
||||
characters.init();
|
||||
document.getElementById('menu').style.display = 'none';
|
||||
this.elMenu.style.display = 'none';
|
||||
document.getElementById('mainMenuButton').onclick = (e) => this.showMainMenu();
|
||||
document.getElementById('background').onclick = (e) => this.onTouch(e);
|
||||
this.nextCommandRunnable = () => {
|
||||
@ -76,7 +76,7 @@ export class MainView implements ViewModel {
|
||||
|
||||
private onTouch(e: MouseEvent): void {
|
||||
if (this.blockTap) return;
|
||||
if (document.getElementById('menu').style.display !== 'none') return;
|
||||
if (this.elMenu.style.display !== 'none') return;
|
||||
if ((e.target as HTMLElement).tagName.toLowerCase() === 'li') return;
|
||||
if ((e.target as HTMLElement).id === 'mainMenuButton') return;
|
||||
|
||||
@ -85,11 +85,11 @@ export class MainView implements ViewModel {
|
||||
}
|
||||
|
||||
public text(text: string): void {
|
||||
this.textAuthorTag.innerText = '';
|
||||
this.elTextAuthor.innerText = '';
|
||||
if (TextUtils.isEmpty(text)) this.windowHide("");
|
||||
else {
|
||||
this.windowShow("");
|
||||
this.formatString(this.textContentTag, text);
|
||||
this.formatString(this.elTextContent, text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,9 +99,9 @@ export class MainView implements ViewModel {
|
||||
else {
|
||||
this.windowShow("");
|
||||
const person = this.characters.get(whoid);
|
||||
this.textAuthorTag.textContent = person.name;
|
||||
this.textAuthorTag.style.color = this.toColor(person.color);
|
||||
this.formatString(this.textContentTag, text);
|
||||
this.elTextAuthor.textContent = person.name;
|
||||
this.elTextAuthor.style.color = this.toColor(person.color);
|
||||
this.formatString(this.elTextContent, text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,9 +109,9 @@ export class MainView implements ViewModel {
|
||||
let edited = TextUtils.replaceAll(text, "\\{w.*?\\}", "");
|
||||
if (TextUtils.contains(edited, "{center}")) {
|
||||
edited = TextUtils.replaceAll(edited, "\\{center\\}", "");
|
||||
this.textContentTag.style.textAlign = "center";
|
||||
this.elTextContent.style.textAlign = "center";
|
||||
} else {
|
||||
this.textContentTag.style.textAlign = "left";
|
||||
this.elTextContent.style.textAlign = "left";
|
||||
}
|
||||
if (TextUtils.contains(edited, "{html}")) {
|
||||
edited = TextUtils.replaceAll(edited, "\\{html\\}", "");
|
||||
@ -155,36 +155,30 @@ export class MainView implements ViewModel {
|
||||
}
|
||||
|
||||
let animationTime = 0;
|
||||
document.getElementById('background1').style.background = document.getElementById('background2').style.background;
|
||||
document.getElementById('background1').style.display = 'block';
|
||||
this.elBackground1.style.background = this.elBackground2.style.background;
|
||||
this.elBackground1.style.display = 'block';
|
||||
if (effect in Transition.DEFAULT) {
|
||||
const transition = Transition.DEFAULT[effect];
|
||||
if (transition["type"] === TransitionType.TYPE_FADE) {
|
||||
animationTime = transition["inTime"] + transition["outTime"];
|
||||
document.getElementById('background2').style.display = 'none';
|
||||
document.getElementById('background2').style.background = background;
|
||||
document.getElementById('background2').style.backgroundSize = 'cover';
|
||||
|
||||
// TODO
|
||||
//$('#background1').fadeOut(transition["outTime"], function () {
|
||||
// $('#background2').fadeIn(transition["inTime"], function () {
|
||||
// $('#background1').hide();
|
||||
// $(this).show();
|
||||
// });
|
||||
//});
|
||||
document.getElementById('background1').style.display = 'none';
|
||||
document.getElementById('background2').style.display = 'block';
|
||||
document.getElementById('background2').style.backgroundSize = 'cover';
|
||||
this.elBackground2.style.display = 'none';
|
||||
this.elBackground2.style.background = background;
|
||||
this.elBackground2.style.backgroundSize = 'cover';
|
||||
|
||||
UIUtils.fadeOut(this.elBackground1, transition["outTime"], () => {
|
||||
this.elBackground2.style.display = 'block';
|
||||
this.elBackground1.style.display = 'none';
|
||||
UIUtils.fadeIn(this.elBackground2, transition["inTime"]);
|
||||
});
|
||||
this.pause(animationTime, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('background1').style.display = 'none';
|
||||
document.getElementById('background2').style.background = background;
|
||||
document.getElementById('background2').style.backgroundSize = 'cover';
|
||||
document.getElementById('background1').style.display = 'block';
|
||||
this.elBackground1.style.display = 'none';
|
||||
this.elBackground2.style.background = background;
|
||||
this.elBackground2.style.backgroundSize = 'cover';
|
||||
this.elBackground1.style.display = 'block';
|
||||
this.pause(animationTime, false);
|
||||
}
|
||||
|
||||
@ -207,11 +201,9 @@ export class MainView implements ViewModel {
|
||||
img.onload = () => {
|
||||
this.setSpritePosition(img, position);
|
||||
if (effect in Transition.DEFAULT) {
|
||||
var transition = Transition.DEFAULT[effect];
|
||||
const transition = Transition.DEFAULT[effect];
|
||||
if (transition["type"] === TransitionType.TYPE_FADE) {
|
||||
// img.style.display = 'none';
|
||||
// TODO
|
||||
// $(this).hide().fadeIn(transition["inTime"]);
|
||||
UIUtils.fadeIn(img, transition["inTime"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -239,16 +231,14 @@ export class MainView implements ViewModel {
|
||||
if (effect in Transition.DEFAULT) {
|
||||
const transition = Transition.DEFAULT[effect];
|
||||
if (transition["type"] === TransitionType.TYPE_FADE) {
|
||||
// TODO
|
||||
//img.fadeOut(transition["outTime"], function () {
|
||||
// $(this).remove();
|
||||
//});
|
||||
img.remove();
|
||||
UIUtils.fadeOut(
|
||||
img, transition["outTime"],
|
||||
() => UIUtils.removeElement(img));
|
||||
} else {
|
||||
img.remove();
|
||||
UIUtils.removeElement(img);
|
||||
}
|
||||
} else {
|
||||
img.remove();
|
||||
UIUtils.removeElement(img);
|
||||
}
|
||||
delete this.spriteInContainer[whoid];
|
||||
}
|
||||
@ -298,12 +288,12 @@ export class MainView implements ViewModel {
|
||||
menuContainer.appendChild(li);
|
||||
i++;
|
||||
}
|
||||
document.getElementById('menu').style.display = 'block';
|
||||
this.elMenu.style.display = 'block';
|
||||
}
|
||||
|
||||
private createMenuItemClickFunction(pos: number) {
|
||||
return function () {
|
||||
document.getElementById('menu').style.display = 'none';
|
||||
this.elMenu.style.display = 'none';
|
||||
this.navigable.setPosition(pos);
|
||||
};
|
||||
}
|
||||
@ -319,7 +309,7 @@ export class MainView implements ViewModel {
|
||||
this.addMainMenuItem("Next scene", () => this.navigable.nextScene());
|
||||
// TODO
|
||||
this.addMainMenuItem("Save", () => {
|
||||
document.getElementById('menu').style.display = 'none';
|
||||
this.elMenu.style.display = 'none';
|
||||
// this.saveState();
|
||||
});
|
||||
const saves = JSON.parse(localStorage.saves || null) || {};
|
||||
@ -329,9 +319,9 @@ export class MainView implements ViewModel {
|
||||
// this.addMainMenuItem("Delete…", () => this.showRemoveStateMenu());
|
||||
//}
|
||||
this.addMainMenuItem("Close", () => {
|
||||
document.getElementById('menu').style.display = 'none';
|
||||
this.elMenu.style.display = 'none';
|
||||
});
|
||||
document.getElementById('menu').style.display = 'block';
|
||||
this.elMenu.style.display = 'block';
|
||||
}
|
||||
|
||||
private addMainMenuItem(name: string, func: () => void) {
|
||||
@ -351,12 +341,12 @@ export class MainView implements ViewModel {
|
||||
li.onclick = this.createMapPlaceClickFunction(key);
|
||||
menuContainer.appendChild(li);
|
||||
}
|
||||
document.getElementById('menu').style.display = 'block';
|
||||
this.elMenu.style.display = 'block';
|
||||
}
|
||||
|
||||
private createMapPlaceClickFunction(zoneLabel: string): () => void {
|
||||
return () => {
|
||||
document.getElementById('menu').style.display = 'none';
|
||||
this.elMenu.style.display = 'none';
|
||||
this.navigable.jumpLabel(zoneLabel);
|
||||
this.navigable.next();
|
||||
};
|
||||
@ -406,9 +396,10 @@ export class MainView implements ViewModel {
|
||||
});
|
||||
this.musicPlayerAudio.play();
|
||||
if (fade.fadeIn) {
|
||||
this.musicPlayerAudio.volume = 0.0;
|
||||
// TODO
|
||||
// $(this.musicPlayerAudio).animate({ volume: 1.0 }, fade.duration * 1000);
|
||||
UIUtils.animate(
|
||||
(value: number) => this.musicPlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
0, 1);
|
||||
} else {
|
||||
this.musicPlayerAudio.volume = 1.0;
|
||||
}
|
||||
@ -429,9 +420,10 @@ export class MainView implements ViewModel {
|
||||
});
|
||||
this.soundPlayerAudio.play();
|
||||
if (fade.fadeIn) {
|
||||
this.soundPlayerAudio.volume = 0.0;
|
||||
// TODO
|
||||
// $(this.soundPlayerAudio).animate({ volume: 1.0 }, fade.duration * 1000);
|
||||
UIUtils.animate(
|
||||
(value: number) => this.soundPlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
0, 1);
|
||||
} else {
|
||||
this.soundPlayerAudio.volume = 1.0;
|
||||
}
|
||||
@ -451,10 +443,12 @@ export class MainView implements ViewModel {
|
||||
});
|
||||
this.soundLoopPlayerAudio.play();
|
||||
if (fade.fadeIn) {
|
||||
// $(this.soundLoopPlayerAudio).prop("volume", 0.0);
|
||||
// $(this.soundLoopPlayerAudio).animate({ volume: 1.0 }, fade.duration * 1000);
|
||||
UIUtils.animate(
|
||||
(value: number) => this.soundLoopPlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
0, 1);
|
||||
} else {
|
||||
// $(this.soundLoopPlayerAudio).prop("volume", 1.0);
|
||||
this.soundLoopPlayerAudio.volume = 1.0;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("soundloop: " + name + " " + e);
|
||||
@ -472,10 +466,12 @@ export class MainView implements ViewModel {
|
||||
});
|
||||
this.ambiencePlayerAudio.play();
|
||||
if (fade.fadeIn) {
|
||||
// $(this.ambiencePlayerAudio).prop("volume", 0.0);
|
||||
// $(this.ambiencePlayerAudio).animate({ volume: 1.0 }, fade.duration * 1000);
|
||||
UIUtils.animate(
|
||||
(value: number) => this.ambiencePlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
0, 1);
|
||||
} else {
|
||||
// $(this.ambiencePlayerAudio).prop("volume", 1.0);
|
||||
this.ambiencePlayerAudio.volume = 1.0;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("ambience: " + name + " " + e);
|
||||
@ -502,10 +498,10 @@ export class MainView implements ViewModel {
|
||||
if (this.musicPlayerAudio.paused) return;
|
||||
|
||||
if (fade.fadeOut) {
|
||||
// TODO
|
||||
// $(this.musicPlayerAudio).animate({ volume: 0.0 }, fade.duration * 1000, function () {
|
||||
// this.pause();
|
||||
// });
|
||||
UIUtils.animate(
|
||||
(value: number) => this.musicPlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
1, 0, () => this.musicPlayerAudio.pause());
|
||||
} else {
|
||||
this.musicPlayerAudio.pause();
|
||||
}
|
||||
@ -515,9 +511,10 @@ export class MainView implements ViewModel {
|
||||
if (this.soundPlayerAudio.paused) return;
|
||||
|
||||
if (fade.fadeOut) {
|
||||
// $(this.soundPlayerAudio).animate({ volume: 0.0 }, fade.duration * 1000, function () {
|
||||
this.soundPlayerAudio.pause();
|
||||
// });
|
||||
UIUtils.animate(
|
||||
(value: number) => this.soundPlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
1, 0, () => this.soundPlayerAudio.pause());
|
||||
} else {
|
||||
this.soundPlayerAudio.pause();
|
||||
}
|
||||
@ -527,9 +524,10 @@ export class MainView implements ViewModel {
|
||||
if (this.soundLoopPlayerAudio.paused) return;
|
||||
|
||||
if (fade.fadeOut) {
|
||||
// $(this.soundLoopPlayerAudio).animate({ volume: 0.0 }, fade.duration * 1000, function () {
|
||||
this.soundLoopPlayerAudio.pause();
|
||||
// });
|
||||
UIUtils.animate(
|
||||
(value: number) => this.soundLoopPlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
1, 0, () => this.soundLoopPlayerAudio.pause());
|
||||
} else {
|
||||
this.soundLoopPlayerAudio.pause();
|
||||
}
|
||||
@ -539,17 +537,18 @@ export class MainView implements ViewModel {
|
||||
if (this.ambiencePlayerAudio.paused) return;
|
||||
|
||||
if (fade.fadeOut) {
|
||||
// $(this.ambiencePlayerAudio).animate({ volume: 0.0 }, fade.duration * 1000, function () {
|
||||
this.ambiencePlayerAudio.pause();
|
||||
// });
|
||||
UIUtils.animate(
|
||||
(value: number) => this.ambiencePlayerAudio.volume = value,
|
||||
fade.duration * 1000,
|
||||
1, 0, () => this.ambiencePlayerAudio.pause());
|
||||
} else {
|
||||
this.ambiencePlayerAudio.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public windowShow(effect: string): boolean {
|
||||
if (this.windowTag.style.visibility !== "visible") {
|
||||
this.windowTag.style.visibility = "visible";
|
||||
if (this.elWindow.style.visibility !== "visible") {
|
||||
this.elWindow.style.visibility = "visible";
|
||||
}
|
||||
if (!TextUtils.isEmpty(effect)) {
|
||||
this.background(this.backgroundType, this.backgroundName, effect);
|
||||
@ -559,8 +558,8 @@ export class MainView implements ViewModel {
|
||||
}
|
||||
|
||||
public windowHide(effect: string): boolean {
|
||||
if (this.windowTag.style.visibility !== "hidden") {
|
||||
this.windowTag.style.visibility = "hidden";
|
||||
if (this.elWindow.style.visibility !== "hidden") {
|
||||
this.elWindow.style.visibility = "hidden";
|
||||
}
|
||||
if (!TextUtils.isEmpty(effect)) {
|
||||
this.background(this.backgroundType, this.backgroundName, effect);
|
||||
@ -570,10 +569,10 @@ export class MainView implements ViewModel {
|
||||
}
|
||||
|
||||
private windowSwitchVisibility(): void {
|
||||
if (this.windowTag.style.visibility === "hidden") {
|
||||
this.windowTag.style.visibility = "visible";
|
||||
if (this.elWindow.style.visibility === "hidden") {
|
||||
this.elWindow.style.visibility = "visible";
|
||||
} else {
|
||||
this.windowTag.style.visibility = "hidden";
|
||||
this.elWindow.style.visibility = "hidden";
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user