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 /** 34 * cc.view is the singleton object which represents the game window.<br/> 35 * It's main task include: <br/> 36 * - Apply the design resolution policy<br/> 37 * - Provide interaction with the window, like resize event on web, retina display support, etc...<br/> 38 * - Manage the game view port which can be different with the window<br/> 39 * - Manage the content scale and translation<br/> 40 * <br/> 41 * Since the cc.view is a singleton, you don't need to call any constructor or create functions,<br/> 42 * the standard way to use it is by calling:<br/> 43 * - cc.view.methodName(); <br/> 44 * @class 45 * @name cc.view 46 * @extend cc.Class 47 */ 48 cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ 49 _delegate: null, 50 // Size of parent node that contains cc.container and cc._canvas 51 _frameSize: null, 52 // resolution size, it is the size appropriate for the app resources. 53 _designResolutionSize: null, 54 _originalDesignResolutionSize: null, 55 // Viewport is the container's rect related to content's coordinates in pixel 56 _viewPortRect: null, 57 // The visible rect in content's coordinate in point 58 _visibleRect: null, 59 _retinaEnabled: false, 60 _autoFullScreen: true, 61 // The device's pixel ratio (for retina displays) 62 _devicePixelRatio: 1, 63 // the view name 64 _viewName: "", 65 // Custom callback for resize event 66 _resizeCallback: null, 67 _scaleX: 1, 68 _originalScaleX: 1, 69 _scaleY: 1, 70 _originalScaleY: 1, 71 _indexBitsUsed: 0, 72 _maxTouches: 5, 73 _resolutionPolicy: null, 74 _rpExactFit: null, 75 _rpShowAll: null, 76 _rpNoBorder: null, 77 _rpFixedHeight: null, 78 _rpFixedWidth: null, 79 _initialized: false, 80 81 _captured: false, 82 _wnd: null, 83 _hDC: null, 84 _hRC: null, 85 _supportTouch: false, 86 _contentTranslateLeftTop: null, 87 88 // Parent node that contains cc.container and cc._canvas 89 _frame: null, 90 _frameZoomFactor: 1.0, 91 __resizeWithBrowserSize: false, 92 _isAdjustViewPort: true, 93 94 /** 95 * Constructor of cc.EGLView 96 */ 97 ctor: function () { 98 var _t = this, d = document, _strategyer = cc.ContainerStrategy, _strategy = cc.ContentStrategy; 99 _t._frame = (cc.container.parentNode === d.body) ? d.documentElement : cc.container.parentNode; 100 _t._frameSize = cc.size(0, 0); 101 _t._initFrameSize(); 102 103 var w = cc._canvas.width, h = cc._canvas.height; 104 _t._designResolutionSize = cc.size(w, h); 105 _t._originalDesignResolutionSize = cc.size(w, h); 106 _t._viewPortRect = cc.rect(0, 0, w, h); 107 _t._visibleRect = cc.rect(0, 0, w, h); 108 _t._contentTranslateLeftTop = {left: 0, top: 0}; 109 _t._viewName = "Cocos2dHTML5"; 110 111 var sys = cc.sys; 112 _t.enableRetina(sys.os == sys.OS_IOS || sys.os == sys.OS_OSX); 113 cc.visibleRect && cc.visibleRect.init(_t._visibleRect); 114 115 // Setup system default resolution policies 116 _t._rpExactFit = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.EXACT_FIT); 117 _t._rpShowAll = new cc.ResolutionPolicy(_strategyer.PROPORTION_TO_FRAME, _strategy.SHOW_ALL); 118 _t._rpNoBorder = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.NO_BORDER); 119 _t._rpFixedHeight = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_HEIGHT); 120 _t._rpFixedWidth = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_WIDTH); 121 122 _t._hDC = cc._canvas; 123 _t._hRC = cc._renderContext; 124 }, 125 126 // Resize helper functions 127 _resizeEvent: function () { 128 var width = this._originalDesignResolutionSize.width; 129 var height = this._originalDesignResolutionSize.height; 130 if (this._resizeCallback) { 131 this._initFrameSize(); 132 this._resizeCallback.call(); 133 } 134 if (width > 0) 135 this.setDesignResolutionSize(width, height, this._resolutionPolicy); 136 }, 137 138 /** 139 * Sets whether resize canvas automatically when browser's size changed.<br/> 140 * Useful only on web. 141 * @param {Boolean} enabled Whether enable automatic resize with browser's resize event 142 */ 143 resizeWithBrowserSize: function (enabled) { 144 var adjustSize, _t = this; 145 if (enabled) { 146 //enable 147 if (!_t.__resizeWithBrowserSize) { 148 _t.__resizeWithBrowserSize = true; 149 adjustSize = _t._resizeEvent.bind(_t); 150 cc._addEventListener(window, 'resize', adjustSize, false); 151 } 152 } else { 153 //disable 154 if (_t.__resizeWithBrowserSize) { 155 _t.__resizeWithBrowserSize = true; 156 adjustSize = _t._resizeEvent.bind(_t); 157 window.removeEventListener('resize', adjustSize, false); 158 } 159 } 160 }, 161 162 /** 163 * Sets the callback function for cc.view's resize action,<br/> 164 * this callback will be invoked before applying resolution policy, <br/> 165 * so you can do any additional modifications within the callback.<br/> 166 * Useful only on web. 167 * @param {Function} callback The callback function 168 */ 169 setResizeCallback: function (callback) { 170 if (typeof callback == "function" || callback == null) { 171 this._resizeCallback = callback; 172 } 173 }, 174 175 _initFrameSize: function () { 176 var locFrameSize = this._frameSize; 177 locFrameSize.width = this._frame.clientWidth; 178 locFrameSize.height = this._frame.clientHeight; 179 }, 180 181 // hack 182 _adjustSizeKeepCanvasSize: function () { 183 var designWidth = this._originalDesignResolutionSize.width; 184 var designHeight = this._originalDesignResolutionSize.height; 185 if (designWidth > 0) 186 this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy); 187 }, 188 189 _setViewPortMeta: function (width, height) { 190 if (this._isAdjustViewPort) { 191 var viewportMetas = {"user-scalable": "no", "maximum-scale": "1.0", "initial-scale": "1.0"}, elems = document.getElementsByName("viewport"), vp, content; 192 if (elems.length == 0) { 193 vp = cc.newElement("meta"); 194 vp.name = "viewport"; 195 vp.content = ""; 196 document.head.appendChild(vp); 197 } 198 else vp = elems[0]; 199 200 // For avoiding Android Firefox issue, to remove once firefox fixes its issue. 201 if (cc.sys.isMobile && cc.sys.browserType == cc.sys.BROWSER_TYPE_FIREFOX) { 202 vp.content = "initial-scale:1"; 203 return; 204 } 205 206 content = vp.content; 207 for (var key in viewportMetas) { 208 var pattern = new RegExp(key); 209 if (!pattern.test(content)) { 210 content += (content == "" ? "" : ",") + key + "=" + viewportMetas[key]; 211 } 212 } 213 /* 214 if(width<=320){ 215 width = 321; 216 } 217 if(height) 218 content ="height="+height+","+content; 219 if(width) 220 content ="width="+width+","+content; 221 */ 222 vp.content = content; 223 } 224 }, 225 226 // RenderTexture hacker 227 _setScaleXYForRenderTexture: function () { 228 //hack for RenderTexture on canvas mode when adapting multiple resolution resources 229 var scaleFactor = cc.contentScaleFactor(); 230 this._scaleX = scaleFactor; 231 this._scaleY = scaleFactor; 232 }, 233 234 // Other helper functions 235 _resetScale: function () { 236 this._scaleX = this._originalScaleX; 237 this._scaleY = this._originalScaleY; 238 }, 239 240 // Useless, just make sure the compatibility temporarily, should be removed 241 _adjustSizeToBrowser: function () { 242 }, 243 244 initialize: function () { 245 this._initialized = true; 246 }, 247 248 /** 249 * Sets whether the engine modify the "viewport" meta in your web page.<br/> 250 * It's enabled by default, we strongly suggest you not to disable it.<br/> 251 * And even when it's enabled, you can still set your own "viewport" meta, it won't be overridden<br/> 252 * Only useful on web 253 * @param {Boolean} enabled Enable automatic modification to "viewport" meta 254 */ 255 adjustViewPort: function (enabled) { 256 this._isAdjustViewPort = enabled; 257 }, 258 259 /** 260 * Retina support is enabled by default for Apple device but disabled for other devices,<br/> 261 * it takes effect only when you called setDesignResolutionPolicy<br/> 262 * Only useful on web 263 * @param {Boolean} enabled Enable or disable retina display 264 */ 265 enableRetina: function(enabled) { 266 this._retinaEnabled = enabled ? true : false; 267 }, 268 269 /** 270 * Check whether retina display is enabled.<br/> 271 * Only useful on web 272 * @return {Boolean} 273 */ 274 isRetinaEnabled: function() { 275 return this._retinaEnabled; 276 }, 277 278 /** 279 * If enabled, the application will try automatically to enter full screen mode on mobile devices<br/> 280 * You can pass true as parameter to enable it and disable it by passing false.<br/> 281 * Only useful on web 282 * @param {Boolean} enabled Enable or disable auto full screen on mobile devices 283 */ 284 enableAutoFullScreen: function(enabled) { 285 this._autoFullScreen = enabled ? true : false; 286 }, 287 288 /** 289 * Check whether auto full screen is enabled.<br/> 290 * Only useful on web 291 * @return {Boolean} Auto full screen enabled or not 292 */ 293 isAutoFullScreenEnabled: function() { 294 return this._autoFullScreen; 295 }, 296 297 /** 298 * Force destroying EGL view, subclass must implement this method. 299 */ 300 end: function () { 301 }, 302 303 /** 304 * Get whether render system is ready(no matter opengl or canvas),<br/> 305 * this name is for the compatibility with cocos2d-x, subclass must implement this method. 306 * @return {Boolean} 307 */ 308 isOpenGLReady: function () { 309 return (this._hDC != null && this._hRC != null); 310 }, 311 312 /* 313 * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop. 314 * @param {Number} zoomFactor 315 */ 316 setFrameZoomFactor: function (zoomFactor) { 317 this._frameZoomFactor = zoomFactor; 318 this.centerWindow(); 319 cc.director.setProjection(cc.director.getProjection()); 320 }, 321 322 /** 323 * Exchanges the front and back buffers, subclass must implement this method. 324 */ 325 swapBuffers: function () { 326 }, 327 328 /** 329 * Open or close IME keyboard , subclass must implement this method. 330 * @param {Boolean} isOpen 331 */ 332 setIMEKeyboardState: function (isOpen) { 333 }, 334 335 /** 336 * Sets the resolution translate on EGLView 337 * @param {Number} offsetLeft 338 * @param {Number} offsetTop 339 */ 340 setContentTranslateLeftTop: function (offsetLeft, offsetTop) { 341 this._contentTranslateLeftTop = {left: offsetLeft, top: offsetTop}; 342 }, 343 344 /** 345 * Returns the resolution translate on EGLView 346 * @return {cc.Size|Object} 347 */ 348 getContentTranslateLeftTop: function () { 349 return this._contentTranslateLeftTop; 350 }, 351 352 /** 353 * Returns the frame size of the view.<br/> 354 * On native platforms, it returns the screen size since the view is a fullscreen view.<br/> 355 * On web, it returns the size of the canvas's outer DOM element. 356 * @return {cc.Size} 357 */ 358 getFrameSize: function () { 359 return cc.size(this._frameSize.width, this._frameSize.height); 360 }, 361 362 /** 363 * On native, it sets the frame size of view.<br/> 364 * On web, it sets the size of the canvas's outer DOM element. 365 * @param {Number} width 366 * @param {Number} height 367 */ 368 setFrameSize: function (width, height) { 369 this._frameSize.width = width; 370 this._frameSize.height = height; 371 this._frame.style.width = width + "px"; 372 this._frame.style.height = height + "px"; 373 //this.centerWindow(); 374 this._resizeEvent(); 375 cc.director.setProjection(cc.director.getProjection()); 376 }, 377 378 /** 379 * Empty function 380 */ 381 centerWindow: function () { 382 }, 383 384 /** 385 * Returns the visible area size of the view port. 386 * @return {cc.Size} 387 */ 388 getVisibleSize: function () { 389 return cc.size(this._visibleRect.width,this._visibleRect.height); 390 }, 391 392 /** 393 * Returns the visible origin of the view port. 394 * @return {cc.Point} 395 */ 396 getVisibleOrigin: function () { 397 return cc.p(this._visibleRect.x,this._visibleRect.y); 398 }, 399 400 /** 401 * Returns whether developer can set content's scale factor. 402 * @return {Boolean} 403 */ 404 canSetContentScaleFactor: function () { 405 return true; 406 }, 407 408 /** 409 * Returns the current resolution policy 410 * @see cc.ResolutionPolicy 411 * @return {cc.ResolutionPolicy} 412 */ 413 getResolutionPolicy: function () { 414 return this._resolutionPolicy; 415 }, 416 417 /** 418 * Sets the current resolution policy 419 * @see cc.ResolutionPolicy 420 * @param {cc.ResolutionPolicy|Number} resolutionPolicy 421 */ 422 setResolutionPolicy: function (resolutionPolicy) { 423 var _t = this; 424 if (resolutionPolicy instanceof cc.ResolutionPolicy) { 425 _t._resolutionPolicy = resolutionPolicy; 426 } 427 // Ensure compatibility with JSB 428 else { 429 var _locPolicy = cc.ResolutionPolicy; 430 if(resolutionPolicy === _locPolicy.EXACT_FIT) 431 _t._resolutionPolicy = _t._rpExactFit; 432 if(resolutionPolicy === _locPolicy.SHOW_ALL) 433 _t._resolutionPolicy = _t._rpShowAll; 434 if(resolutionPolicy === _locPolicy.NO_BORDER) 435 _t._resolutionPolicy = _t._rpNoBorder; 436 if(resolutionPolicy === _locPolicy.FIXED_HEIGHT) 437 _t._resolutionPolicy = _t._rpFixedHeight; 438 if(resolutionPolicy === _locPolicy.FIXED_WIDTH) 439 _t._resolutionPolicy = _t._rpFixedWidth; 440 } 441 }, 442 443 /** 444 * Sets the resolution policy with designed view size in points.<br/> 445 * The resolution policy include: <br/> 446 * [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/> 447 * [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/> 448 * [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/> 449 * [4] ResolutionFixedHeight Scale the content's height to screen's height and proportionally scale its width<br/> 450 * [5] ResolutionFixedWidth Scale the content's width to screen's width and proportionally scale its height<br/> 451 * [cc.ResolutionPolicy] [Web only feature] Custom resolution policy, constructed by cc.ResolutionPolicy<br/> 452 * @param {Number} width Design resolution width. 453 * @param {Number} height Design resolution height. 454 * @param {cc.ResolutionPolicy|Number} resolutionPolicy The resolution policy desired 455 */ 456 setDesignResolutionSize: function (width, height, resolutionPolicy) { 457 // Defensive code 458 if (isNaN(width) || width == 0 || isNaN(height) || height == 0) { 459 cc.log(cc._LogInfos.EGLView_setDesignResolutionSize); 460 return; 461 } 462 var _t = this; 463 _t.setResolutionPolicy(resolutionPolicy); 464 var policy = _t._resolutionPolicy; 465 if (policy) 466 policy.preApply(_t); 467 else { 468 cc.log(cc._LogInfos.EGLView_setDesignResolutionSize_2); 469 return; 470 } 471 472 // Reinit frame size 473 var frameW = _t._frameSize.width, frameH = _t._frameSize.height; 474 if (cc.sys.isMobile) 475 _t._setViewPortMeta(_t._frameSize.width, _t._frameSize.height); 476 _t._initFrameSize(); 477 // No change 478 if (resolutionPolicy == _t._resolutionPolicy 479 && width == _t._originalDesignResolutionSize.width && height == _t._originalDesignResolutionSize.height 480 && frameW == _t._frameSize.width && frameH == _t._frameSize.height) 481 return; 482 _t._designResolutionSize = cc.size(width, height); 483 _t._originalDesignResolutionSize = cc.size(width, height); 484 485 var result = policy.apply(_t, _t._designResolutionSize); 486 if (result.scale && result.scale.length == 2) { 487 _t._scaleX = result.scale[0]; 488 _t._scaleY = result.scale[1]; 489 } 490 if (result.viewport) { 491 var vp = _t._viewPortRect = result.viewport, visible = _t._visibleRect; 492 visible.width = cc._canvas.width / _t._scaleX; 493 visible.height = cc._canvas.height / _t._scaleY; 494 visible.x = -vp.x / _t._scaleX; 495 visible.y = -vp.y / _t._scaleY; 496 } 497 498 // reset director's member variables to fit visible rect 499 var director = cc.director; 500 cc.winSize.width = director._winSizeInPoints.width = _t._visibleRect.width; 501 cc.winSize.height = director._winSizeInPoints.height = _t._visibleRect.height; 502 503 policy.postApply(_t); 504 505 if (cc._renderType == cc._RENDER_TYPE_WEBGL) { 506 // reset director's member variables to fit visible rect 507 director._createStatsLabel(); 508 director.setGLDefaultValues(); 509 } 510 511 _t._originalScaleX = _t._scaleX; 512 _t._originalScaleY = _t._scaleY; 513 // For editbox 514 if (cc.DOM) 515 cc.DOM._resetEGLViewDiv(); 516 cc.visibleRect && cc.visibleRect.init(_t._visibleRect); 517 }, 518 519 /** 520 * Returns the designed size for the view. 521 * Default resolution size is the same as 'getFrameSize'. 522 * @return {cc.Size} 523 */ 524 getDesignResolutionSize: function () { 525 return cc.size(this._designResolutionSize.width, this._designResolutionSize.height); 526 }, 527 528 /** 529 * Sets view port rectangle with points. 530 * @param {Number} x 531 * @param {Number} y 532 * @param {Number} w width 533 * @param {Number} h height 534 */ 535 setViewPortInPoints: function (x, y, w, h) { 536 var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY; 537 cc._renderContext.viewport((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor), 538 (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor), 539 (w * locScaleX * locFrameZoomFactor), 540 (h * locScaleY * locFrameZoomFactor)); 541 }, 542 543 /** 544 * Sets Scissor rectangle with points. 545 * @param {Number} x 546 * @param {Number} y 547 * @param {Number} w 548 * @param {Number} h 549 */ 550 setScissorInPoints: function (x, y, w, h) { 551 var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY; 552 cc._renderContext.scissor((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor), 553 (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor), 554 (w * locScaleX * locFrameZoomFactor), 555 (h * locScaleY * locFrameZoomFactor)); 556 }, 557 558 /** 559 * Returns whether GL_SCISSOR_TEST is enable 560 * @return {Boolean} 561 */ 562 isScissorEnabled: function () { 563 var gl = cc._renderContext; 564 return gl.isEnabled(gl.SCISSOR_TEST); 565 }, 566 567 /** 568 * Returns the current scissor rectangle 569 * @return {cc.Rect} 570 */ 571 getScissorRect: function () { 572 var gl = cc._renderContext, scaleX = this._scaleX, scaleY = this._scaleY; 573 var boxArr = gl.getParameter(gl.SCISSOR_BOX); 574 return cc.rect((boxArr[0] - this._viewPortRect.x) / scaleX, (boxArr[1] - this._viewPortRect.y) / scaleY, 575 boxArr[2] / scaleX, boxArr[3] / scaleY); 576 }, 577 578 /** 579 * Sets the name of the view 580 * @param {String} viewName 581 */ 582 setViewName: function (viewName) { 583 if (viewName != null && viewName.length > 0) { 584 this._viewName = viewName; 585 } 586 }, 587 588 /** 589 * Returns the name of the view 590 * @return {String} 591 */ 592 getViewName: function () { 593 return this._viewName; 594 }, 595 596 /** 597 * Returns the view port rectangle. 598 * @return {cc.Rect} 599 */ 600 getViewPortRect: function () { 601 return this._viewPortRect; 602 }, 603 604 /** 605 * Returns scale factor of the horizontal direction (X axis). 606 * @return {Number} 607 */ 608 getScaleX: function () { 609 return this._scaleX; 610 }, 611 612 /** 613 * Returns scale factor of the vertical direction (Y axis). 614 * @return {Number} 615 */ 616 getScaleY: function () { 617 return this._scaleY; 618 }, 619 620 /** 621 * Returns device pixel ratio for retina display. 622 * @return {Number} 623 */ 624 getDevicePixelRatio: function() { 625 return this._devicePixelRatio; 626 }, 627 628 /** 629 * Returns the real location in view for a translation based on a related position 630 * @param {Number} tx The X axis translation 631 * @param {Number} ty The Y axis translation 632 * @param {Object} relatedPos The related position object including "left", "top", "width", "height" informations 633 * @return {cc.Point} 634 */ 635 convertToLocationInView: function (tx, ty, relatedPos) { 636 return {x: this._devicePixelRatio * (tx - relatedPos.left), y: this._devicePixelRatio * (relatedPos.top + relatedPos.height - ty)}; 637 }, 638 639 _convertMouseToLocationInView: function(point, relatedPos) { 640 var locViewPortRect = this._viewPortRect, _t = this; 641 point.x = ((_t._devicePixelRatio * (point.x - relatedPos.left)) - locViewPortRect.x) / _t._scaleX; 642 point.y = (_t._devicePixelRatio * (relatedPos.top + relatedPos.height - point.y) - locViewPortRect.y) / _t._scaleY; 643 }, 644 645 _convertTouchesWithScale: function(touches){ 646 var locViewPortRect = this._viewPortRect, locScaleX = this._scaleX, locScaleY = this._scaleY, selTouch, selPoint, selPrePoint; 647 for( var i = 0; i < touches.length; i ++){ 648 selTouch = touches[i]; 649 selPoint = selTouch._point; 650 selPrePoint = selTouch._prevPoint; 651 selTouch._setPoint((selPoint.x - locViewPortRect.x) / locScaleX, 652 (selPoint.y - locViewPortRect.y) / locScaleY); 653 selTouch._setPrevPoint((selPrePoint.x - locViewPortRect.x) / locScaleX, 654 (selPrePoint.y - locViewPortRect.y) / locScaleY); 655 } 656 } 657 }); 658 659 /** 660 * @function 661 * @return {cc.EGLView} 662 * @private 663 */ 664 cc.EGLView._getInstance = function () { 665 if (!this._instance) { 666 this._instance = this._instance || new cc.EGLView(); 667 this._instance.initialize(); 668 } 669 return this._instance; 670 }; 671 672 /** 673 * <p>cc.ContainerStrategy class is the root strategy class of container's scale strategy, 674 * it controls the behavior of how to scale the cc.container and cc._canvas object</p> 675 * 676 * @class 677 * @extends cc.Class 678 */ 679 cc.ContainerStrategy = cc.Class.extend(/** @lends cc.ContainerStrategy# */{ 680 /** 681 * Manipulation before appling the strategy 682 * @param {cc.view} The target view 683 */ 684 preApply: function (view) { 685 }, 686 687 /** 688 * Function to apply this strategy 689 * @param {cc.view} view 690 * @param {cc.Size} designedResolution 691 */ 692 apply: function (view, designedResolution) { 693 }, 694 695 /** 696 * Manipulation after applying the strategy 697 * @param {cc.view} view The target view 698 */ 699 postApply: function (view) { 700 701 }, 702 703 _setupContainer: function (view, w, h) { 704 var frame = view._frame; 705 if (cc.view._autoFullScreen && cc.sys.isMobile && frame == document.documentElement) { 706 // Automatically full screen when user touches on mobile version 707 cc.screen.autoFullScreen(frame); 708 } 709 710 var locCanvasElement = cc._canvas, locContainer = cc.container; 711 // Setup container 712 locContainer.style.width = locCanvasElement.style.width = w + "px"; 713 locContainer.style.height = locCanvasElement.style.height = h + "px"; 714 // Setup pixel ratio for retina display 715 var devicePixelRatio = view._devicePixelRatio = 1; 716 if (view.isRetinaEnabled()) 717 devicePixelRatio = view._devicePixelRatio = window.devicePixelRatio || 1; 718 // Setup canvas 719 locCanvasElement.width = w * devicePixelRatio; 720 locCanvasElement.height = h * devicePixelRatio; 721 722 var body = document.body, style; 723 if (body && (style = body.style)) { 724 style.paddingTop = style.paddingTop || "0px"; 725 style.paddingRight = style.paddingRight || "0px"; 726 style.paddingBottom = style.paddingBottom || "0px"; 727 style.paddingLeft = style.paddingLeft || "0px"; 728 style.borderTop = style.borderTop || "0px"; 729 style.borderRight = style.borderRight || "0px"; 730 style.borderBottom = style.borderBottom || "0px"; 731 style.borderLeft = style.borderLeft || "0px"; 732 style.marginTop = style.marginTop || "0px"; 733 style.marginRight = style.marginRight || "0px"; 734 style.marginBottom = style.marginBottom || "0px"; 735 style.marginLeft = style.marginLeft || "0px"; 736 } 737 }, 738 739 _fixContainer: function () { 740 // Add container to document body 741 document.body.insertBefore(cc.container, document.body.firstChild); 742 // Set body's width height to window's size, and forbid overflow, so that game will be centered 743 var bs = document.body.style; 744 bs.width = window.innerWidth + "px"; 745 bs.height = window.innerHeight + "px"; 746 bs.overflow = "hidden"; 747 // Body size solution doesn't work on all mobile browser so this is the aleternative: fixed container 748 var contStyle = cc.container.style; 749 contStyle.position = "fixed"; 750 contStyle.left = contStyle.top = "0px"; 751 // Reposition body 752 document.body.scrollTop = 0; 753 } 754 }); 755 756 /** 757 * <p>cc.ContentStrategy class is the root strategy class of content's scale strategy, 758 * it controls the behavior of how to scale the scene and setup the viewport for the game</p> 759 * 760 * @class 761 * @extends cc.Class 762 */ 763 cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{ 764 765 _result: { 766 scale: [1, 1], 767 viewport: null 768 }, 769 770 _buildResult: function (containerW, containerH, contentW, contentH, scaleX, scaleY) { 771 // Makes content fit better the canvas 772 Math.abs(containerW - contentW) < 2 && (contentW = containerW); 773 Math.abs(containerH - contentH) < 2 && (contentH = containerH); 774 775 var viewport = cc.rect(Math.round((containerW - contentW) / 2), 776 Math.round((containerH - contentH) / 2), 777 contentW, contentH); 778 779 // Translate the content 780 if (cc._renderType == cc._RENDER_TYPE_CANVAS) 781 cc._renderContext.translate(viewport.x, viewport.y + contentH); 782 783 this._result.scale = [scaleX, scaleY]; 784 this._result.viewport = viewport; 785 return this._result; 786 }, 787 788 /** 789 * Manipulation before applying the strategy 790 * @param {cc.view} view The target view 791 */ 792 preApply: function (view) { 793 }, 794 795 /** 796 * Function to apply this strategy 797 * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}}, 798 * The target view can then apply these value to itself, it's preferred not to modify directly its private variables 799 * @param {cc.view} view 800 * @param {cc.Size} designedResolution 801 * @return {object} scaleAndViewportRect 802 */ 803 apply: function (view, designedResolution) { 804 return {"scale": [1, 1]}; 805 }, 806 807 /** 808 * Manipulation after applying the strategy 809 * @param {cc.view} view The target view 810 */ 811 postApply: function (view) { 812 } 813 }); 814 815 (function () { 816 817 // Container scale strategys 818 /** 819 * @class 820 * @extends cc.ContainerStrategy 821 */ 822 var EqualToFrame = cc.ContainerStrategy.extend({ 823 apply: function (view) { 824 this._setupContainer(view, view._frameSize.width, view._frameSize.height); 825 } 826 }); 827 828 /** 829 * @class 830 * @extends cc.ContainerStrategy 831 */ 832 var ProportionalToFrame = cc.ContainerStrategy.extend({ 833 apply: function (view, designedResolution) { 834 var frameW = view._frameSize.width, frameH = view._frameSize.height, containerStyle = cc.container.style, 835 designW = designedResolution.width, designH = designedResolution.height, 836 scaleX = frameW / designW, scaleY = frameH / designH, 837 containerW, containerH; 838 839 scaleX < scaleY ? (containerW = frameW, containerH = designH * scaleX) : (containerW = designW * scaleY, containerH = frameH); 840 841 // Adjust container size with integer value 842 var offx = Math.round((frameW - containerW) / 2); 843 var offy = Math.round((frameH - containerH) / 2); 844 containerW = frameW - 2 * offx; 845 containerH = frameH - 2 * offy; 846 847 this._setupContainer(view, containerW, containerH); 848 // Setup container's margin 849 containerStyle.marginLeft = offx + "px"; 850 containerStyle.marginRight = offx + "px"; 851 containerStyle.marginTop = offy + "px"; 852 containerStyle.marginBottom = offy + "px"; 853 } 854 }); 855 856 /** 857 * @class 858 * @extends EqualToFrame 859 */ 860 var EqualToWindow = EqualToFrame.extend({ 861 preApply: function (view) { 862 this._super(view); 863 view._frame = document.documentElement; 864 }, 865 866 apply: function (view) { 867 this._super(view); 868 this._fixContainer(); 869 } 870 }); 871 872 /** 873 * @class 874 * @extends ProportionalToFrame 875 */ 876 var ProportionalToWindow = ProportionalToFrame.extend({ 877 preApply: function (view) { 878 this._super(view); 879 view._frame = document.documentElement; 880 }, 881 882 apply: function (view, designedResolution) { 883 this._super(view, designedResolution); 884 this._fixContainer(); 885 } 886 }); 887 888 /** 889 * @class 890 * @extends cc.ContainerStrategy 891 */ 892 var OriginalContainer = cc.ContainerStrategy.extend({ 893 apply: function (view) { 894 this._setupContainer(view, cc._canvas.width, cc._canvas.height); 895 } 896 }); 897 898 // #NOT STABLE on Android# Alias: Strategy that makes the container's size equals to the window's size 899 // cc.ContainerStrategy.EQUAL_TO_WINDOW = new EqualToWindow(); 900 // #NOT STABLE on Android# Alias: Strategy that scale proportionally the container's size to window's size 901 // cc.ContainerStrategy.PROPORTION_TO_WINDOW = new ProportionalToWindow(); 902 // Alias: Strategy that makes the container's size equals to the frame's size 903 cc.ContainerStrategy.EQUAL_TO_FRAME = new EqualToFrame(); 904 // Alias: Strategy that scale proportionally the container's size to frame's size 905 cc.ContainerStrategy.PROPORTION_TO_FRAME = new ProportionalToFrame(); 906 // Alias: Strategy that keeps the original container's size 907 cc.ContainerStrategy.ORIGINAL_CONTAINER = new OriginalContainer(); 908 909 // Content scale strategys 910 var ExactFit = cc.ContentStrategy.extend({ 911 apply: function (view, designedResolution) { 912 var containerW = cc._canvas.width, containerH = cc._canvas.height, 913 scaleX = containerW / designedResolution.width, scaleY = containerH / designedResolution.height; 914 915 return this._buildResult(containerW, containerH, containerW, containerH, scaleX, scaleY); 916 } 917 }); 918 919 var ShowAll = cc.ContentStrategy.extend({ 920 apply: function (view, designedResolution) { 921 var containerW = cc._canvas.width, containerH = cc._canvas.height, 922 designW = designedResolution.width, designH = designedResolution.height, 923 scaleX = containerW / designW, scaleY = containerH / designH, scale = 0, 924 contentW, contentH; 925 926 scaleX < scaleY ? (scale = scaleX, contentW = containerW, contentH = designH * scale) 927 : (scale = scaleY, contentW = designW * scale, contentH = containerH); 928 929 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 930 } 931 }); 932 933 var NoBorder = cc.ContentStrategy.extend({ 934 apply: function (view, designedResolution) { 935 var containerW = cc._canvas.width, containerH = cc._canvas.height, 936 designW = designedResolution.width, designH = designedResolution.height, 937 scaleX = containerW / designW, scaleY = containerH / designH, scale, 938 contentW, contentH; 939 940 scaleX < scaleY ? (scale = scaleY, contentW = designW * scale, contentH = containerH) 941 : (scale = scaleX, contentW = containerW, contentH = designH * scale); 942 943 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 944 } 945 }); 946 947 var FixedHeight = cc.ContentStrategy.extend({ 948 apply: function (view, designedResolution) { 949 var containerW = cc._canvas.width, containerH = cc._canvas.height, 950 designH = designedResolution.height, scale = containerH / designH, 951 contentW = containerW, contentH = containerH; 952 953 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 954 }, 955 956 postApply: function (view) { 957 cc.director._winSizeInPoints = view.getVisibleSize(); 958 } 959 }); 960 961 var FixedWidth = cc.ContentStrategy.extend({ 962 apply: function (view, designedResolution) { 963 var containerW = cc._canvas.width, containerH = cc._canvas.height, 964 designW = designedResolution.width, scale = containerW / designW, 965 contentW = containerW, contentH = containerH; 966 967 return this._buildResult(containerW, containerH, contentW, contentH, scale, scale); 968 }, 969 970 postApply: function (view) { 971 cc.director._winSizeInPoints = view.getVisibleSize(); 972 } 973 }); 974 975 // Alias: Strategy to scale the content's size to container's size, non proportional 976 cc.ContentStrategy.EXACT_FIT = new ExactFit(); 977 // Alias: Strategy to scale the content's size proportionally to maximum size and keeps the whole content area to be visible 978 cc.ContentStrategy.SHOW_ALL = new ShowAll(); 979 // Alias: Strategy to scale the content's size proportionally to fill the whole container area 980 cc.ContentStrategy.NO_BORDER = new NoBorder(); 981 // Alias: Strategy to scale the content's height to container's height and proportionally scale its width 982 cc.ContentStrategy.FIXED_HEIGHT = new FixedHeight(); 983 // Alias: Strategy to scale the content's width to container's width and proportionally scale its height 984 cc.ContentStrategy.FIXED_WIDTH = new FixedWidth(); 985 986 })(); 987 988 /** 989 * <p>cc.ResolutionPolicy class is the root strategy class of scale strategy, 990 * its main task is to maintain the compatibility with Cocos2d-x</p> 991 * 992 * @class 993 * @extends cc.Class 994 * @param {cc.ContainerStrategy} containerStg The container strategy 995 * @param {cc.ContentStrategy} contentStg The content strategy 996 */ 997 cc.ResolutionPolicy = cc.Class.extend(/** @lends cc.ResolutionPolicy# */{ 998 _containerStrategy: null, 999 _contentStrategy: null, 1000 1001 /** 1002 * Constructor of cc.ResolutionPolicy 1003 * @param {cc.ContainerStrategy} containerStg 1004 * @param {cc.ContentStrategy} contentStg 1005 */ 1006 ctor: function (containerStg, contentStg) { 1007 this.setContainerStrategy(containerStg); 1008 this.setContentStrategy(contentStg); 1009 }, 1010 1011 /** 1012 * Manipulation before applying the resolution policy 1013 * @param {cc.view} view The target view 1014 */ 1015 preApply: function (view) { 1016 this._containerStrategy.preApply(view); 1017 this._contentStrategy.preApply(view); 1018 }, 1019 1020 /** 1021 * Function to apply this resolution policy 1022 * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}}, 1023 * The target view can then apply these value to itself, it's preferred not to modify directly its private variables 1024 * @param {cc.view} view The target view 1025 * @param {cc.Size} designedResolution The user defined design resolution 1026 * @return {object} An object contains the scale X/Y values and the viewport rect 1027 */ 1028 apply: function (view, designedResolution) { 1029 this._containerStrategy.apply(view, designedResolution); 1030 return this._contentStrategy.apply(view, designedResolution); 1031 }, 1032 1033 /** 1034 * Manipulation after appyling the strategy 1035 * @param {cc.view} view The target view 1036 */ 1037 postApply: function (view) { 1038 this._containerStrategy.postApply(view); 1039 this._contentStrategy.postApply(view); 1040 }, 1041 1042 /** 1043 * Setup the container's scale strategy 1044 * @param {cc.ContainerStrategy} containerStg 1045 */ 1046 setContainerStrategy: function (containerStg) { 1047 if (containerStg instanceof cc.ContainerStrategy) 1048 this._containerStrategy = containerStg; 1049 }, 1050 1051 /** 1052 * Setup the content's scale strategy 1053 * @param {cc.ContentStrategy} contentStg 1054 */ 1055 setContentStrategy: function (contentStg) { 1056 if (contentStg instanceof cc.ContentStrategy) 1057 this._contentStrategy = contentStg; 1058 } 1059 }); 1060 1061 /** 1062 * @memberOf cc.ResolutionPolicy# 1063 * @name EXACT_FIT 1064 * @constant 1065 * @type Number 1066 * @static 1067 * The entire application is visible in the specified area without trying to preserve the original aspect ratio.<br/> 1068 * Distortion can occur, and the application may appear stretched or compressed. 1069 */ 1070 cc.ResolutionPolicy.EXACT_FIT = 0; 1071 1072 /** 1073 * @memberOf cc.ResolutionPolicy# 1074 * @name NO_BORDER 1075 * @constant 1076 * @type Number 1077 * @static 1078 * The entire application fills the specified area, without distortion but possibly with some cropping,<br/> 1079 * while maintaining the original aspect ratio of the application. 1080 */ 1081 cc.ResolutionPolicy.NO_BORDER = 1; 1082 1083 /** 1084 * @memberOf cc.ResolutionPolicy# 1085 * @name SHOW_ALL 1086 * @constant 1087 * @type Number 1088 * @static 1089 * The entire application is visible in the specified area without distortion while maintaining the original<br/> 1090 * aspect ratio of the application. Borders can appear on two sides of the application. 1091 */ 1092 cc.ResolutionPolicy.SHOW_ALL = 2; 1093 1094 /** 1095 * @memberOf cc.ResolutionPolicy# 1096 * @name FIXED_HEIGHT 1097 * @constant 1098 * @type Number 1099 * @static 1100 * The application takes the height of the design resolution size and modifies the width of the internal<br/> 1101 * canvas so that it fits the aspect ratio of the device<br/> 1102 * no distortion will occur however you must make sure your application works on different<br/> 1103 * aspect ratios 1104 */ 1105 cc.ResolutionPolicy.FIXED_HEIGHT = 3; 1106 1107 /** 1108 * @memberOf cc.ResolutionPolicy# 1109 * @name FIXED_WIDTH 1110 * @constant 1111 * @type Number 1112 * @static 1113 * The application takes the width of the design resolution size and modifies the height of the internal<br/> 1114 * canvas so that it fits the aspect ratio of the device<br/> 1115 * no distortion will occur however you must make sure your application works on different<br/> 1116 * aspect ratios 1117 */ 1118 cc.ResolutionPolicy.FIXED_WIDTH = 4; 1119 1120 /** 1121 * @memberOf cc.ResolutionPolicy# 1122 * @name UNKNOWN 1123 * @constant 1124 * @type Number 1125 * @static 1126 * Unknow policy 1127 */ 1128 cc.ResolutionPolicy.UNKNOWN = 5;