1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * @ignore 29 */ 30 cc.Touches = []; 31 cc.TouchesIntergerDict = {}; 32 33 cc.DENSITYDPI_DEVICE = "device-dpi"; 34 cc.DENSITYDPI_HIGH = "high-dpi"; 35 cc.DENSITYDPI_MEDIUM = "medium-dpi"; 36 cc.DENSITYDPI_LOW = "low-dpi"; 37 38 cc.__BrowserGetter = { 39 init: function(){ 40 this.html = document.getElementsByTagName("html")[0]; 41 }, 42 availWidth: function(frame){ 43 if(!frame || frame === this.html) 44 return window.innerWidth; 45 else 46 return frame.clientWidth; 47 }, 48 availHeight: function(frame){ 49 if(!frame || frame === this.html) 50 return window.innerHeight; 51 else 52 return frame.clientHeight; 53 }, 54 meta: { 55 "width": "device-width" 56 }, 57 adaptationType: cc.sys.browserType 58 }; 59 60 if(window.navigator.userAgent.indexOf("OS 8_1_") > -1) //this mistake like MIUI, so use of MIUI treatment method 61 cc.__BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_MIUI; 62 63 if(cc.sys.os === cc.sys.OS_IOS) // All browsers are WebView 64 cc.__BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_SAFARI; 65 66 switch(cc.__BrowserGetter.adaptationType){ 67 case cc.sys.BROWSER_TYPE_SAFARI: 68 cc.__BrowserGetter.meta["minimal-ui"] = "true"; 69 cc.__BrowserGetter.availWidth = function(frame){ 70 return frame.clientWidth; 71 }; 72 cc.__BrowserGetter.availHeight = function(frame){ 73 return frame.clientHeight; 74 }; 75 break; 76 case cc.sys.BROWSER_TYPE_CHROME: 77 cc.__BrowserGetter.__defineGetter__("target-densitydpi", function(){ 78 return cc.view._targetDensityDPI; 79 }); 80 case cc.sys.BROWSER_TYPE_SOUGOU: 81 case cc.sys.BROWSER_TYPE_UC: 82 cc.__BrowserGetter.availWidth = function(frame){ 83 return frame.clientWidth; 84 }; 85 cc.__BrowserGetter.availHeight = function(frame){ 86 return frame.clientHeight; 87 }; 88 break; 89 case cc.sys.BROWSER_TYPE_MIUI: 90 cc.__BrowserGetter.init = function(view){ 91 if(view.__resizeWithBrowserSize) return; 92 var resize = function(){ 93 view.setDesignResolutionSize( 94 view._designResolutionSize.width, 95 view._designResolutionSize.height, 96 view._resolutionPolicy 97 ); 98 window.removeEventListener("resize", resize, false); 99 }; 100 window.addEventListener("resize", resize, false); 101 }; 102 break; 103 } 104 105 /** 106 * cc.view is the singleton object which represents the game window.<br/> 107 * It's main task include: <br/> 108 * - Apply the design resolution policy<br/> 109 * - Provide interaction with the window, like resize event on web, retina display support, etc...<br/> 110 * - Manage the game view port which can be different with the window<br/> 111 * - Manage the content scale and translation<br/> 112 * <br/> 113 * Since the cc.view is a singleton, you don't need to call any constructor or create functions,<br/> 114 * the standard way to use it is by calling:<br/> 115 * - cc.view.methodName(); <br/> 116 * @class 117 * @name cc.view 118 * @extend cc.Class 119 */ 120 cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ 121 _delegate: null, 122 // Size of parent node that contains cc.container and cc._canvas 123 _frameSize: null, 124 // resolution size, it is the size appropriate for the app resources. 125 _designResolutionSize: null, 126 _originalDesignResolutionSize: null, 127 // Viewport is the container's rect related to content's coordinates in pixel 128 _viewPortRect: null, 129 // The visible rect in content's coordinate in point 130 _visibleRect: null, 131 _retinaEnabled: false, 132 _autoFullScreen: false, 133 // The device's pixel ratio (for retina displays) 134 _devicePixelRatio: 1, 135 // the view name 136 _viewName: "", 137 // Custom callback for resize event 138 _resizeCallback: null, 139 _scaleX: 1, 140 _originalScaleX: 1, 141 _scaleY: 1, 142 _originalScaleY: 1, 143 _indexBitsUsed: 0, 144 _maxTouches: 5, 145 _resolutionPolicy: null, 146 _rpExactFit: null, 147 _rpShowAll: null, 148 _rpNoBorder: null, 149 _rpFixedHeight: null, 150 _rpFixedWidth: null, 151 _initialized: false, 152 153 _captured: false, 154 _wnd: null, 155 _hDC: null, 156 _hRC: null, 157 _supportTouch: false, 158 _contentTranslateLeftTop: null, 159 160 // Parent node that contains cc.container and cc._canvas 161 _frame: null, 162 _frameZoomFactor: 1.0, 163 __resizeWithBrowserSize: false, 164 _isAdjustViewPort: true, 165 _targetDensityDPI: null, 166 167 /** 168 * Constructor of cc.EGLView 169 */ 170 ctor: function () { 171 var _t = this, d = document, _strategyer = cc.ContainerStrategy, _strategy = cc.ContentStrategy; 172 173 cc.__BrowserGetter.init(this); 174 175 _t._frame = (cc.container.parentNode === d.body) ? d.documentElement : cc.container.parentNode; 176 _t._frameSize = cc.size(0, 0); 177 _t._initFrameSize(); 178 179 var w = cc._canvas.width, h = cc._canvas.height; 180 _t._designResolutionSize = cc.size(w, h); 181 _t._originalDesignResolutionSize = cc.size(w, h); 182 _t._viewPortRect = cc.rect(0, 0, w, h); 183 _t._visibleRect = cc.rect(0, 0, w, h); 184 _t._contentTranslateLeftTop = {left: 0, top: 0}; 185 _t._viewName = "Cocos2dHTML5"; 186 187 var sys = cc.sys; 188 _t.enableRetina(sys.os === sys.OS_IOS || sys.os === sys.OS_OSX); 189 _t.enableAutoFullScreen(sys.isMobile && sys.browserType !== sys.BROWSER_TYPE_BAIDU); 190 cc.visibleRect && cc.visibleRect.init(_t._visibleRect); 191 192 // Setup system default resolution policies 193 _t._rpExactFit = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.EXACT_FIT); 194 _t._rpShowAll = new cc.ResolutionPolicy(_strategyer.PROPORTION_TO_FRAME, _strategy.SHOW_ALL); 195 _t._rpNoBorder = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.NO_BORDER); 196 _t._rpFixedHeight = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_HEIGHT); 197 _t._rpFixedWidth = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_WIDTH); 198 199 _t._hDC = cc._canvas; 200 _t._hRC = cc._renderContext; 201 _t._targetDensityDPI = cc.DENSITYDPI_HIGH; 202 }, 203 204 // Resize helper functions 205 _resizeEvent: function () { 206 var view; 207 if (this.setDesignResolutionSize) { 208 view = this; 209 } else { 210 view = cc.view; 211 } 212 213 // Check frame size changed or not 214 var prevFrameW = view._frameSize.width, prevFrameH = view._frameSize.height; 215 view._initFrameSize(); 216 if (view._frameSize.width === prevFrameW && view._frameSize.height === prevFrameH) 217 return; 218 219 // Frame size changed, do resize works 220 if (view._resizeCallback) { 221 view._resizeCallback.call(); 222 } 223 var width = view._originalDesignResolutionSize.width; 224 var height = view._originalDesignResolutionSize.height; 225 if (width > 0) { 226 view.setDesignResolutionSize(width, height, view._resolutionPolicy); 227 } 228 }, 229 230 /** 231 * <p> 232 * Sets view's target-densitydpi for android mobile browser. it can be set to: <br/> 233 * 1. cc.DENSITYDPI_DEVICE, value is "device-dpi" <br/> 234 * 2. cc.DENSITYDPI_HIGH, value is "high-dpi" (default value) <br/> 235 * 3. cc.DENSITYDPI_MEDIUM, value is "medium-dpi" (browser's default value) <br/> 236 * 4. cc.DENSITYDPI_LOW, value is "low-dpi" <br/> 237 * 5. Custom value, e.g: "480" <br/> 238 * </p> 239 * @param {String} densityDPI 240 */ 241 setTargetDensityDPI: function(densityDPI){ 242 this._targetDensityDPI = densityDPI; 243 this._adjustViewportMeta(); 244 }, 245 246 /** 247 * Returns the current target-densitydpi value of cc.view. 248 * @returns {String} 249 */ 250 getTargetDensityDPI: function(){ 251 return this._targetDensityDPI; 252 }, 253 254 /** 255 * Sets whether resize canvas automatically when browser's size changed.<br/> 256 * Useful only on web. 257 * @param {Boolean} enabled Whether enable automatic resize with browser's resize event 258 */ 259 resizeWithBrowserSize: function (enabled) { 260 if (enabled) { 261 //enable 262 if (!this.__resizeWithBrowserSize) { 263 this.__resizeWithBrowserSize = true; 264 window.addEventListener('resize', this._resizeEvent); 265 window.addEventListener('orientationchange', this._resizeEvent); 266 } 267 } else { 268 //disable 269 if (this.__resizeWithBrowserSize) { 270 this.__resizeWithBrowserSize = false; 271 window.removeEventListener('resize', this._resizeEvent); 272 window.removeEventListener('orientationchange', this._resizeEvent); 273 } 274 } 275 }, 276 277 /** 278 * Sets the callback function for cc.view's resize action,<br/> 279 * this callback will be invoked before applying resolution policy, <br/> 280 * so you can do any additional modifications within the callback.<br/> 281 * Useful only on web. 282 * @param {Function|null} callback The callback function 283 */ 284 setResizeCallback: function (callback) { 285 if (cc.isFunction(callback) || callback == null) { 286 this._resizeCallback = callback; 287 } 288 }, 289 290 _initFrameSize: function () { 291 var locFrameSize = this._frameSize; 292 locFrameSize.width = cc.__BrowserGetter.availWidth(this._frame); 293 locFrameSize.height = cc.__BrowserGetter.availHeight(this._frame); 294 }, 295 296 // hack 297 _adjustSizeKeepCanvasSize: function () { 298 var designWidth = this._originalDesignResolutionSize.width; 299 var designHeight = this._originalDesignResolutionSize.height; 300 if (designWidth > 0) 301 this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy); 302 }, 303 304 _setViewportMeta: function (metas, overwrite) { 305 var vp = document.getElementById("cocosMetaElement"); 306 if(vp && overwrite){ 307 document.head.removeChild(vp); 308 } 309 310 var elems = document.getElementsByName("viewport"), 311 currentVP = elems ? elems[0] : null, 312 content, key, pattern; 313 314 content = currentVP ? currentVP.content : ""; 315 vp = vp || document.createElement("meta"); 316 vp.id = "cocosMetaElement"; 317 vp.name = "viewport"; 318 vp.content = ""; 319 320 for (key in metas) { 321 if (content.indexOf(key) == -1) { 322 content += "," + key + "=" + metas[key]; 323 } 324 else if (overwrite) { 325 pattern = new RegExp(key+"\s*=\s*[^,]+"); 326 content.replace(pattern, key + "=" + metas[key]); 327 } 328 } 329 if(/^,/.test(content)) 330 content = content.substr(1); 331 332 vp.content = content; 333 // For adopting certain android devices which don't support second viewport 334 if (currentVP) 335 currentVP.content = content; 336 337 document.head.appendChild(vp); 338 }, 339 340 _adjustViewportMeta: function () { 341 if (this._isAdjustViewPort) { 342 this._setViewportMeta(cc.__BrowserGetter.meta, false); 343 // Only adjust viewport once 344 this._isAdjustViewPort = false; 345 } 346 }, 347 348 // RenderTexture hacker 349 _setScaleXYForRenderTexture: function () { 350 //hack for RenderTexture on canvas mode when adapting multiple resolution resources 351 var scaleFactor = cc.contentScaleFactor(); 352 this._scaleX = scaleFactor; 353 this._scaleY = scaleFactor; 354 }, 355 356 // Other helper functions 357 _resetScale: function () { 358 this._scaleX = this._originalScaleX; 359 this._scaleY = this._originalScaleY; 360 }, 361 362 // Useless, just make sure the compatibility temporarily, should be removed 363 _adjustSizeToBrowser: function () { 364 }, 365 366 initialize: function () { 367 this._initialized = true; 368 }, 369 370 /** 371 * Sets whether the engine modify the "viewport" meta in your web page.<br/> 372 * It's enabled by default, we strongly suggest you not to disable it.<br/> 373 * And even when it's enabled, you can still set your own "viewport" meta, it won't be overridden<br/> 374 * Only useful on web 375 * @param {Boolean} enabled Enable automatic modification to "viewport" meta 376 */ 377 adjustViewPort: function (enabled) { 378 this._isAdjustViewPort = enabled; 379 }, 380 381 /** 382 * Retina support is enabled by default for Apple device but disabled for other devices,<br/> 383 * it takes effect only when you called setDesignResolutionPolicy<br/> 384 * Only useful on web 385 * @param {Boolean} enabled Enable or disable retina display 386 */ 387 enableRetina: function(enabled) { 388 this._retinaEnabled = enabled ? true : false; 389 }, 390 391 /** 392 * Check whether retina display is enabled.<br/> 393 * Only useful on web 394 * @return {Boolean} 395 */ 396 isRetinaEnabled: function() { 397 return this._retinaEnabled; 398 }, 399 400 /** 401 * If enabled, the application will try automatically to enter full screen mode on mobile devices<br/> 402 * You can pass true as parameter to enable it and disable it by passing false.<br/> 403 * Only useful on web 404 * @param {Boolean} enabled Enable or disable auto full screen on mobile devices 405 */ 406 enableAutoFullScreen: function(enabled) { 407 if (enabled && enabled !== this._autoFullScreen && cc.sys.isMobile && this._frame === document.documentElement) { 408 // Automatically full screen when user touches on mobile version 409 this._autoFullScreen = true; 410 cc.screen.autoFullScreen(this._frame); 411 } 412 else { 413 this._autoFullScreen = false; 414 } 415 }, 416 417 /** 418 * Check whether auto full screen is enabled.<br/> 419 * Only useful on web 420 * @return {Boolean} Auto full screen enabled or not 421 */ 422 isAutoFullScreenEnabled: function() { 423 return this._autoFullScreen; 424 }, 425 426 /** 427 * Force destroying EGL view, subclass must implement this method. 428 */ 429 end: function () { 430 }, 431 432 /** 433 * Get whether render system is ready(no matter opengl or canvas),<br/> 434 * this name is for the compatibility with cocos2d-x, subclass must implement this method. 435 * @return {Boolean} 436 */ 437 isOpenGLReady: function () { 438 return (this._hDC !== null && this._hRC !== null); 439 }, 440 441 /* 442 * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop. 443 * @param {Number} zoomFactor 444 */ 445 setFrameZoomFactor: function (zoomFactor) { 446 this._frameZoomFactor = zoomFactor; 447 this.centerWindow(); 448 cc.director.setProjection(cc.director.getProjection()); 449 }, 450 451 /** 452 * Exchanges the front and back buffers, subclass must implement this method. 453 */ 454 swapBuffers: function () { 455 }, 456 457 /** 458 * Open or close IME keyboard , subclass must implement this method. 459 * @param {Boolean} isOpen 460 */ 461 setIMEKeyboardState: function (isOpen) { 462 }, 463 464 /** 465 * Sets the resolution translate on EGLView 466 * @param {Number} offsetLeft 467 * @param {Number} offsetTop 468 */ 469 setContentTranslateLeftTop: function (offsetLeft, offsetTop) { 470 this._contentTranslateLeftTop = {left: offsetLeft, top: offsetTop}; 471 }, 472 473 /** 474 * Returns the resolution translate on EGLView 475 * @return {cc.Size|Object} 476 */ 477 getContentTranslateLeftTop: function () { 478 return this._contentTranslateLeftTop; 479 }, 480 481 /** 482 * Returns the canvas size of the view.<br/> 483 * On native platforms, it returns the screen size since the view is a fullscreen view.<br/> 484 * On web, it returns the size of the canvas element. 485 * @return {cc.Size} 486 */ 487 getCanvasSize: function () { 488 return cc.size(cc._canvas.width, cc._canvas.height); 489 }, 490 491 /** 492 * Returns the frame size of the view.<br/> 493 * On native platforms, it returns the screen size since the view is a fullscreen view.<br/> 494 * On web, it returns the size of the canvas's outer DOM element. 495 * @return {cc.Size} 496 */ 497 getFrameSize: function () { 498 return cc.size(this._frameSize.width, this._frameSize.height); 499 }, 500 501 /** 502 * On native, it sets the frame size of view.<br/> 503 * On web, it sets the size of the canvas's outer DOM element. 504 * @param {Number} width 505 * @param {Number} height 506 */ 507 setFrameSize: function (width, height) { 508 this._frameSize.width = width; 509 this._frameSize.height = height; 510 this._frame.style.width = width + "px"; 511 this._frame.style.height = height + "px"; 512 //this.centerWindow(); 513 this._resizeEvent(); 514 cc.director.setProjection(cc.director.getProjection()); 515 }, 516 517 /** 518 * Empty function 519 */ 520 centerWindow: function () { 521 }, 522 523 /** 524 * Returns the visible area size of the view port. 525 * @return {cc.Size} 526 */ 527 getVisibleSize: function () { 528 return cc.size(this._visibleRect.width,this._visibleRect.height); 529 }, 530 531 /** 532 * Returns the visible area size of the view port. 533 * @return {cc.Size} 534 */ 535 getVisibleSizeInPixel: function () { 536 return cc.size( this._visibleRect.width * this._scaleX, 537 this._visibleRect.height * this._scaleY ); 538 }, 539 540 /** 541 * Returns the visible origin of the view port. 542 * @return {cc.Point} 543 */ 544 getVisibleOrigin: function () { 545 return cc.p(this._visibleRect.x,this._visibleRect.y); 546 }, 547 548 /** 549 * Returns the visible origin of the view port. 550 * @return {cc.Point} 551 */ 552 getVisibleOriginInPixel: function () { 553 return cc.p(this._visibleRect.x * this._scaleX, 554 this._visibleRect.y * this._scaleY); 555 }, 556 557 /** 558 * Returns whether developer can set content's scale factor. 559 * @return {Boolean} 560 */ 561 canSetContentScaleFactor: function () { 562 return true; 563 }, 564 565 /** 566 * Returns the current resolution policy 567 * @see cc.ResolutionPolicy 568 * @return {cc.ResolutionPolicy} 569 */ 570 getResolutionPolicy: function () { 571 return this._resolutionPolicy; 572 }, 573 574 /** 575 * Sets the current resolution policy 576 * @see cc.ResolutionPolicy 577 * @param {cc.ResolutionPolicy|Number} resolutionPolicy 578 */ 579 setResolutionPolicy: function (resolutionPolicy) { 580 var _t = this; 581 if (resolutionPolicy instanceof cc.ResolutionPolicy) { 582 _t._resolutionPolicy = resolutionPolicy; 583 } 584 // Ensure compatibility with JSB 585 else { 586 var _locPolicy = cc.ResolutionPolicy; 587 if(resolutionPolicy === _locPolicy.EXACT_FIT) 588 _t._resolutionPolicy = _t._rpExactFit; 589 if(resolutionPolicy === _locPolicy.SHOW_ALL) 590 _t._resolutionPolicy = _t._rpShowAll; 591 if(resolutionPolicy === _locPolicy.NO_BORDER) 592 _t._resolutionPolicy = _t._rpNoBorder; 593 if(resolutionPolicy === _locPolicy.FIXED_HEIGHT) 594 _t._resolutionPolicy = _t._rpFixedHeight; 595 if(resolutionPolicy === _locPolicy.FIXED_WIDTH) 596 _t._resolutionPolicy = _t._rpFixedWidth; 597 } 598 }, 599 600 /** 601 * Sets the resolution policy with designed view size in points.<br/> 602 * The resolution policy include: <br/> 603 * [1] ResolutionExactFit Fill screen by stretch-to-fit: if the design resolution ratio of width to height is different from the screen resolution ratio, your game view will be stretched.<br/> 604 * [2] ResolutionNoBorder Full screen without black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two areas of your game view will be cut.<br/> 605 * [3] ResolutionShowAll Full screen with black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two black borders will be shown.<br/> 606 * [4] ResolutionFixedHeight Scale the content's height to screen's height and proportionally scale its width<br/> 607 * [5] ResolutionFixedWidth Scale the content's width to screen's width and proportionally scale its height<br/> 608 * [cc.ResolutionPolicy] [Web only feature] Custom resolution policy, constructed by cc.ResolutionPolicy<br/> 609 * @param {Number} width Design resolution width. 610 * @param {Number} height Design resolution height. 611 * @param {cc.ResolutionPolicy|Number} resolutionPolicy The resolution policy desired 612 */ 613 setDesignResolutionSize: function (width, height, resolutionPolicy) { 614 // Defensive code 615 if( !(width > 0 || height > 0) ){ 616 cc.log(cc._LogInfos.EGLView_setDesignResolutionSize); 617 return; 618 } 619 620 this.setResolutionPolicy(resolutionPolicy); 621 var policy = this._resolutionPolicy; 622 if (!policy){ 623 cc.log(cc._LogInfos.EGLView_setDesignResolutionSize_2); 624 return; 625 } 626 policy.preApply(this); 627 628 // Reinit frame size 629 if(cc.sys.isMobile) 630 this._adjustViewportMeta(); 631 632 this._initFrameSize(); 633 634 this._originalDesignResolutionSize.width = this._designResolutionSize.width = width; 635 this._originalDesignResolutionSize.height = this._designResolutionSize.height = height; 636 637 var result = policy.apply(this, this._designResolutionSize); 638 639 if(result.scale && result.scale.length === 2){ 640 this._scaleX = result.scale[0]; 641 this._scaleY = result.scale[1]; 642 } 643 644 if(result.viewport){ 645 var vp = this._viewPortRect, 646 vb = this._visibleRect, 647 rv = result.viewport; 648 649 vp.x = rv.x; 650 vp.y = rv.y; 651 vp.width = rv.width; 652 vp.height = rv.height; 653 654 vb.x = -vp.x / this._scaleX; 655 vb.y = -vp.y / this._scaleY; 656 vb.width = cc._canvas.width / this._scaleX; 657 vb.height = cc._canvas.height / this._scaleY; 658 cc._renderContext.setOffset && cc._renderContext.setOffset(vp.x, -vp.y) 659 } 660 661 // reset director's member variables to fit visible rect 662 var director = cc.director; 663 director._winSizeInPoints.width = this._designResolutionSize.width; 664 director._winSizeInPoints.height = this._designResolutionSize.height; 665 policy.postApply(this); 666 cc.winSize.width = director._winSizeInPoints.width; 667 cc.winSize.height = director._winSizeInPoints.height; 668 669 if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { 670 // reset director's member variables to fit visible rect 671 director.setGLDefaultValues(); 672 } 673 674 this._originalScaleX = this._scaleX; 675 this._originalScaleY = this._scaleY; 676 // For editbox 677 if (cc.DOM) 678 cc.DOM._resetEGLViewDiv(); 679 cc.visibleRect && cc.visibleRect.init(this._visibleRect); 680 }, 681 682 /** 683 * Returns the designed size for the view. 684 * Default resolution size is the same as 'getFrameSize'. 685 * @return {cc.Size} 686 */ 687 getDesignResolutionSize: function () { 688 return cc.size(this._designResolutionSize.width, this._designResolutionSize.height); 689 }, 690 691 /** 692 * Sets the document body to desired pixel resolution and fit the game content to it. 693 * This function is very useful for adaptation in mobile browsers. 694 * In some HD android devices, the resolution is very high, but its browser performance may not be very good. 695 * In this case, enabling retina display is very costy and not suggested, and if retina is disabled, the image may be blurry. 696 * But this API can be helpful to set a desired pixel resolution which is in between. 697 * This API will do the following: 698 * 1. Set viewport's width to the desired width in pixel 699 * 2. Set body width to the exact pixel resolution 700 * 3. The resolution policy will be reset with designed view size in points. 701 * @param {Number} width Design resolution width. 702 * @param {Number} height Design resolution height. 703 * @param {cc.ResolutionPolicy|Number} resolutionPolicy The resolution policy desired 704 */ 705 setRealPixelResolution: function (width, height, resolutionPolicy) { 706 // Set viewport's width 707 this._setViewportMeta({"width": width, "target-densitydpi": cc.DENSITYDPI_DEVICE}, true); 708 709 // Set body width to the exact pixel resolution 710 document.body.style.width = width + "px"; 711 document.body.style.left = "0px"; 712 document.body.style.top = "0px"; 713 714 // Reset the resolution size and policy 715 this.setDesignResolutionSize(width, height, resolutionPolicy); 716 }, 717 718 /** 719 * Sets view port rectangle with points. 720 * @param {Number} x 721 * @param {Number} y 722 * @param {Number} w width 723 * @param {Number} h height 724 */ 725 setViewPortInPoints: function (x, y, w, h) { 726 var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY; 727 cc._renderContext.viewport((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor), 728 (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor), 729 (w * locScaleX * locFrameZoomFactor), 730 (h * locScaleY * locFrameZoomFactor)); 731 }, 732 733 /** 734 * Sets Scissor rectangle with points. 735 * @param {Number} x 736 * @param {Number} y 737 * @param {Number} w 738 * @param {Number} h 739 */ 740 setScissorInPoints: function (x, y, w, h) { 741 var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY; 742 cc._renderContext.scissor((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor), 743 (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor), 744 (w * locScaleX * locFrameZoomFactor), 745 (h * locScaleY * locFrameZoomFactor)); 746 }, 747 748 /** 749 * Returns whether GL_SCISSOR_TEST is enable 750 * @return {Boolean} 751 */ 752 isScissorEnabled: function () { 753 var gl = cc._renderContext; 754 return gl.isEnabled(gl.SCISSOR_TEST); 755 }, 756 757 /** 758 * Returns the current scissor rectangle 759 * @return {cc.Rect} 760 */ 761 getScissorRect: function () { 762 var gl = cc._renderContext, scaleX = this._scaleX, scaleY = this._scaleY; 763 var boxArr = gl.getParameter(gl.SCISSOR_BOX); 764 return cc.rect((boxArr[0] - this._viewPortRect.x) / scaleX, (boxArr[1] - this._viewPortRect.y) / scaleY, 765 boxArr[2] / scaleX, boxArr[3] / scaleY); 766 }, 767 768 /** 769 * Sets the name of the view 770 * @param {String} viewName 771 */ 772 setViewName: function (viewName) { 773 if (viewName != null && viewName.length > 0) { 774 this._viewName = viewName; 775 } 776 }, 777 778 /** 779 * Returns the name of the view 780 * @return {String} 781 */ 782 getViewName: function () { 783 return this._viewName; 784 }, 785 786 /** 787 * Returns the view port rectangle. 788 * @return {cc.Rect} 789 */ 790 getViewPortRect: function () { 791 return this._viewPortRect; 792 }, 793 794 /** 795 * Returns scale factor of the horizontal direction (X axis). 796 * @return {Number} 797 */ 798 getScaleX: function () { 799 return this._scaleX; 800 }, 801 802 /** 803 * Returns scale factor of the vertical direction (Y axis). 804 * @return {Number} 805 */ 806 getScaleY: function () { 807 return this._scaleY; 808 }, 809 810 /** 811 * Returns device pixel ratio for retina display. 812 * @return {Number} 813 */ 814 getDevicePixelRatio: function() { 815 return this._devicePixelRatio; 816 }, 817 818 /** 819 * Returns the real location in view for a translation based on a related position 820 * @param {Number} tx The X axis translation 821 * @param {Number} ty The Y axis translation 822 * @param {Object} relatedPos The related position object including "left", "top", "width", "height" informations 823 * @return {cc.Point} 824 */ 825 convertToLocationInView: function (tx, ty, relatedPos) { 826 return {x: this._devicePixelRatio * (tx - relatedPos.left), y: this._devicePixelRatio * (relatedPos.top + relatedPos.height - ty)}; 827 }, 828 829 _convertMouseToLocationInView: function(point, relatedPos) { 830 var locViewPortRect = this._viewPortRect, _t = this; 831 point.x = ((_t._devicePixelRatio * (point.x - relatedPos.left)) - locViewPortRect.x) / _t._scaleX; 832 point.y = (_t._devicePixelRatio * (relatedPos.top + relatedPos.height - point.y) - locViewPortRect.y) / _t._scaleY; 833 }, 834 835 _convertTouchesWithScale: function(touches){ 836 var locViewPortRect = this._viewPortRect, locScaleX = this._scaleX, locScaleY = this._scaleY, selTouch, selPoint, selPrePoint; 837 for( var i = 0; i < touches.length; i ++){ 838 selTouch = touches[i]; 839 selPoint = selTouch._point; 840 selPrePoint = selTouch._prevPoint; 841 selTouch._setPoint((selPoint.x - locViewPortRect.x) / locScaleX, 842 (selPoint.y - locViewPortRect.y) / locScaleY); 843 selTouch._setPrevPoint((selPrePoint.x - locViewPortRect.x) / locScaleX, 844 (selPrePoint.y - locViewPortRect.y) / locScaleY); 845 } 846 } 847 }); 848 849 /** 850 * @function 851 * @return {cc.EGLView} 852 * @private 853 */ 854 cc.EGLView._getInstance = function () { 855 if (!this._instance) { 856 this._instance = this._instance || new cc.EGLView(); 857 this._instance.initialize(); 858 } 859 return this._instance; 860 }; 861 862 /** 863 * <p>cc.ContainerStrategy class is the root strategy class of container's scale strategy, 864 * it controls the behavior of how to scale the cc.container and cc._canvas object</p> 865 * 866 * @class 867 * @extends cc.Class 868 */ 869 cc.ContainerStrategy = cc.Class.extend(/** @lends cc.ContainerStrategy# */{ 870 /** 871 * Manipulation before appling the strategy 872 * @param {cc.view} The target view 873 */ 874 preApply: function (view) { 875 }, 876 877 /** 878 * Function to apply this strategy 879 * @param {cc.view} view 880 * @param {cc.Size} designedResolution 881 */ 882 apply: function (view, designedResolution) { 883 }, 884 885 /** 886 * Manipulation after applying the strategy 887 * @param {cc.view} view The target view 888 */ 889 postApply: function (view) { 890 891 }, 892 893 _setupContainer: function (view, w, h) { 894 var frame = view._frame; 895 896 var locCanvasElement = cc._canvas, locContainer = cc.container; 897 // Setup container 898 locContainer.style.width = locCanvasElement.style.width = w + "px"; 899 locContainer.style.height = locCanvasElement.style.height = h + "px"; 900 // Setup pixel ratio for retina display 901 var devicePixelRatio = view._devicePixelRatio = 1; 902 if (view.isRetinaEnabled()) 903 devicePixelRatio = view._devicePixelRatio = Math.min(2, window.devicePixelRatio || 1); 904 // Setup canvas 905 locCanvasElement.width = w * devicePixelRatio; 906 locCanvasElement.height = h * devicePixelRatio; 907 cc._renderContext.resetCache && cc._renderContext.resetCache(); 908 909 var body = document.body, style; 910 if (body && (style = body.style)) { 911 style.paddingTop = style.paddingTop || "0px"; 912 style.paddingRight = style.paddingRight || "0px"; 913 style.paddingBottom = style.paddingBottom || "0px"; 914 style.paddingLeft = style.paddingLeft || "0px"; 915 style.borderTop = style.borderTop || "0px"; 916 style.borderRight = style.borderRight || "0px"; 917 style.borderBottom = style.borderBottom || "0px"; 918 style.borderLeft = style.borderLeft || "0px"; 919 style.marginTop = style.marginTop || "0px"; 920 style.marginRight = style.marginRight || "0px"; 921 style.marginBottom = style.marginBottom || "0px"; 922 style.marginLeft = style.marginLeft || "0px"; 923 } 924 }, 925 926 _fixContainer: function () { 927 // Add container to document body 928 document.body.insertBefore(cc.container, document.body.firstChild); 929 // Set body's width height to window's size, and forbid overflow, so that game will be centered 930 var bs = document.body.style; 931 bs.width = window.innerWidth + "px"; 932 bs.height = window.innerHeight + "px"; 933 bs.overflow = "hidden"; 934 // Body size solution doesn't work on all mobile browser so this is the aleternative: fixed container 935 var contStyle = cc.container.style; 936 contStyle.position = "fixed"; 937 contStyle.left = contStyle.top = "0px"; 938 // Reposition body 939 document.body.scrollTop = 0; 940 } 941 }); 942 943 /** 944 * <p>cc.ContentStrategy class is the root strategy class of content's scale strategy, 945 * it controls the behavior of how to scale the scene and setup the viewport for the game</p> 946 * 947 * @class 948 * @extends cc.Class 949 */ 950 cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{ 951 952 _result: { 953 scale: [1, 1], 954 viewport: null 955 }, 956 957 _buildResult: function (containerW, containerH, contentW, contentH, scaleX, scaleY) { 958 // Makes content fit better the canvas 959 Math.abs(containerW - contentW) < 2 && (contentW = containerW); 960 Math.abs(containerH - contentH) < 2 && (contentH = containerH); 961 962 var viewport = cc.rect(Math.round((containerW - contentW) / 2), 963 Math.round((containerH - contentH) / 2), 964 contentW, contentH); 965 966 // Translate the content 967 if (cc._renderType === cc.game.RENDER_TYPE_CANVAS){ 968 //TODO: modify something for setTransform 969 //cc._renderContext.translate(viewport.x, viewport.y + contentH); 970 } 971 972 this._result.scale = [scaleX, scaleY]; 973 this._result.viewport = viewport; 974 return this._result; 975 }, 976 977 /** 978 * Manipulation before applying the strategy 979 * @param {cc.view} view The target view 980 */ 981 preApply: function (view) { 982 }, 983 984 /** 985 * Function to apply this strategy 986 * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}}, 987 * The target view can then apply these value to itself, it's preferred not to modify directly its private variables 988 * @param {cc.view} view 989 * @param {cc.Size} designedResolution 990 * @return {object} scaleAndViewportRect 991 */ 992 apply: function (view, designedResolution) { 993 return {"scale": [1, 1]}; 994 }, 995 996 /** 997 * Manipulation after applying the strategy 998 * @param {cc.view} view The target view 999 */ 1000 postApply: function (view) { 1001 } 1002 }); 1003 1004 (function () { 1005 1006 // Container scale strategys 1007 /** 1008 * @class 1009 * @extends cc.ContainerStrategy 1010 */ 1011 var EqualToFrame = cc.ContainerStrategy.extend({ 1012 apply: function (view) { 1013 this._setupContainer(view, view._frameSize.width, view._frameSize.height); 1014 } 1015 }); 1016 1017 /** 1018 * @class 1019 * @extends cc.ContainerStrategy 1020 */ 1021 var ProportionalToFrame = cc.ContainerStrategy.extend({ 1022 apply: function (view, designedResolution) { 1023 var frameW = view._frameSize.width, frameH = view._frameSize.height, containerStyle = cc.container.style, 1024 designW = designedResolution.width, designH = designedResolution.height, 1025 scaleX = frameW / designW, scaleY = frameH / designH, 1026 containerW, containerH; 1027 1028 scaleX < scaleY ? (containerW = frameW, containerH = designH * scaleX) : (containerW = designW * scaleY, containerH = frameH); 1029 1030 // Adjust container size with integer value 1031 var offx = Math.round((frameW - containerW) / 2); 1032 var offy = Math.round((frameH - containerH) / 2); 1033 containerW = frameW - 2 * offx; 1034 containerH = frameH - 2 * offy; 1035 1036 this._setupContainer(view, containerW, containerH); 1037 // Setup container's margin 1038 containerStyle.marginLeft = offx + "px"; 1039 containerStyle.marginRight = offx + "px"; 1040 containerStyle.marginTop = offy + "px"; 1041 containerStyle.marginBottom = offy + "px"; 1042 } 1043 }); 1044 1045 /** 1046 * @class 1047 * @extends EqualToFrame 1048 */ 1049 var EqualToWindow = EqualToFrame.extend({ 1050 preApply: function (view) { 1051 this._super(view); 1052 view._frame = document.documentElement; 1053 }, 1054 1055 apply: function (view) { 1056 this._super(view); 1057 this._fixContainer(); 1058 } 1059 }); 1060 1061 /** 1062 * @class 1063 * @extends ProportionalToFrame 1064 */ 1065 var ProportionalToWindow = ProportionalToFrame.extend({ 1066 preApply: function (view) { 1067 this._super(view); 1068 view._frame = document.documentElement; 1069 }, 1070 1071 apply: function (view, designedResolution) { 1072 this._super(view, designedResolution); 1073 this._fixContainer(); 1074 } 1075 }); 1076 1077 /** 1078 * @class 1079 * @extends cc.ContainerStrategy 1080 */ 1081 var OriginalContainer = cc.ContainerStrategy.extend({ 1082 apply: function (view) { 1083 this._setupContainer(view, cc._canvas.width, cc._canvas.height); 1084 } 1085 }); 1086 1087 // #NOT STABLE on Android# Alias: Strategy that makes the container's size equals to the window's size 1088 // cc.ContainerStrategy.EQUAL_TO_WINDOW = new EqualToWindow(); 1089 // #NOT STABLE on Android# Alias: Strategy that scale proportionally the container's size to window's size 1090 // cc.ContainerStrategy.PROPORTION_TO_WINDOW = new ProportionalToWindow(); 1091 // Alias: Strategy that makes the container's size equals to the frame's size 1092 cc.ContainerStrategy.EQUAL_TO_FRAME = new EqualToFrame(); 1093 // Alias: Strategy that scale proportionally the container's size to frame's size 1094 cc.ContainerStrategy.PROPORTION_TO_FRAME = new ProportionalToFrame(); 1095 // Alias: Strategy that keeps the original container's size 1096 cc.ContainerStrategy.ORIGINAL_CONTAINER = new OriginalContainer(); 1097 1098 // Content scale strategys 1099 var ExactFit = cc.ContentStrategy.extend({ 1100 apply: function (view, designedResolution) { 1101 var containerW = cc._canvas.width, containerH = cc._canvas.height, 1102 scaleX = containerW / designedResolution.width, scaleY = containerH / designedResolution.height; 1103 1104 return this._buildResult(containerW, containerH, containerW, containerH, scaleX, scaleY); 1105 } 1106 }); 1107 1108 var ShowAll = cc.ContentStrategy.extend({ 1109 apply: function (view, designedResolution) { 1110 var containerW = cc._canvas.width, containerH = cc._canvas.height, 1111 designW = designedResolution.width, designH = designedResolution.height, 1112 scaleX = containerW / designW, scaleY = containerH / designH, scale = 0, 1113 contentW, contentH; 1114 1115 scaleX < scaleY ? (scale = scaleX, contentW = containerW, contentH = designH * scale) 1116 : (scale = scaleY, contentW = designW * scale, contentH = containerH); 1117 1118 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 1119 } 1120 }); 1121 1122 var NoBorder = cc.ContentStrategy.extend({ 1123 apply: function (view, designedResolution) { 1124 var containerW = cc._canvas.width, containerH = cc._canvas.height, 1125 designW = designedResolution.width, designH = designedResolution.height, 1126 scaleX = containerW / designW, scaleY = containerH / designH, scale, 1127 contentW, contentH; 1128 1129 scaleX < scaleY ? (scale = scaleY, contentW = designW * scale, contentH = containerH) 1130 : (scale = scaleX, contentW = containerW, contentH = designH * scale); 1131 1132 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 1133 } 1134 }); 1135 1136 var FixedHeight = cc.ContentStrategy.extend({ 1137 apply: function (view, designedResolution) { 1138 var containerW = cc._canvas.width, containerH = cc._canvas.height, 1139 designH = designedResolution.height, scale = containerH / designH, 1140 contentW = containerW, contentH = containerH; 1141 1142 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 1143 }, 1144 1145 postApply: function (view) { 1146 cc.director._winSizeInPoints = view.getVisibleSize(); 1147 } 1148 }); 1149 1150 var FixedWidth = cc.ContentStrategy.extend({ 1151 apply: function (view, designedResolution) { 1152 var containerW = cc._canvas.width, containerH = cc._canvas.height, 1153 designW = designedResolution.width, scale = containerW / designW, 1154 contentW = containerW, contentH = containerH; 1155 1156 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 1157 }, 1158 1159 postApply: function (view) { 1160 cc.director._winSizeInPoints = view.getVisibleSize(); 1161 } 1162 }); 1163 1164 // Alias: Strategy to scale the content's size to container's size, non proportional 1165 cc.ContentStrategy.EXACT_FIT = new ExactFit(); 1166 // Alias: Strategy to scale the content's size proportionally to maximum size and keeps the whole content area to be visible 1167 cc.ContentStrategy.SHOW_ALL = new ShowAll(); 1168 // Alias: Strategy to scale the content's size proportionally to fill the whole container area 1169 cc.ContentStrategy.NO_BORDER = new NoBorder(); 1170 // Alias: Strategy to scale the content's height to container's height and proportionally scale its width 1171 cc.ContentStrategy.FIXED_HEIGHT = new FixedHeight(); 1172 // Alias: Strategy to scale the content's width to container's width and proportionally scale its height 1173 cc.ContentStrategy.FIXED_WIDTH = new FixedWidth(); 1174 1175 })(); 1176 1177 /** 1178 * <p>cc.ResolutionPolicy class is the root strategy class of scale strategy, 1179 * its main task is to maintain the compatibility with Cocos2d-x</p> 1180 * 1181 * @class 1182 * @extends cc.Class 1183 * @param {cc.ContainerStrategy} containerStg The container strategy 1184 * @param {cc.ContentStrategy} contentStg The content strategy 1185 */ 1186 cc.ResolutionPolicy = cc.Class.extend(/** @lends cc.ResolutionPolicy# */{ 1187 _containerStrategy: null, 1188 _contentStrategy: null, 1189 1190 /** 1191 * Constructor of cc.ResolutionPolicy 1192 * @param {cc.ContainerStrategy} containerStg 1193 * @param {cc.ContentStrategy} contentStg 1194 */ 1195 ctor: function (containerStg, contentStg) { 1196 this.setContainerStrategy(containerStg); 1197 this.setContentStrategy(contentStg); 1198 }, 1199 1200 /** 1201 * Manipulation before applying the resolution policy 1202 * @param {cc.view} view The target view 1203 */ 1204 preApply: function (view) { 1205 this._containerStrategy.preApply(view); 1206 this._contentStrategy.preApply(view); 1207 }, 1208 1209 /** 1210 * Function to apply this resolution policy 1211 * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}}, 1212 * The target view can then apply these value to itself, it's preferred not to modify directly its private variables 1213 * @param {cc.view} view The target view 1214 * @param {cc.Size} designedResolution The user defined design resolution 1215 * @return {object} An object contains the scale X/Y values and the viewport rect 1216 */ 1217 apply: function (view, designedResolution) { 1218 this._containerStrategy.apply(view, designedResolution); 1219 return this._contentStrategy.apply(view, designedResolution); 1220 }, 1221 1222 /** 1223 * Manipulation after appyling the strategy 1224 * @param {cc.view} view The target view 1225 */ 1226 postApply: function (view) { 1227 this._containerStrategy.postApply(view); 1228 this._contentStrategy.postApply(view); 1229 }, 1230 1231 /** 1232 * Setup the container's scale strategy 1233 * @param {cc.ContainerStrategy} containerStg 1234 */ 1235 setContainerStrategy: function (containerStg) { 1236 if (containerStg instanceof cc.ContainerStrategy) 1237 this._containerStrategy = containerStg; 1238 }, 1239 1240 /** 1241 * Setup the content's scale strategy 1242 * @param {cc.ContentStrategy} contentStg 1243 */ 1244 setContentStrategy: function (contentStg) { 1245 if (contentStg instanceof cc.ContentStrategy) 1246 this._contentStrategy = contentStg; 1247 } 1248 }); 1249 1250 /** 1251 * @memberOf cc.ResolutionPolicy# 1252 * @name EXACT_FIT 1253 * @constant 1254 * @type Number 1255 * @static 1256 * The entire application is visible in the specified area without trying to preserve the original aspect ratio.<br/> 1257 * Distortion can occur, and the application may appear stretched or compressed. 1258 */ 1259 cc.ResolutionPolicy.EXACT_FIT = 0; 1260 1261 /** 1262 * @memberOf cc.ResolutionPolicy# 1263 * @name NO_BORDER 1264 * @constant 1265 * @type Number 1266 * @static 1267 * The entire application fills the specified area, without distortion but possibly with some cropping,<br/> 1268 * while maintaining the original aspect ratio of the application. 1269 */ 1270 cc.ResolutionPolicy.NO_BORDER = 1; 1271 1272 /** 1273 * @memberOf cc.ResolutionPolicy# 1274 * @name SHOW_ALL 1275 * @constant 1276 * @type Number 1277 * @static 1278 * The entire application is visible in the specified area without distortion while maintaining the original<br/> 1279 * aspect ratio of the application. Borders can appear on two sides of the application. 1280 */ 1281 cc.ResolutionPolicy.SHOW_ALL = 2; 1282 1283 /** 1284 * @memberOf cc.ResolutionPolicy# 1285 * @name FIXED_HEIGHT 1286 * @constant 1287 * @type Number 1288 * @static 1289 * The application takes the height of the design resolution size and modifies the width of the internal<br/> 1290 * canvas so that it fits the aspect ratio of the device<br/> 1291 * no distortion will occur however you must make sure your application works on different<br/> 1292 * aspect ratios 1293 */ 1294 cc.ResolutionPolicy.FIXED_HEIGHT = 3; 1295 1296 /** 1297 * @memberOf cc.ResolutionPolicy# 1298 * @name FIXED_WIDTH 1299 * @constant 1300 * @type Number 1301 * @static 1302 * The application takes the width of the design resolution size and modifies the height of the internal<br/> 1303 * canvas so that it fits the aspect ratio of the device<br/> 1304 * no distortion will occur however you must make sure your application works on different<br/> 1305 * aspect ratios 1306 */ 1307 cc.ResolutionPolicy.FIXED_WIDTH = 4; 1308 1309 /** 1310 * @memberOf cc.ResolutionPolicy# 1311 * @name UNKNOWN 1312 * @constant 1313 * @type Number 1314 * @static 1315 * Unknow policy 1316 */ 1317 cc.ResolutionPolicy.UNKNOWN = 5; 1318