@pilotlab/lux-tools
Version:
A luxurious user experience framework, developed by your friends at Pilot.
414 lines (413 loc) • 19.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const is = require("@pilotlab/lux-is");
const lux_audio_1 = require("@pilotlab/lux-audio");
const lux_animation_1 = require("@pilotlab/lux-animation");
const lux_initializable_1 = require("@pilotlab/lux-initializable");
const lux_commands_1 = require("@pilotlab/lux-commands");
const lux_debug_1 = require("@pilotlab/lux-debug");
const lux_detector_1 = require("@pilotlab/lux-detector");
const lux_fonts_1 = require("@pilotlab/lux-fonts");
const lux_elements_1 = require("@pilotlab/lux-elements");
const lux_signals_1 = require("@pilotlab/lux-signals");
const lux_types_1 = require("@pilotlab/lux-types");
const appContext_1 = require("./appContext");
const appEnums_1 = require("./appEnums");
class AppManager extends lux_initializable_1.Initializable {
constructor() {
super();
this._isOnline = false;
this._buildEnvironment = appEnums_1.BuildEnvironment.DEVELOPMENT;
this._appWidth = 1920;
this._appHeight = 1080;
this._appScale = 1;
this._deviceScreen = new Element();
this.p_commands = new lux_commands_1.CommandManager(true);
this.p_fonts = new lux_fonts_1.FontManager();
this.p_audio = new lux_audio_1.AudioManager();
this.isAudioOn = false;
this._deviceScaleFactor = null;
this.durationQuick = 0.5;
this.durationNormal = 1.0;
this.durationLong = 1.5;
this.animEaseDefault = lux_animation_1.AnimationEaseQuartic.easeOut;
this.initialized = new lux_signals_1.Signal(true);
this.layoutChanged = new lux_signals_1.Signal(false);
this.onlineStarted = new lux_signals_1.Signal(false);
this.offlineStarted = new lux_signals_1.Signal(false);
}
get isOnline() { return this._isOnline; }
get appContext() { return this._appContext; }
get viewport() { return this._viewport; }
get buildEnvironment() { return this._buildEnvironment; }
set buildEnvironment(value) {
this._buildEnvironment = value;
lux_debug_1.default.isDebugLoggingOn = (value === appEnums_1.BuildEnvironment.DEVELOPMENT || value === appEnums_1.BuildEnvironment.TESTING);
}
get appWidth() { return this._appWidth; }
get appHeight() { return this._appHeight; }
get appScale() { return this._appScale; }
get root() { return this._root; }
get deviceScreen() { return this._deviceScreen; }
get appRootElement() { return this._appRootElement; }
get commands() { return this.p_commands; }
get fonts() { return this.p_fonts; }
get audio() { return this.p_audio; }
get colorVeryLight() { return new lux_types_1.Color(255, 255, 255); }
get colorLight() { return new lux_types_1.Color(240, 240, 240); }
get colorDark() { return new lux_types_1.Color(80, 80, 80); }
get colorVeryDark() { return new lux_types_1.Color(35, 31, 32); }
get colorGrayLight() { return lux_types_1.Color.fromHex('#e2e2e2'); }
get colorGrayMediumLight() { return lux_types_1.Color.fromHex('#c5c5c5'); }
get colorGray() { return lux_types_1.Color.fromHex('#9e9e9e'); }
get colorGrayMediumDark() { return lux_types_1.Color.fromHex('#6f6f6f'); }
get colorGrayDark() { return lux_types_1.Color.fromHex('#9e9e9e'); }
get colorAccent() { return new lux_types_1.Color(25, 230, 140); }
get colorBody() { return this.colorVeryLight; }
get colorAppBackground() { return new lux_types_1.Color(0, 0, 0); }
static get isFullscreen() {
let doc = document;
let isFullscreen = false;
if (doc.fullscreenElement ||
doc.webkitFullscreenElement ||
doc.mozFullScreenElement ||
doc.msFullscreenElement)
isFullscreen = true;
else if (window.innerHeight == screen.size.y)
isFullscreen = true;
else if ((screen.availHeight || screen.size.y - 30) <= window.innerHeight) {
isFullscreen = true;
}
return isFullscreen;
}
static fullscreenToggle() {
if (AppManager.isFullscreen)
AppManager.fullscreenExit();
else
AppManager.fullscreenEnter();
}
static fullscreenEnter() {
let docElem = document.documentElement;
if (lux_detector_1.default.isChromeApp) {
let win = window;
win.chrome.app.window.current().fullscreen();
}
else if (docElem.requestFullscreen)
docElem.requestFullscreen();
else if (docElem.mozRequestFullScreen)
docElem.mozRequestFullScreen();
else if (docElem.webkitRequestFullScreen)
docElem.webkitRequestFullScreen();
}
static fullscreenExit() {
let doc = document;
if (lux_detector_1.default.isChromeApp) {
let win = window;
win.chrome.app.window.current().restore();
}
else if (doc.exitFullscreen)
doc.exitFullscreen();
else if (doc.webkitExitFullscreen)
doc.webkitExitFullscreen();
else if (doc.webkitCancelFullscreen)
doc.webkitCancelFullscreen();
else if (doc.mozCancelFullScreen)
doc.mozCancelFullScreen();
else if (doc.msExitFullscreen)
doc.msExitFullscreen();
}
initialize(renderer, appContext, appRootElement) {
return super.initialize(renderer, appContext, appRootElement);
}
p_onInitializeStarted(result, args) {
this.p_initializeApp(args[0], args[1], args[2]);
result.resolve();
return result;
}
p_initializeApp(renderer, appContext, appRootElement) {
if (this.isInitialized)
return false;
lux_animation_1.Animation.initialize();
if (is.empty(renderer))
renderer = new RendererCanvas();
if (is.empty(appContext))
appContext = new appContext_1.AppContextDesktop();
if (is.empty(appRootElement))
appRootElement = new Element();
this._appContext = appContext;
if (is.notEmpty(this._appContext) && lux_detector_1.default.isMobile) {
if (lux_detector_1.default.isSupportedDeviceOrientationEvent) {
window.addEventListener('deviceorientation', () => { this.p_layoutChanged(); }, false);
}
else
window.addEventListener('orientationchange', () => { this.p_layoutChanged(); });
}
let resizeCommand = new lux_commands_1.ThrottlingCommand(() => {
if (lux_detector_1.default.isAndroid) {
let dif = window.innerWidth / this.root.size.x;
let round = Math.round(dif * 100) / 100;
if ((window.orientation !== undefined && window.orientation !== this.deviceScreen.rotation.z)
|| round !== 1)
this.p_layoutChanged();
}
else
this.p_layoutChanged();
}, null, this, 100);
if (!lux_detector_1.default.isAppleMobile) {
window.addEventListener('resize', (e) => resizeCommand.throttle());
}
document.body.style.backgroundColor = this.colorBody.toHex();
this._root = new lux_elements_1.ElementRoot(renderer, this);
this.root.mouseMoveInterval = lux_detector_1.default.isMobile ? 1 : 0;
this.root.style.background.color = lux_types_1.Color.empty;
this.root.isPropagateUserInputEvents = true;
document.body.appendChild(this.root.element);
if (lux_detector_1.default.isMobile) {
let viewport = document.head.querySelector('meta[name=viewport]');
if (is.notEmpty(viewport))
this._viewport = viewport;
else {
this._viewport = document.createElement('meta');
this._viewport.name = 'viewport';
document.head.appendChild(this._viewport);
}
}
this.deviceScreen.pivot.x = 0.5;
this.deviceScreen.pivot.y = 0.5;
this.deviceScreen.isClipChildElements = true;
this.deviceScreen.isPropagateUserInputEvents = true;
this.deviceScreen.style.background.color = lux_types_1.Color.empty;
this.root.children.addByName(this.deviceScreen, 'deviceScreen');
this._appRootElement = appRootElement;
this.deviceScreen.children.addByName(this.appRootElement, 'appRoot');
this.root.animate.ticked.listen((elapsedMilliseconds) => {
if (!this.isAudioOn)
return;
this.p_audio.tick(elapsedMilliseconds);
});
window.addEventListener('online', () => {
this._isOnline = true;
this.p_online();
this.onlineStarted.dispatch(this);
}, false);
window.addEventListener('offline', () => {
this._isOnline = false;
this.p_offline();
this.offlineStarted.dispatch(this);
}, false);
this.p_layoutChanged();
return true;
}
setLayout(appContext, w, h, browserZoom, screenOrientation) {
if (is.empty(this.root) || is.empty(appContext))
return;
if (appContext.deviceTarget === appContext_1.DeviceType.MOBILE) {
let appContextMobile = appContext;
if (appContextMobile.orientationMode === appEnums_1.Orientation.VERTICAL) {
if (screenOrientation === appEnums_1.Orientation.VERTICAL) {
this.setMobileLayout(appContextMobile, w, h, false);
}
else {
this.setMobileLayout(appContextMobile, w, h, true);
}
}
else if (appContextMobile.orientationMode === appEnums_1.Orientation.HORIZONTAL) {
if (screenOrientation === appEnums_1.Orientation.HORIZONTAL) {
this.setMobileLayout(appContextMobile, w, h, false);
}
else {
this.setMobileLayout(appContextMobile, w, h, true);
}
}
else {
this.setMobileLayout(appContextMobile, w, h, false);
}
if (!lux_detector_1.default.isMobile && is.notEmpty(appContextMobile.emulationContext)) {
this._appScale = 0.5;
}
}
else {
this.setDesktopRootLayout(appContext, w, h, browserZoom, true);
}
}
setDesktopRootLayout(appContextDesktop, screenWidth, screenHeight, browserZoom = 1, isSetAppDimensions = false) {
if (is.empty(appContextDesktop)
|| (is.empty(appContextDesktop.widthPreferred)
&& is.empty(appContextDesktop.heightPreferred))) {
this.fitRoot(screenWidth, screenHeight, browserZoom);
if (isSetAppDimensions) {
this._appWidth = screenWidth;
this._appHeight = screenHeight;
}
}
else if (is.notEmpty(appContextDesktop.widthPreferred)
&& is.notEmpty(appContextDesktop.heightPreferred)) {
let rootAspectRatio = appContextDesktop.heightPreferred / appContextDesktop.widthPreferred;
this.forceRootAspectRatio(screenWidth, screenHeight, rootAspectRatio, browserZoom);
if (isSetAppDimensions) {
this._appWidth = appContextDesktop.widthPreferred;
this._appHeight = appContextDesktop.heightPreferred;
}
}
else if (is.notEmpty(appContextDesktop.widthPreferred)) {
let widthFinal = this.appContext.widthPreferred;
if (this.appContext.widthPreferred <= screenWidth)
widthFinal = this.appContext.isConstrainMax ? this.appContext.widthPreferred : screenWidth;
else
widthFinal = this.appContext.isConstrainMin ? this.appContext.widthPreferred : screenWidth;
this.fitRoot(widthFinal, screenHeight, browserZoom);
if (isSetAppDimensions) {
this._appWidth = widthFinal;
this._appHeight = screenHeight;
}
}
else if (is.notEmpty(appContextDesktop.heightPreferred)) {
let heightFinal = this.appContext.heightPreferred;
if (this.appContext.heightPreferred <= screenHeight)
heightFinal = this.appContext.isConstrainMax ? this.appContext.heightPreferred : screenHeight;
else
heightFinal = this.appContext.isConstrainMin ? this.appContext.heightPreferred : screenHeight;
this.fitRoot(screenWidth, heightFinal, browserZoom);
if (isSetAppDimensions) {
this._appWidth = screenWidth;
this._appHeight = heightFinal;
}
}
}
setMobileLayout(appContextMobile, screenWidth, screenHeight, isRotated = false, browserZoom = 1) {
if (is.notEmpty(appContextMobile.widthPreferred)) {
this._appWidth = appContextMobile.widthPreferred;
if (is.notEmpty(appContextMobile.heightPreferred)) {
this._appHeight = appContextMobile.heightPreferred;
}
else {
this._appHeight = isRotated
? screenWidth * (this._appWidth / screenHeight)
: screenHeight * (this._appWidth / screenWidth);
}
}
else {
this._appWidth = isRotated ? screenHeight : screenWidth;
this._appHeight = isRotated ? screenWidth : screenHeight;
}
this._appScale = 1;
if (lux_detector_1.default.isMobile) {
this.p_initializeViewport(screenWidth, screenHeight, isRotated);
if (isRotated)
this.fitRoot(this._appHeight, appContextMobile.widthPreferred, browserZoom);
else
this.fitRoot(appContextMobile.widthPreferred, this._appHeight, browserZoom);
}
else {
if (is.notEmpty(appContextMobile.emulationContext)) {
this._appWidth = appContextMobile.emulationContext.appWidthPreferred;
this._appHeight = appContextMobile.emulationContext.appHeightPreferred;
this._appScale = 1;
}
else {
if (is.notEmpty(appContextMobile.widthPreferred)) {
this._appScale = (isRotated ? screenHeight : screenWidth) / appContextMobile.widthPreferred;
if (is.empty(appContextMobile.heightPreferred)) {
this._appHeight /= this._appScale;
}
}
}
this.setDesktopRootLayout(appContextMobile.emulationContext, screenWidth, screenHeight, browserZoom, false);
}
if (lux_detector_1.default.isMobile
|| is.empty(appContextMobile.emulationContext)
|| appContextMobile.emulationContext.mobileOrientationMode === appEnums_1.Orientation.BOTH) {
this.deviceScreen.rotation.z = isRotated ? 90 : 0;
}
else {
this.deviceScreen.rotation.z = appContextMobile.emulationContext.mobileOrientationMode === appEnums_1.Orientation.HORIZONTAL ? 90 : 0;
}
}
p_initializeViewport(screenWidth, screenHeight, isRotated) {
if (this.viewport) {
let width = isRotated ? this._appHeight : this._appWidth;
let scale = (isRotated ? screenHeight : screenWidth) / this._appWidth;
let viewScale;
if (is.empty(this._deviceScaleFactor))
viewScale = scale;
else if (Math.round(scale * 10) / 10 === 1) {
viewScale = 1;
}
else {
viewScale = Math.round(scale * this._deviceScaleFactor * 10) / 10;
}
if (this._deviceScaleFactor == null)
this._deviceScaleFactor = scale;
this._viewport.setAttribute('content', 'width=' + width
+ ', minimum-scale=' + viewScale
+ ', maximum-scale=' + viewScale
+ ', user-scalable=no');
}
}
fitRoot(w, h, browserZoom) {
this.root.size.x = w / browserZoom;
this.root.size.y = h / browserZoom;
this.root.position.left = (w / 2) - (this.root.size.x / 2);
this.root.position.top = (h / 2) - (this.root.size.y / 2);
}
forceRootAspectRatio(w, h, rootAspectRatio, browserZoom = 1) {
if (h / w > rootAspectRatio) {
this.root.position.left = 0;
let widthFinal = w / browserZoom;
if (this.appContext.widthPreferred <= widthFinal)
this.root.size.x = this.appContext.isConstrainMax ? this.appContext.widthPreferred : widthFinal;
else
this.root.size.x = this.appContext.isConstrainMin ? this.appContext.widthPreferred : widthFinal;
this.root.size.y = this.root.size.x * rootAspectRatio;
this.root.position.top = (h / 2) - (this.root.size.y / 2);
this._appScale = this.root.size.x / this._appContext.widthPreferred;
}
else {
this.root.position.top = 0;
let heightFinal = h / browserZoom;
if (this.appContext.heightPreferred <= heightFinal)
this.root.size.y = this.appContext.isConstrainMax ? this.appContext.heightPreferred : heightFinal;
else
this.root.size.y = this.appContext.isConstrainMin ? this.appContext.heightPreferred : heightFinal;
this.root.size.x = this.root.size.y / rootAspectRatio;
this.root.position.left = (w / 2) - (this.root.size.x / 2);
this._appScale = this.root.size.y / this._appContext.heightPreferred;
}
}
p_layoutChanged(eventData) {
let w = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
let h = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
let browserZoom = 1;
let screenOrientation = w > h
? appEnums_1.Orientation.HORIZONTAL
: appEnums_1.Orientation.VERTICAL;
this.setLayout(this._appContext, w, h, browserZoom, screenOrientation);
if (is.notEmpty(this.deviceScreen)) {
this.deviceScreen.size.x = this._appWidth;
this.deviceScreen.size.y = this._appHeight;
this.deviceScreen.scale = this._appScale;
this.deviceScreen.position.x = this.root.size.x / 2;
this.deviceScreen.position.y = this.root.size.y / 2;
}
if (is.notEmpty(this.appRootElement)) {
this.appRootElement.size.x = this._appWidth;
this.appRootElement.size.y = this._appHeight;
}
this.p_onLayoutChanged();
this.layoutChanged.dispatch(this);
if (this.root.size.x < w)
this.root.left = (w / 2) - (this.root.size.x / 2);
if (this.root.size.y < h)
this.root.top = (h / 2) - (this.root.size.y / 2);
}
p_onLayoutChanged() { }
p_online() { }
p_offline() { }
}
exports.AppManager = AppManager;
exports.default = AppManager;
//# sourceMappingURL=appManager.js.map