import { EventApi } from "../event/EventApi" ; import { Manager } from "../Framework" ; import { getSingleton } from "../base/Singleton" ; type DeviceDirection = "" | "Landscape" | "Portrait" ; export enum ScreenAdaptType { description None , description Increase , description Decrease , description Max } function instance ( ) { return getSingleton ( ResolutionHelper ) ; } export class ResolutionHelper { private _logTag = "[ResolutionHelper]" ; private static _instance : ResolutionHelper = null ; public static Instance ( ) { return this . _instance || ( this . _instance = new ResolutionHelper ( ) ) ; } private canvas : cc . Canvas = null ; description private screenAdaptType : ScreenAdaptType = ScreenAdaptType . None ; private node : cc . Node = null ; /**最大允许屏幕比率 */ private readonly MAX_RATE = 2.4 ; private designResolution : cc . Size = null ; private landscapeHeight = 0 ; private protraitHeight = 0 ; private waitScorllY = null ; private isFirstResize = true ; public _isShowKeyboard = false ; public _keybordChangeTimerId = - 1 ; public _maxLandscapeHeight = 0 ; public get isShowKeyboard ( ) { return instance ( ) . _isShowKeyboard ; } public set isShowKeyboard ( value ) { let me = instance ( ) ; me . _isShowKeyboard = value ; if ( ! value ) { me . _onResize ( true ) ; } } description public fullScreenAdapt ( node ) { let me = instance ( ) ; if ( node && me . isNeedAdapt ) { node . setContentSize ( cc . winSize ) ; me . updateAlignment ( node ) ; } } description public get isNeedAdapt ( ) { let me = instance ( ) ; if ( me . screenAdaptType != ScreenAdaptType . None ) { return true ; } return false ; } private updateAlignment ( node ) { let me = instance ( ) ; let ch = node . children ; for ( let i = 0 ; i < ch . length ; i ++ ) { let child = ch [ i ] ; cc . updateAlignment ( child ) ; me . updateAlignment ( child ) ; } } public onLoad ( node ) { let me = instance ( ) ; me . node = node ; me . canvas = node . getComponent ( cc . Canvas ) ; me . designResolution = me . canvas . designResolution . clone ( ) ; me . onResize ( ) ; } public onDestroy ( ) { let me = instance ( ) ; me . node = null ; me . isFirstResize = false ; } description private doChangeResolution ( ) { let me = instance ( ) ; if ( me . screenAdaptType == ScreenAdaptType . Increase ) { let winsize = me . getWinsize ( ) ; me . canvas . designResolution = winsize ; } else if ( me . screenAdaptType == ScreenAdaptType . Max ) { let winsize = me . getMaxWinsize ( ) ; if ( CC_DEBUG ) cc . log ( `max winsize : ${ winsize . width } * ${ winsize . height }` ) ; me . canvas . designResolution = winsize ; } else { me . canvas . designResolution = me . designResolution ; } if ( me . isNeedAdapt ) { dispatch ( EventApi . AdaptScreenEvent ) ; Manager . uiManager . fullScreenAdapt ( ) ; } } description public initBrowserAdaptor ( ) { let me = instance ( ) ; if ( me . isBrowser && ! CC_EDITOR ) { cc . view . resizeWithBrowserSize ( true ) ; if ( CC_PREVIEW || CC_WECHATGAME ) { me . recordHeight ( ) ; } else { window . addEventListener ( "load" , ( ) => { me . recordHeight ( ) ; window . addEventListener ( "resize" , me . onResize , false ) ; window . addEventListener ( "orientationchange" , me . onOrientationChange , false ) ; } , false ) ; } } } private get isBrowser ( ) { if ( cc . sys . isBrowser ) { return true ; } return false ; } private get isSafari ( ) { let me = instance ( ) ; if ( me . isBrowser && cc . sys . OS_IOS == cc . sys . os && cc . sys . browserType == cc . sys . BROWSER_TYPE_SAFARI ) { return true ; } return false ; } private onOrientationChange ( ) { let me = instance ( ) ; me . recordHeight ( ) ; me . isFirstResize = false ; } private onResize ( ) { let me = instance ( ) ; me . _onResize ( false ) ; } private _onResize ( isHideKeyboard ) { let me = instance ( ) ; if ( me . node ) { if ( CC_PREVIEW || CC_WECHATGAME ) { me . recordHeight ( ) ; me . doAdapt ( ) ; } else { if ( me . isShowKeyboard ) { me . recordHeight ( ) ; return ; } if ( me . dviceDirection == "Landscape" ) { let height = me . landscapeHeight ; let offsetY = 0 ; me . recordHeight ( ) ; if ( me . landscapeHeight != 0 ) { offsetY = me . landscapeHeight - height ; if ( me . isFirstResize ) { if ( CC_DEBUG ) cc . log ( me . _logTag , `在有导行条情况下进行刷新操作` ) ; me . waitScorllY = offsetY ; me . doAdapt ( ) ; me . isFirstResize = false ; return ; } } } if ( isHideKeyboard && me . dviceDirection == "Landscape" ) { me . waitScorllY = Math . abs ( me . _maxLandscapeHeight - me . landscapeHeight ) ; } me . isFirstResize = false ; me . doAdapt ( ) ; setTimeout ( ( ) => { if ( me . isShowKeyboard ) { return ; } if ( me . dviceDirection == "Landscape" ) { me . recordHeight ( ) ; cc . log ( `cur scrolly : ${ window . scrollY }` ) ; if ( window . scrollY > 0 || me . isSafari ) { if ( CC_DEBUG ) cc . log ( me . _logTag , me . dviceDirection ) ; if ( me . isSafari ) { me . waitScorllY = window . scrollY > 0 ? - window . scrollY : - 50 ; } else { me . waitScorllY = - window . scrollY ; } if ( CC_DEBUG ) cc . log ( me . _logTag , `scrollY : ${ me . waitScorllY }` ) ; me . doAdapt ( ) ; } else { me . doAdapt ( ) ; } } else if ( me . dviceDirection == "Portrait" ) { if ( me . protraitHeight > window . innerHeight ) { me . waitScorllY = ( me . protraitHeight - window . innerHeight ) ; } me . recordHeight ( ) ; me . doAdapt ( ) ; } } , 505 ) ; } } } private doAdapt ( ) { let me = instance ( ) ; if ( me . canvas ) { if ( me . waitScorllY != null ) { let top = me . waitScorllY ; if ( CC_DEBUG ) cc . log ( me . _logTag , `scroll top : ${ top }` ) ; if ( window . scrollTo ) { window . scrollTo ( 0 , top ) ; } me . waitScorllY = null ; } me . calculateNeedFullScreenAdapt ( ) ; me . doChangeResolution ( ) ; } else { if ( CC_DEBUG ) cc . log ( me . _logTag , `等待场景加载完成做适配` ) ; } } private recordHeight ( ) { if ( window . innerWidth && window . innerHeight ) { let me = instance ( ) ; if ( me . dviceDirection == "Landscape" ) { me . landscapeHeight = window . innerHeight ; me . _maxLandscapeHeight = Math . max ( me . _maxLandscapeHeight , me . landscapeHeight ) ; } else if ( me . dviceDirection == "Portrait" ) { me . protraitHeight = Math . max ( window . innerWidth , window . innerHeight ) ; } } } private getWinsize ( ) { let me = instance ( ) ; let frameSize = me . getFrameSize ( ) ; let width = frameSize . width * me . designResolution . height / frameSize . height ; let height = me . designResolution . height ; return cc . size ( width , height ) ; } description private getMaxWinsize ( ) { let me = instance ( ) ; let height = me . designResolution . height ; let width = height * me . MAX_RATE ; return cc . size ( width , height ) ; } private getFrameSize ( ) { let me = instance ( ) ; let frameSize = cc . view . getFrameSize ( ) ; let innerSize = me . windowInnerSize ; let size = frameSize . clone ( ) ; if ( ! CC_JSB && ! CC_PREVIEW ) { size = innerSize ; } return size ; } /**计算是否需要进行全屏幕适配 */ private calculateNeedFullScreenAdapt ( ) { let me = instance ( ) ; let design = me . designResolution . width / me . designResolution . height ; let frameSize = me . getFrameSize ( ) ; let rate = frameSize . width / frameSize . height ; if ( me . dviceDirection == "Portrait" || ( me . dviceDirection == '' && design < 1 ) ) { design = 1 / design ; rate = 1 / rate ; } if ( CC_DEBUG ) cc . log ( me . _logTag , `design : ${ design } real : ${ rate }` ) ; me . screenAdaptType = ScreenAdaptType . None ; if ( design == rate ) { if ( CC_DEBUG ) cc . log ( me . _logTag , `相等比率` ) ; } else if ( rate < design ) { me . screenAdaptType = ScreenAdaptType . Decrease ; if ( CC_DEBUG ) cc . log ( me . _logTag , `当前设计比率大于实际比率，按宽进行适配，上下有黑边` ) ; } else { if ( CC_DEBUG ) cc . log ( me . _logTag , `当前设计比率小于实际比率，将会对支持全屏的界面进行重重布局` ) ; if ( rate >= me . MAX_RATE ) { if ( CC_DEBUG ) cc . log ( me . _logTag , `超过上限比率，按最大值来` ) ; me . screenAdaptType = ScreenAdaptType . Max ; } else { me . screenAdaptType = ScreenAdaptType . Increase ; } } } description private get dviceDirection ( ) : DeviceDirection { if ( ( window . orientation != undefined || window . orientation != null ) && ( window . orientation == 90 || window . orientation == - 90 ) ) { return "Landscape" ; } if ( ( window . orientation != undefined || window . orientation != null ) && ( window . orientation == 0 || window . orientation == 180 ) ) { return "Portrait" ; } return "" ; } private get windowInnerSize ( ) { let size = cc . Size . ZERO . clone ( ) ; if ( window . innerHeight && window . innerWidth ) { let w = window . innerWidth ; let h = window . innerHeight ; let isLandscape = w >= h ; if ( ! cc . sys . isMobile || isLandscape ) { size . width = w ; size . height = h ; } else { size . width = h ; size . height = w ; } } return size ; } }