CCLayer.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  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. /** cc.Layer is a subclass of cc.Node that implements the TouchEventsDelegate protocol.<br/>
  23. * All features from cc.Node are valid, plus the bake feature: Baked layer can cache a static layer to improve performance
  24. * @class
  25. * @extends cc.Node
  26. */
  27. cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
  28. _isBaked: false,
  29. _bakeSprite: null,
  30. _className: "Layer",
  31. /**
  32. * <p>Constructor of cc.Layer, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.</p>
  33. */
  34. ctor: function () {
  35. var nodep = cc.Node.prototype;
  36. nodep.ctor.call(this);
  37. this._ignoreAnchorPointForPosition = true;
  38. nodep.setAnchorPoint.call(this, 0.5, 0.5);
  39. nodep.setContentSize.call(this, cc.winSize);
  40. },
  41. /**
  42. * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
  43. */
  44. init: function(){
  45. var _t = this;
  46. _t._ignoreAnchorPointForPosition = true;
  47. _t.setAnchorPoint(0.5, 0.5);
  48. _t.setContentSize(cc.winSize);
  49. _t.cascadeOpacity = false;
  50. _t.cascadeColor = false;
  51. return true;
  52. },
  53. /**
  54. * Sets the layer to cache all of children to a bake sprite, and draw itself by bake sprite. recommend using it in UI.<br/>
  55. * This is useful only in html5 engine
  56. * @function
  57. * @see cc.Layer#unbake
  58. */
  59. bake: null,
  60. /**
  61. * Cancel the layer to cache all of children to a bake sprite.<br/>
  62. * This is useful only in html5 engine
  63. * @function
  64. * @see cc.Layer#bake
  65. */
  66. unbake: null,
  67. /**
  68. * Determines if the layer is baked.
  69. * @function
  70. * @returns {boolean}
  71. * @see cc.Layer#bake and cc.Layer#unbake
  72. */
  73. isBaked: function(){
  74. return this._isBaked;
  75. },
  76. visit: null
  77. });
  78. /**
  79. * Creates a layer
  80. * @deprecated since v3.0, please use the new construction instead
  81. * @see cc.Layer
  82. * @return {cc.Layer|Null}
  83. */
  84. cc.Layer.create = function () {
  85. return new cc.Layer();
  86. };
  87. if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
  88. var p = cc.Layer.prototype;
  89. p.bake = function(){
  90. if (!this._isBaked) {
  91. //limit: 1. its children's blendfunc are invalid.
  92. this._isBaked = this._cacheDirty = true;
  93. this._cachedParent = this;
  94. var children = this._children;
  95. for(var i = 0, len = children.length; i < len; i++)
  96. children[i]._setCachedParent(this);
  97. if (!this._bakeSprite)
  98. this._bakeSprite = new cc.BakeSprite();
  99. }
  100. };
  101. p.unbake = function(){
  102. if (this._isBaked) {
  103. this._isBaked = false;
  104. this._cacheDirty = true;
  105. this._cachedParent = null;
  106. var children = this._children;
  107. for(var i = 0, len = children.length; i < len; i++)
  108. children[i]._setCachedParent(null);
  109. }
  110. };
  111. p.visit = function(ctx){
  112. if(!this._isBaked){
  113. cc.Node.prototype.visit.call(this, ctx);
  114. return;
  115. }
  116. var context = ctx || cc._renderContext, i;
  117. var _t = this;
  118. var children = _t._children;
  119. var len = children.length;
  120. // quick return if not visible
  121. if (!_t._visible || len === 0)
  122. return;
  123. var locBakeSprite = this._bakeSprite;
  124. context.save();
  125. _t.transform(context);
  126. if(this._cacheDirty){
  127. //compute the bounding box of the bake layer.
  128. var boundingBox = this._getBoundingBoxForBake();
  129. boundingBox.width = 0 | boundingBox.width;
  130. boundingBox.height = 0 | boundingBox.height;
  131. var bakeContext = locBakeSprite.getCacheContext();
  132. locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
  133. bakeContext.translate(0 - boundingBox.x, boundingBox.height + boundingBox.y);
  134. //reset the bake sprite's position
  135. var anchor = locBakeSprite.getAnchorPointInPoints();
  136. locBakeSprite.setPosition(anchor.x + boundingBox.x, anchor.y + boundingBox.y);
  137. //visit for canvas
  138. _t.sortAllChildren();
  139. cc.view._setScaleXYForRenderTexture();
  140. for (i = 0; i < len; i++) {
  141. children[i].visit(bakeContext);
  142. }
  143. cc.view._resetScale();
  144. this._cacheDirty = false;
  145. }
  146. //the bakeSprite is drawing
  147. locBakeSprite.visit(context);
  148. _t.arrivalOrder = 0;
  149. context.restore();
  150. };
  151. p._getBoundingBoxForBake = function () {
  152. var rect = null;
  153. //query child's BoundingBox
  154. if (!this._children || this._children.length === 0)
  155. return cc.rect(0, 0, 10, 10);
  156. var locChildren = this._children;
  157. for (var i = 0; i < locChildren.length; i++) {
  158. var child = locChildren[i];
  159. if (child && child._visible) {
  160. if(rect){
  161. var childRect = child._getBoundingBoxToCurrentNode();
  162. if (childRect)
  163. rect = cc.rectUnion(rect, childRect);
  164. }else{
  165. rect = child._getBoundingBoxToCurrentNode();
  166. }
  167. }
  168. }
  169. return rect;
  170. };
  171. p = null;
  172. }else{
  173. cc.assert(typeof cc._tmp.LayerDefineForWebGL === "function", cc._LogInfos.MissingFile, "CCLayerWebGL.js");
  174. cc._tmp.LayerDefineForWebGL();
  175. delete cc._tmp.LayerDefineForWebGL;
  176. }
  177. /**
  178. * <p>
  179. * CCLayerColor is a subclass of CCLayer that implements the CCRGBAProtocol protocol. <br/>
  180. * All features from CCLayer are valid, plus the following new features: <br/>
  181. * - opacity <br/>
  182. * - RGB colors </p>
  183. * @class
  184. * @extends cc.Layer
  185. *
  186. * @param {cc.Color} [color=] The color of the layer
  187. * @param {Number} [width=] The width of the layer
  188. * @param {Number} [height=] The height of the layer
  189. *
  190. * @example
  191. * // Example
  192. * //Create a yellow color layer as background
  193. * var yellowBackground = new cc.LayerColor(cc.color(255,255,0,255));
  194. * //If you didnt pass in width and height, it defaults to the same size as the canvas
  195. *
  196. * //create a yellow box, 200 by 200 in size
  197. * var yellowBox = new cc.LayerColor(cc.color(255,255,0,255), 200, 200);
  198. */
  199. cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
  200. _blendFunc: null,
  201. _className: "LayerColor",
  202. /**
  203. * Returns the blend function
  204. * @return {cc.BlendFunc}
  205. */
  206. getBlendFunc: function () {
  207. return this._blendFunc;
  208. },
  209. /**
  210. * Changes width and height
  211. * @deprecated since v3.0 please use setContentSize instead
  212. * @see cc.Node#setContentSize
  213. * @param {Number} w width
  214. * @param {Number} h height
  215. */
  216. changeWidthAndHeight: function (w, h) {
  217. this.width = w;
  218. this.height = h;
  219. },
  220. /**
  221. * Changes width in Points
  222. * @deprecated since v3.0 please use setContentSize instead
  223. * @see cc.Node#setContentSize
  224. * @param {Number} w width
  225. */
  226. changeWidth: function (w) {
  227. this.width = w;
  228. },
  229. /**
  230. * change height in Points
  231. * @deprecated since v3.0 please use setContentSize instead
  232. * @see cc.Node#setContentSize
  233. * @param {Number} h height
  234. */
  235. changeHeight: function (h) {
  236. this.height = h;
  237. },
  238. setOpacityModifyRGB: function (value) {
  239. },
  240. isOpacityModifyRGB: function () {
  241. return false;
  242. },
  243. setColor: function (color) {
  244. cc.Layer.prototype.setColor.call(this, color);
  245. this._updateColor();
  246. },
  247. setOpacity: function (opacity) {
  248. cc.Layer.prototype.setOpacity.call(this, opacity);
  249. this._updateColor();
  250. },
  251. _blendFuncStr: "source",
  252. /**
  253. * Constructor of cc.LayerColor
  254. * @function
  255. * @param {cc.Color} [color=]
  256. * @param {Number} [width=]
  257. * @param {Number} [height=]
  258. */
  259. ctor: null,
  260. /**
  261. * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
  262. * @param {cc.Color} [color=]
  263. * @param {Number} [width=]
  264. * @param {Number} [height=]
  265. * @return {Boolean}
  266. */
  267. init: function (color, width, height) {
  268. if (cc._renderType !== cc._RENDER_TYPE_CANVAS)
  269. this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
  270. var winSize = cc.director.getWinSize();
  271. color = color || cc.color(0, 0, 0, 255);
  272. width = width === undefined ? winSize.width : width;
  273. height = height === undefined ? winSize.height : height;
  274. var locDisplayedColor = this._displayedColor;
  275. locDisplayedColor.r = color.r;
  276. locDisplayedColor.g = color.g;
  277. locDisplayedColor.b = color.b;
  278. var locRealColor = this._realColor;
  279. locRealColor.r = color.r;
  280. locRealColor.g = color.g;
  281. locRealColor.b = color.b;
  282. this._displayedOpacity = color.a;
  283. this._realOpacity = color.a;
  284. var proto = cc.LayerColor.prototype;
  285. proto.setContentSize.call(this, width, height);
  286. proto._updateColor.call(this);
  287. return true;
  288. },
  289. /**
  290. * Sets the blend func, you can pass either a cc.BlendFunc object or source and destination value separately
  291. * @param {Number|cc.BlendFunc} src
  292. * @param {Number} [dst]
  293. */
  294. setBlendFunc: function (src, dst) {
  295. var _t = this, locBlendFunc = this._blendFunc;
  296. if (dst === undefined) {
  297. locBlendFunc.src = src.src;
  298. locBlendFunc.dst = src.dst;
  299. } else {
  300. locBlendFunc.src = src;
  301. locBlendFunc.dst = dst;
  302. }
  303. if (cc._renderType === cc._RENDER_TYPE_CANVAS)
  304. _t._blendFuncStr = cc._getCompositeOperationByBlendFunc(locBlendFunc);
  305. },
  306. _setWidth: null,
  307. _setHeight: null,
  308. _updateColor: null,
  309. updateDisplayedColor: function (parentColor) {
  310. cc.Layer.prototype.updateDisplayedColor.call(this, parentColor);
  311. this._updateColor();
  312. },
  313. updateDisplayedOpacity: function (parentOpacity) {
  314. cc.Layer.prototype.updateDisplayedOpacity.call(this, parentOpacity);
  315. this._updateColor();
  316. },
  317. draw: null
  318. });
  319. /**
  320. * Creates a cc.Layer with color, width and height in Points
  321. * @deprecated since v3.0 please use the new construction instead
  322. * @see cc.LayerColor
  323. * @param {cc.Color} color
  324. * @param {Number|Null} [width=]
  325. * @param {Number|Null} [height=]
  326. * @return {cc.LayerColor}
  327. */
  328. cc.LayerColor.create = function (color, width, height) {
  329. return new cc.LayerColor(color, width, height);
  330. };
  331. if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
  332. //cc.LayerColor define start
  333. var _p = cc.LayerColor.prototype;
  334. _p.ctor = function (color, width, height) {
  335. cc.Layer.prototype.ctor.call(this);
  336. this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
  337. cc.LayerColor.prototype.init.call(this, color, width, height);
  338. };
  339. _p._setWidth = cc.Layer.prototype._setWidth;
  340. _p._setHeight = cc.Layer.prototype._setHeight;
  341. _p._updateColor = function () {
  342. };
  343. _p.draw = function (ctx) {
  344. var context = ctx || cc._renderContext, _t = this;
  345. var locEGLViewer = cc.view, locDisplayedColor = _t._displayedColor;
  346. context.fillStyle = "rgba(" + (0 | locDisplayedColor.r) + "," + (0 | locDisplayedColor.g) + ","
  347. + (0 | locDisplayedColor.b) + "," + _t._displayedOpacity / 255 + ")";
  348. context.fillRect(0, 0, _t.width * locEGLViewer.getScaleX(), -_t.height * locEGLViewer.getScaleY());
  349. cc.g_NumberOfDraws++;
  350. };
  351. //for bake
  352. _p.visit = function(ctx){
  353. if(!this._isBaked){
  354. cc.Node.prototype.visit.call(this, ctx);
  355. return;
  356. }
  357. var context = ctx || cc._renderContext, i;
  358. var _t = this;
  359. var children = _t._children;
  360. var len = children.length;
  361. // quick return if not visible
  362. if (!_t._visible)
  363. return;
  364. var locBakeSprite = this._bakeSprite;
  365. context.save();
  366. _t.transform(context);
  367. if(this._cacheDirty){
  368. //compute the bounding box of the bake layer.
  369. var boundingBox = this._getBoundingBoxForBake();
  370. boundingBox.width = 0 | boundingBox.width;
  371. boundingBox.height = 0 | boundingBox.height;
  372. var bakeContext = locBakeSprite.getCacheContext();
  373. locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
  374. var anchor = locBakeSprite.getAnchorPointInPoints(), locPos = this._position;
  375. if(this._ignoreAnchorPointForPosition){
  376. bakeContext.translate(0 - boundingBox.x + locPos.x, boundingBox.height + boundingBox.y - locPos.y);
  377. //reset the bake sprite's position
  378. locBakeSprite.setPosition(anchor.x + boundingBox.x - locPos.x, anchor.y + boundingBox.y - locPos.y);
  379. } else {
  380. var selfAnchor = this.getAnchorPointInPoints();
  381. var selfPos = {x: locPos.x - selfAnchor.x, y: locPos.y - selfAnchor.y};
  382. bakeContext.translate(0 - boundingBox.x + selfPos.x, boundingBox.height + boundingBox.y - selfPos.y);
  383. locBakeSprite.setPosition(anchor.x + boundingBox.x - selfPos.x, anchor.y + boundingBox.y - selfPos.y);
  384. }
  385. var child;
  386. cc.view._setScaleXYForRenderTexture();
  387. //visit for canvas
  388. if (len > 0) {
  389. _t.sortAllChildren();
  390. // draw children zOrder < 0
  391. for (i = 0; i < len; i++) {
  392. child = children[i];
  393. if (child._localZOrder < 0)
  394. child.visit(bakeContext);
  395. else
  396. break;
  397. }
  398. _t.draw(bakeContext);
  399. for (; i < len; i++) {
  400. children[i].visit(bakeContext);
  401. }
  402. } else
  403. _t.draw(bakeContext);
  404. cc.view._resetScale();
  405. this._cacheDirty = false;
  406. }
  407. //the bakeSprite is drawing
  408. locBakeSprite.visit(context);
  409. _t.arrivalOrder = 0;
  410. context.restore();
  411. };
  412. _p._getBoundingBoxForBake = function () {
  413. //default size
  414. var rect = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
  415. var trans = this.nodeToWorldTransform();
  416. rect = cc.rectApplyAffineTransform(rect, this.nodeToWorldTransform());
  417. //query child's BoundingBox
  418. if (!this._children || this._children.length === 0)
  419. return rect;
  420. var locChildren = this._children;
  421. for (var i = 0; i < locChildren.length; i++) {
  422. var child = locChildren[i];
  423. if (child && child._visible) {
  424. var childRect = child._getBoundingBoxToCurrentNode(trans);
  425. rect = cc.rectUnion(rect, childRect);
  426. }
  427. }
  428. return rect;
  429. };
  430. //cc.LayerColor define end
  431. _p = null;
  432. } else {
  433. cc.assert(typeof cc._tmp.WebGLLayerColor === "function", cc._LogInfos.MissingFile, "CCLayerWebGL.js");
  434. cc._tmp.WebGLLayerColor();
  435. delete cc._tmp.WebGLLayerColor;
  436. }
  437. cc.assert(typeof cc._tmp.PrototypeLayerColor === "function", cc._LogInfos.MissingFile, "CCLayerPropertyDefine.js");
  438. cc._tmp.PrototypeLayerColor();
  439. delete cc._tmp.PrototypeLayerColor;
  440. /**
  441. * <p>
  442. * CCLayerGradient is a subclass of cc.LayerColor that draws gradients across the background.<br/>
  443. *<br/>
  444. * All features from cc.LayerColor are valid, plus the following new features:<br/>
  445. * <ul><li>direction</li>
  446. * <li>final color</li>
  447. * <li>interpolation mode</li></ul>
  448. * <br/>
  449. * Color is interpolated between the startColor and endColor along the given<br/>
  450. * vector (starting at the origin, ending at the terminus). If no vector is<br/>
  451. * supplied, it defaults to (0, -1) -- a fade from top to bottom.<br/>
  452. * <br/>
  453. * If 'compressedInterpolation' is disabled, you will not see either the start or end color for<br/>
  454. * non-cardinal vectors; a smooth gradient implying both end points will be still<br/>
  455. * be drawn, however.<br/>
  456. *<br/>
  457. * If 'compressedInterpolation' is enabled (default mode) you will see both the start and end colors of the gradient.
  458. * </p>
  459. * @class
  460. * @extends cc.LayerColor
  461. *
  462. * @param {cc.Color} start Starting color
  463. * @param {cc.Color} end Ending color
  464. * @param {cc.Point} [v=cc.p(0, -1)] A vector defines the gradient direction, default direction is from top to bottom
  465. *
  466. * @property {cc.Color} startColor - Start color of the color gradient
  467. * @property {cc.Color} endColor - End color of the color gradient
  468. * @property {Number} startOpacity - Start opacity of the color gradient
  469. * @property {Number} endOpacity - End opacity of the color gradient
  470. * @property {Number} vector - Direction vector of the color gradient
  471. * @property {Number} compresseInterpolation - Indicate whether or not the interpolation will be compressed
  472. */
  473. cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
  474. _startColor: null,
  475. _endColor: null,
  476. _startOpacity: 255,
  477. _endOpacity: 255,
  478. _alongVector: null,
  479. _compressedInterpolation: false,
  480. _gradientStartPoint: null,
  481. _gradientEndPoint: null,
  482. _className: "LayerGradient",
  483. /**
  484. * Constructor of cc.LayerGradient
  485. * @param {cc.Color} start
  486. * @param {cc.Color} end
  487. * @param {cc.Point} [v=cc.p(0, -1)]
  488. */
  489. ctor: function (start, end, v) {
  490. var _t = this;
  491. cc.LayerColor.prototype.ctor.call(_t);
  492. _t._startColor = cc.color(0, 0, 0, 255);
  493. _t._endColor = cc.color(0, 0, 0, 255);
  494. _t._alongVector = cc.p(0, -1);
  495. _t._startOpacity = 255;
  496. _t._endOpacity = 255;
  497. _t._gradientStartPoint = cc.p(0, 0);
  498. _t._gradientEndPoint = cc.p(0, 0);
  499. cc.LayerGradient.prototype.init.call(_t, start, end, v);
  500. },
  501. /**
  502. * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
  503. * @param {cc.Color} start starting color
  504. * @param {cc.Color} end
  505. * @param {cc.Point|Null} v
  506. * @return {Boolean}
  507. */
  508. init: function (start, end, v) {
  509. start = start || cc.color(0, 0, 0, 255);
  510. end = end || cc.color(0, 0, 0, 255);
  511. v = v || cc.p(0, -1);
  512. var _t = this;
  513. // Initializes the CCLayer with a gradient between start and end in the direction of v.
  514. var locStartColor = _t._startColor, locEndColor = _t._endColor;
  515. locStartColor.r = start.r;
  516. locStartColor.g = start.g;
  517. locStartColor.b = start.b;
  518. _t._startOpacity = start.a;
  519. locEndColor.r = end.r;
  520. locEndColor.g = end.g;
  521. locEndColor.b = end.b;
  522. _t._endOpacity = end.a;
  523. _t._alongVector = v;
  524. _t._compressedInterpolation = true;
  525. _t._gradientStartPoint = cc.p(0, 0);
  526. _t._gradientEndPoint = cc.p(0, 0);
  527. cc.LayerColor.prototype.init.call(_t, cc.color(start.r, start.g, start.b, 255));
  528. cc.LayerGradient.prototype._updateColor.call(_t);
  529. return true;
  530. },
  531. /**
  532. * Sets the untransformed size of the LayerGradient.
  533. * @param {cc.Size|Number} size The untransformed size of the LayerGradient or The untransformed size's width of the LayerGradient.
  534. * @param {Number} [height] The untransformed size's height of the LayerGradient.
  535. */
  536. setContentSize: function (size, height) {
  537. cc.LayerColor.prototype.setContentSize.call(this, size, height);
  538. this._updateColor();
  539. },
  540. _setWidth: function (width) {
  541. cc.LayerColor.prototype._setWidth.call(this, width);
  542. this._updateColor();
  543. },
  544. _setHeight: function (height) {
  545. cc.LayerColor.prototype._setHeight.call(this, height);
  546. this._updateColor();
  547. },
  548. /**
  549. * Returns the starting color
  550. * @return {cc.Color}
  551. */
  552. getStartColor: function () {
  553. return this._realColor;
  554. },
  555. /**
  556. * Sets the starting color
  557. * @param {cc.Color} color
  558. * @example
  559. * // Example
  560. * myGradientLayer.setStartColor(cc.color(255,0,0));
  561. * //set the starting gradient to red
  562. */
  563. setStartColor: function (color) {
  564. this.color = color;
  565. },
  566. /**
  567. * Sets the end gradient color
  568. * @param {cc.Color} color
  569. * @example
  570. * // Example
  571. * myGradientLayer.setEndColor(cc.color(255,0,0));
  572. * //set the ending gradient to red
  573. */
  574. setEndColor: function (color) {
  575. this._endColor = color;
  576. this._updateColor();
  577. },
  578. /**
  579. * Returns the end color
  580. * @return {cc.Color}
  581. */
  582. getEndColor: function () {
  583. return this._endColor;
  584. },
  585. /**
  586. * Sets starting gradient opacity
  587. * @param {Number} o from 0 to 255, 0 is transparent
  588. */
  589. setStartOpacity: function (o) {
  590. this._startOpacity = o;
  591. this._updateColor();
  592. },
  593. /**
  594. * Returns the starting gradient opacity
  595. * @return {Number}
  596. */
  597. getStartOpacity: function () {
  598. return this._startOpacity;
  599. },
  600. /**
  601. * Sets the end gradient opacity
  602. * @param {Number} o
  603. */
  604. setEndOpacity: function (o) {
  605. this._endOpacity = o;
  606. this._updateColor();
  607. },
  608. /**
  609. * Returns the end gradient opacity
  610. * @return {Number}
  611. */
  612. getEndOpacity: function () {
  613. return this._endOpacity;
  614. },
  615. /**
  616. * Sets the direction vector of the gradient
  617. * @param {cc.Point} Var
  618. */
  619. setVector: function (Var) {
  620. this._alongVector.x = Var.x;
  621. this._alongVector.y = Var.y;
  622. this._updateColor();
  623. },
  624. /**
  625. * Returns the direction vector of the gradient
  626. * @return {cc.Point}
  627. */
  628. getVector: function () {
  629. return cc.p(this._alongVector.x, this._alongVector.y);
  630. },
  631. /**
  632. * Returns whether compressed interpolation is enabled
  633. * @return {Boolean}
  634. */
  635. isCompressedInterpolation: function () {
  636. return this._compressedInterpolation;
  637. },
  638. /**
  639. * Sets whether compressed interpolation is enabled
  640. * @param {Boolean} compress
  641. */
  642. setCompressedInterpolation: function (compress) {
  643. this._compressedInterpolation = compress;
  644. this._updateColor();
  645. },
  646. _draw: null,
  647. _updateColor: null
  648. });
  649. /**
  650. * Creates a gradient layer
  651. * @deprecated since v3.0, please use the new construction instead
  652. * @see cc.layerGradient
  653. * @param {cc.Color} start starting color
  654. * @param {cc.Color} end ending color
  655. * @param {cc.Point|Null} v
  656. * @return {cc.LayerGradient}
  657. */
  658. cc.LayerGradient.create = function (start, end, v) {
  659. return new cc.LayerGradient(start, end, v);
  660. };
  661. if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
  662. //cc.LayerGradient define start
  663. var _p = cc.LayerGradient.prototype;
  664. _p.draw = function (ctx) {
  665. var context = ctx || cc._renderContext, _t = this;
  666. if (_t._blendFuncStr != "source")
  667. context.globalCompositeOperation = _t._blendFuncStr;
  668. context.save();
  669. var opacityf = _t._displayedOpacity / 255.0;
  670. var scaleX = cc.view.getScaleX(), scaleY = cc.view.getScaleY();
  671. var tWidth = _t.width * scaleX, tHeight = _t.height * scaleY;
  672. var tGradient = context.createLinearGradient(_t._gradientStartPoint.x * scaleX, _t._gradientStartPoint.y * scaleY,
  673. _t._gradientEndPoint.x * scaleX, _t._gradientEndPoint.y * scaleY);
  674. var locDisplayedColor = _t._displayedColor, locEndColor = _t._endColor;
  675. tGradient.addColorStop(0, "rgba(" + Math.round(locDisplayedColor.r) + "," + Math.round(locDisplayedColor.g) + ","
  676. + Math.round(locDisplayedColor.b) + "," + (opacityf * (_t._startOpacity / 255)).toFixed(4) + ")");
  677. tGradient.addColorStop(1, "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + ","
  678. + Math.round(locEndColor.b) + "," + (opacityf * (_t._endOpacity / 255)).toFixed(4) + ")");
  679. context.fillStyle = tGradient;
  680. context.fillRect(0, 0, tWidth, -tHeight);
  681. if (_t._rotation != 0)
  682. context.rotate(_t._rotationRadians);
  683. context.restore();
  684. cc.g_NumberOfDraws++;
  685. };
  686. _p._updateColor = function () {
  687. var _t = this;
  688. var locAlongVector = _t._alongVector, tWidth = _t.width * 0.5, tHeight = _t.height * 0.5;
  689. _t._gradientStartPoint.x = tWidth * (-locAlongVector.x) + tWidth;
  690. _t._gradientStartPoint.y = tHeight * locAlongVector.y - tHeight;
  691. _t._gradientEndPoint.x = tWidth * locAlongVector.x + tWidth;
  692. _t._gradientEndPoint.y = tHeight * (-locAlongVector.y) - tHeight;
  693. };
  694. //cc.LayerGradient define end
  695. _p = null;
  696. } else {
  697. cc.assert(typeof cc._tmp.WebGLLayerGradient === "function", cc._LogInfos.MissingFile, "CCLayerWebGL.js");
  698. cc._tmp.WebGLLayerGradient();
  699. delete cc._tmp.WebGLLayerGradient;
  700. }
  701. cc.assert(typeof cc._tmp.PrototypeLayerGradient === "function", cc._LogInfos.MissingFile, "CCLayerPropertyDefine.js");
  702. cc._tmp.PrototypeLayerGradient();
  703. delete cc._tmp.PrototypeLayerGradient;
  704. /**
  705. * CCMultipleLayer is a CCLayer with the ability to multiplex it's children.<br/>
  706. * Features:<br/>
  707. * <ul><li>- It supports one or more children</li>
  708. * <li>- Only one children will be active a time</li></ul>
  709. * @class
  710. * @extends cc.Layer
  711. * @param {Array} layers an array of cc.Layer
  712. * @example
  713. * // Example
  714. * var multiLayer = new cc.LayerMultiple(layer1, layer2, layer3);//any number of layers
  715. */
  716. cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{
  717. _enabledLayer: 0,
  718. _layers: null,
  719. _className: "LayerMultiplex",
  720. /**
  721. * Constructor of cc.LayerMultiplex
  722. * @param {Array} layers an array of cc.Layer
  723. */
  724. ctor: function (layers) {
  725. cc.Layer.prototype.ctor.call(this);
  726. if (layers instanceof Array)
  727. cc.LayerMultiplex.prototype.initWithLayers.call(this, layers);
  728. else
  729. cc.LayerMultiplex.prototype.initWithLayers.call(this, Array.prototype.slice.call(arguments));
  730. },
  731. /**
  732. * Initialization of the layer multiplex, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer multiplex
  733. * @param {Array} layers an array of cc.Layer
  734. * @return {Boolean}
  735. */
  736. initWithLayers: function (layers) {
  737. if ((layers.length > 0) && (layers[layers.length - 1] == null))
  738. cc.log(cc._LogInfos.LayerMultiplex_initWithLayers);
  739. this._layers = layers;
  740. this._enabledLayer = 0;
  741. this.addChild(this._layers[this._enabledLayer]);
  742. return true;
  743. },
  744. /**
  745. * Switches to a certain layer indexed by n.<br/>
  746. * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
  747. * @param {Number} n the layer index to switch to
  748. */
  749. switchTo: function (n) {
  750. if (n >= this._layers.length) {
  751. cc.log(cc._LogInfos.LayerMultiplex_switchTo);
  752. return;
  753. }
  754. this.removeChild(this._layers[this._enabledLayer], true);
  755. this._enabledLayer = n;
  756. this.addChild(this._layers[n]);
  757. },
  758. /**
  759. * Release the current layer and switches to another layer indexed by n.<br/>
  760. * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
  761. * @param {Number} n the layer index to switch to
  762. */
  763. switchToAndReleaseMe: function (n) {
  764. if (n >= this._layers.length) {
  765. cc.log(cc._LogInfos.LayerMultiplex_switchToAndReleaseMe);
  766. return;
  767. }
  768. this.removeChild(this._layers[this._enabledLayer], true);
  769. //[layers replaceObjectAtIndex:_enabledLayer withObject:[NSNull null]];
  770. this._layers[this._enabledLayer] = null;
  771. this._enabledLayer = n;
  772. this.addChild(this._layers[n]);
  773. },
  774. /**
  775. * Add a layer to the multiplex layers list
  776. * @param {cc.Layer} layer
  777. */
  778. addLayer: function (layer) {
  779. if (!layer) {
  780. cc.log(cc._LogInfos.LayerMultiplex_addLayer);
  781. return;
  782. }
  783. this._layers.push(layer);
  784. }
  785. });
  786. /**
  787. * Creates a cc.LayerMultiplex with one or more layers using a variable argument list.
  788. * @deprecated since v3.0, please use new construction instead
  789. * @see cc.LayerMultiplex
  790. * @return {cc.LayerMultiplex|Null}
  791. */
  792. cc.LayerMultiplex.create = function (/*Multiple Arguments*/) {
  793. return new cc.LayerMultiplex(Array.prototype.slice.call(arguments));
  794. };