CCEGLView.js 40 KB

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