UNPKG

@pilotlab/lux-tools

Version:

A luxurious user experience framework, developed by your friends at Pilot.

414 lines (413 loc) 19.3 kB
"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