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 /** cc.Layer is a subclass of cc.Node that implements the TouchEventsDelegate protocol.<br/> 28 * All features from cc.Node are valid, plus the following new features:<br/> 29 * It can receive iPhone Touches<br/> 30 * It can receive Accelerometer input 31 * @class 32 * @extends cc.Node 33 */ 34 cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{ 35 /** 36 * init layer 37 * @return {Boolean} 38 */ 39 _className: "Layer", 40 41 /** 42 * Constructor of cc.Layer 43 */ 44 ctor: function () { 45 var nodep = cc.Node.prototype; 46 nodep.ctor.call(this); 47 this._ignoreAnchorPointForPosition = true; 48 nodep.setAnchorPoint.call(this, 0.5, 0.5); 49 nodep.setContentSize.call(this, cc.winSize); 50 } 51 }); 52 53 /** 54 * creates a layer 55 * @example 56 * // Example 57 * var myLayer = cc.Layer.create(); 58 * //Yes! it's that simple 59 * @return {cc.Layer|Null} 60 */ 61 cc.Layer.create = function () { 62 var ret = new cc.Layer(); 63 return ret; 64 65 }; 66 67 /** 68 * <p> 69 * CCLayerRGBA is a subclass of CCLayer that implements the CCRGBAProtocol protocol using a solid color as the background. <br/> 70 * All features from CCLayer are valid, plus the following new features that propagate into children that conform to the CCRGBAProtocol: <br/> 71 * - opacity <br/> 72 * - RGB colors 73 * </p> 74 * @class 75 * @extends cc.Layer 76 * 77 * @property {Number} opacity - Opacity of layer 78 * @property {Boolean} opacityModifyRGB - Indicate whether or not the opacity modify color 79 * @property {Boolean} cascadeOpacity - Indicate whether or not it will set cascade opacity 80 * @property {cc.Color} color - Color of layer 81 * @property {Boolean} cascadeColor - Indicate whether or not it will set cascade color 82 */ 83 cc.LayerRGBA = cc.Layer.extend(/** @lends cc.LayerRGBA# */{ 84 RGBAProtocol: true, 85 _displayedOpacity: 255, 86 _realOpacity: 255, 87 _displayedColor: null, 88 _realColor: null, 89 _cascadeOpacityEnabled: false, 90 _cascadeColorEnabled: false, 91 _className: "LayerRGBA", 92 93 /** 94 * Constructor of cc.LayerRGBA 95 */ 96 ctor: function () { 97 cc.Layer.prototype.ctor.call(this); 98 this._displayedColor = cc.color(255, 255, 255, 255); 99 this._realColor = cc.color(255, 255, 255, 255); 100 }, 101 102 init: function () { 103 var nodep = cc.Layer.prototype, _t = this; 104 _t._ignoreAnchorPointForPosition = true; 105 nodep.setAnchorPoint.call(_t, 0.5, 0.5); 106 nodep.setContentSize.call(_t, cc.winSize); 107 _t.cascadeOpacity = false; 108 _t.cascadeColor = false; 109 return true; 110 }, 111 112 /** 113 * Get the opacity of Layer 114 * @returns {number} opacity 115 */ 116 getOpacity: function () { 117 return this._realOpacity; 118 }, 119 120 /** 121 * Get the displayed opacity of Layer 122 * @returns {number} displayed opacity 123 */ 124 getDisplayedOpacity: function () { 125 return this._displayedOpacity; 126 }, 127 128 /** 129 * Override synthesized setOpacity to recurse items 130 * @param {Number} opacity 131 */ 132 setOpacity: function (opacity) { 133 var _t = this; 134 _t._displayedOpacity = _t._realOpacity = opacity; 135 136 var parentOpacity = 255, locParent = _t._parent; 137 if (locParent && locParent.RGBAProtocol && locParent.cascadeOpacity) 138 parentOpacity = locParent.getDisplayedOpacity(); 139 _t.updateDisplayedOpacity(parentOpacity); 140 141 _t._displayedColor.a = _t._realColor.a = opacity; 142 }, 143 144 /** 145 * Update displayed opacity of Layer 146 * @param {Number} parentOpacity 147 */ 148 updateDisplayedOpacity: function (parentOpacity) { 149 var _t = this; 150 _t._displayedOpacity = 0 | (_t._realOpacity * parentOpacity / 255.0); 151 152 if (_t._cascadeOpacityEnabled) { 153 var locChildren = _t._children, selItem; 154 for (var i = 0; i < locChildren.length; i++) { 155 selItem = locChildren[i]; 156 if (selItem && selItem.RGBAProtocol) 157 selItem.updateDisplayedOpacity(_t._displayedOpacity); 158 } 159 } 160 }, 161 162 /** 163 * whether or not it will set cascade opacity. 164 * @returns {boolean} 165 */ 166 isCascadeOpacityEnabled: function () { 167 return this._cascadeOpacityEnabled; 168 }, 169 170 /** 171 * Enable or disable cascade opacity 172 * @param {boolean} cascadeOpacityEnabled 173 */ 174 setCascadeOpacityEnabled: function (cascadeOpacityEnabled) { 175 if (this._cascadeOpacityEnabled === cascadeOpacityEnabled) 176 return; 177 178 this._cascadeOpacityEnabled = cascadeOpacityEnabled; 179 if (cascadeOpacityEnabled) 180 this._enableCascadeOpacity(); 181 else 182 this._disableCascadeOpacity(); 183 }, 184 185 _enableCascadeOpacity: function () { 186 var parentOpacity = 255, locParent = this._parent; 187 if (locParent && locParent.RGBAProtocol && locParent.cascadeOpacity) 188 parentOpacity = locParent.getDisplayedOpacity(); 189 this.updateDisplayedOpacity(parentOpacity); 190 }, 191 192 _disableCascadeOpacity: function () { 193 this._displayedOpacity = this._realOpacity; 194 var selChildren = this._children, item; 195 for (var i = 0; i < selChildren.length; i++) { 196 item = selChildren[i]; 197 if (item && item.RGBAProtocol) 198 item.updateDisplayedOpacity(255); 199 } 200 }, 201 202 /** 203 * Get the color of Layer 204 * @returns {cc.Color} 205 */ 206 getColor: function () { 207 var locRealColor = this._realColor; 208 return cc.color(locRealColor.r, locRealColor.g, locRealColor.b, locRealColor.a); 209 }, 210 211 /** 212 * Get the displayed color of Layer 213 * @returns {cc.Color} 214 */ 215 getDisplayedColor: function () { 216 var locDisplayedColor = this._displayedColor; 217 return cc.color(locDisplayedColor.r, locDisplayedColor.g, locDisplayedColor.b); 218 }, 219 220 /** 221 * Set the color of Layer 222 * @param {cc.Color} color 223 */ 224 setColor: function (color) { 225 var locDisplayed = this._displayedColor, locRealColor = this._realColor; 226 locDisplayed.r = locRealColor.r = color.r; 227 locDisplayed.g = locRealColor.g = color.g; 228 locDisplayed.b = locRealColor.b = color.b; 229 230 var parentColor, locParent = this._parent; 231 if (locParent && locParent.RGBAProtocol && locParent.cascadeColor) 232 parentColor = locParent.getDisplayedColor(); 233 else 234 parentColor = cc.color.WHITE; 235 this.updateDisplayedColor(parentColor); 236 237 if (color.a !== undefined && !color.a_undefined) { 238 this.setOpacity(color.a); 239 } 240 }, 241 242 /** 243 * update the displayed color of Node 244 * @param {cc.Color} parentColor 245 */ 246 updateDisplayedColor: function (parentColor) { 247 var locDisplayedColor = this._displayedColor, locRealColor = this._realColor; 248 locDisplayedColor.r = 0 | (locRealColor.r * parentColor.r / 255.0); 249 locDisplayedColor.g = 0 | (locRealColor.g * parentColor.g / 255.0); 250 locDisplayedColor.b = 0 | (locRealColor.b * parentColor.b / 255.0); 251 252 if (this._cascadeColorEnabled) { 253 var locChildren = this._children, selItem; 254 for (var i = 0; i < locChildren.length; i++) { 255 selItem = locChildren[i]; 256 if (selItem && selItem.RGBAProtocol) 257 selItem.updateDisplayedColor(locDisplayedColor); 258 } 259 } 260 }, 261 262 /** 263 * whether or not it will set cascade color. 264 * @returns {boolean} 265 */ 266 isCascadeColorEnabled: function () { 267 return this._cascadeColorEnabled; 268 }, 269 270 /** 271 * Enable or disable cascade color 272 * @param {boolean} cascadeColorEnabled 273 */ 274 setCascadeColorEnabled: function (cascadeColorEnabled) { 275 if (this._cascadeColorEnabled === cascadeColorEnabled) 276 return; 277 this._cascadeColorEnabled = cascadeColorEnabled; 278 if (this._cascadeColorEnabled) 279 this._enableCascadeColor(); 280 else 281 this._disableCascadeColor(); 282 }, 283 284 _enableCascadeColor: function () { 285 var parentColor , locParent = this._parent; 286 if (locParent && locParent.RGBAProtocol && locParent.cascadeColor) 287 parentColor = locParent.getDisplayedColor(); 288 else 289 parentColor = cc.color.WHITE; 290 this.updateDisplayedColor(parentColor); 291 }, 292 293 _disableCascadeColor: function () { 294 var locDisplayedColor = this._displayedColor, locRealColor = this._realColor; 295 locDisplayedColor.r = locRealColor.r; 296 locDisplayedColor.g = locRealColor.g; 297 locDisplayedColor.b = locRealColor.b; 298 299 var selChildren = this._children, whiteColor = cc.color.WHITE, item, i; 300 for (i = 0; i < selChildren.length; i++) { 301 item = selChildren[i]; 302 if (item && item.RGBAProtocol) 303 item.updateDisplayedColor(whiteColor); 304 } 305 }, 306 307 /** 308 * add a child to layer 309 * @overried 310 * @param {cc.Node} child A child node 311 * @param {Number} [zOrder=] Z order for drawing priority. Please refer to setLocalZOrder(int) 312 * @param {Number} [tag=] A integer to identify the node easily. Please refer to setTag(int) 313 */ 314 addChild: function (child, zOrder, tag) { 315 cc.Node.prototype.addChild.call(this, child, zOrder, tag); 316 317 if (this._cascadeColorEnabled) 318 this._enableCascadeColor(); 319 if (this._cascadeOpacityEnabled) 320 this._enableCascadeOpacity(); 321 }, 322 323 setOpacityModifyRGB: function (bValue) { 324 }, 325 326 isOpacityModifyRGB: function () { 327 return false; 328 } 329 }); 330 331 cc.assert(typeof cc._tmp.PrototypeLayerRGBA === "function", cc._LogInfos.MissingFile, "CCLayerPropertyDefine.js"); 332 cc._tmp.PrototypeLayerRGBA(); 333 delete cc._tmp.PrototypeLayerRGBA; 334 335 /** 336 * <p> 337 * CCLayerColor is a subclass of CCLayer that implements the CCRGBAProtocol protocol. <br/> 338 * All features from CCLayer are valid, plus the following new features: <br/> 339 * <ul><li>opacity</li> <br/> 340 * <li>RGB colors</li></ul> <br/> 341 * </p> 342 * @class 343 * @extends cc.LayerRGBA 344 */ 345 cc.LayerColor = cc.LayerRGBA.extend(/** @lends cc.LayerColor# */{ 346 _blendFunc: null, 347 _className: "LayerColor", 348 349 /** 350 * blendFunc getter 351 * @return {cc.BlendFunc} 352 */ 353 getBlendFunc: function () { 354 return this._blendFunc; 355 }, 356 357 /** 358 * change width and height in Points 359 * @deprecated 360 * @param {Number} w width 361 * @param {Number} h height 362 */ 363 changeWidthAndHeight: function (w, h) { 364 this.width = w; 365 this.height = h; 366 }, 367 368 /** 369 * change width in Points 370 * @deprecated 371 * @param {Number} w width 372 */ 373 changeWidth: function (w) { 374 this.width = w; 375 }, 376 377 /** 378 * change height in Points 379 * @deprecated 380 * @param {Number} h height 381 */ 382 changeHeight: function (h) { 383 this.height = h; 384 }, 385 386 /** 387 * set OpacityModifyRGB of cc.LayerColor 388 * @param {Boolean} value 389 */ 390 setOpacityModifyRGB: function (value) { 391 }, 392 393 /** 394 * is OpacityModifyRGB 395 * @return {Boolean} 396 */ 397 isOpacityModifyRGB: function () { 398 return false; 399 }, 400 401 setColor: function (color) { 402 cc.LayerRGBA.prototype.setColor.call(this, color); 403 this._updateColor(); 404 }, 405 406 setOpacity: function (opacity) { 407 cc.LayerRGBA.prototype.setOpacity.call(this, opacity); 408 this._updateColor(); 409 }, 410 411 _isLighterMode: false, 412 /** 413 * Constructor of cc.LayerColor 414 * @function 415 * @param {cc.Color} [color=] 416 * @param {Number} [width=] 417 * @param {Number} [height=] 418 */ 419 ctor: null, 420 421 /** 422 * @param {cc.Color} [color=] 423 * @param {Number} [width=] 424 * @param {Number} [height=] 425 * @return {Boolean} 426 */ 427 init: function (color, width, height) { 428 if (cc._renderType !== cc._RENDER_TYPE_CANVAS) 429 this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR); 430 431 var winSize = cc.director.getWinSize(); 432 color = color || cc.color(0, 0, 0, 255); 433 width = width === undefined ? winSize.width : width; 434 height = height === undefined ? winSize.height : height; 435 436 var locDisplayedColor = this._displayedColor; 437 locDisplayedColor.r = color.r; 438 locDisplayedColor.g = color.g; 439 locDisplayedColor.b = color.b; 440 441 var locRealColor = this._realColor; 442 locRealColor.r = color.r; 443 locRealColor.g = color.g; 444 locRealColor.b = color.b; 445 446 this._displayedOpacity = color.a; 447 this._realOpacity = color.a; 448 449 var proto = cc.LayerColor.prototype; 450 proto.setContentSize.call(this, width, height); 451 proto._updateColor.call(this); 452 return true; 453 }, 454 455 /** 456 * blendFunc setter 457 * @param {Number} src 458 * @param {Number} dst 459 */ 460 setBlendFunc: function (src, dst) { 461 var _t = this; 462 if (dst === undefined) 463 _t._blendFunc = src; 464 else 465 _t._blendFunc = {src: src, dst: dst}; 466 if (cc._renderType === cc._RENDER_TYPE_CANVAS) 467 _t._isLighterMode = (_t._blendFunc && (_t._blendFunc.src == 1) && (_t._blendFunc.dst == 771)); 468 }, 469 470 _setWidth: null, 471 472 _setHeight: null, 473 474 _updateColor: null, 475 476 updateDisplayedColor: function (parentColor) { 477 cc.LayerRGBA.prototype.updateDisplayedColor.call(this, parentColor); 478 this._updateColor(); 479 }, 480 481 updateDisplayedOpacity: function (parentOpacity) { 482 cc.LayerRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity); 483 this._updateColor(); 484 }, 485 486 /** 487 * Renders the layer 488 * @function 489 * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx 490 */ 491 draw: null 492 }); 493 494 /** 495 * creates a cc.Layer with color, width and height in Points 496 * @param {cc.Color} color 497 * @param {Number|Null} [width=] 498 * @param {Number|Null} [height=] 499 * @return {cc.LayerColor} 500 * @example 501 * // Example 502 * //Create a yellow color layer as background 503 * var yellowBackground = cc.LayerColor.create(cc.color(255,255,0,255)); 504 * //If you didnt pass in width and height, it defaults to the same size as the canvas 505 * 506 * //create a yellow box, 200 by 200 in size 507 * var yellowBox = cc.LayerColor.create(cc.color(255,255,0,255), 200, 200); 508 */ 509 cc.LayerColor.create = function (color, width, height) { 510 return new cc.LayerColor(color, width, height); 511 }; 512 513 514 if (cc._renderType === cc._RENDER_TYPE_CANVAS) { 515 //cc.LayerColor define start 516 var _p = cc.LayerColor.prototype; 517 _p.ctor = function (color, width, height) { 518 cc.LayerRGBA.prototype.ctor.call(this); 519 this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST); 520 cc.LayerColor.prototype.init.call(this, color, width, height); 521 } 522 _p._setWidth = cc.LayerRGBA.prototype._setWidth; 523 _p._setHeight = cc.LayerRGBA.prototype._setHeight; 524 _p._updateColor = function () { 525 }; 526 _p.draw = function (ctx) { 527 var context = ctx || cc._renderContext, _t = this; 528 var locEGLViewer = cc.view, locDisplayedColor = _t._displayedColor; 529 530 context.fillStyle = "rgba(" + (0 | locDisplayedColor.r) + "," + (0 | locDisplayedColor.g) + "," 531 + (0 | locDisplayedColor.b) + "," + _t._displayedOpacity / 255 + ")"; 532 context.fillRect(0, 0, _t.width * locEGLViewer.getScaleX(), -_t.height * locEGLViewer.getScaleY()); 533 cc.g_NumberOfDraws++; 534 }; 535 //cc.LayerGradient define end 536 _p = null; 537 } else { 538 cc.assert(typeof cc._tmp.WebGLLayerColor === "function", cc._LogInfos.MissingFile, "CCLayerWebGL.js"); 539 cc._tmp.WebGLLayerColor(); 540 delete cc._tmp.WebGLLayerColor; 541 } 542 543 cc.assert(typeof cc._tmp.PrototypeLayerColor === "function", cc._LogInfos.MissingFile, "CCLayerPropertyDefine.js"); 544 cc._tmp.PrototypeLayerColor(); 545 delete cc._tmp.PrototypeLayerColor; 546 547 /** 548 * <p> 549 * CCLayerGradient is a subclass of cc.LayerColor that draws gradients across the background.<br/> 550 *<br/> 551 * All features from cc.LayerColor are valid, plus the following new features:<br/> 552 * <ul><li>direction</li> 553 * <li>final color</li> 554 * <li>interpolation mode</li></ul> 555 * <br/> 556 * Color is interpolated between the startColor and endColor along the given<br/> 557 * vector (starting at the origin, ending at the terminus). If no vector is<br/> 558 * supplied, it defaults to (0, -1) -- a fade from top to bottom.<br/> 559 * <br/> 560 * If 'compressedInterpolation' is disabled, you will not see either the start or end color for<br/> 561 * non-cardinal vectors; a smooth gradient implying both end points will be still<br/> 562 * be drawn, however.<br/> 563 *<br/> 564 * If 'compressedInterpolation' is enabled (default mode) you will see both the start and end colors of the gradient. 565 * </p> 566 * @class 567 * @extends cc.LayerColor 568 * 569 * @property {cc.Color} startColor - Start color of the color gradient 570 * @property {cc.Color} endColor - End color of the color gradient 571 * @property {Number} startOpacity - Start opacity of the color gradient 572 * @property {Number} endOpacity - End opacity of the color gradient 573 * @property {Number} vector - Direction vector of the color gradient 574 * @property {Number} compresseInterpolation - Indicate whether or not the interpolation will be compressed 575 */ 576 cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{ 577 _startColor: null, 578 _endColor: null, 579 _startOpacity: 255, 580 _endOpacity: 255, 581 _alongVector: null, 582 _compressedInterpolation: false, 583 _gradientStartPoint: null, 584 _gradientEndPoint: null, 585 _className: "LayerGradient", 586 587 /** 588 * Constructor of cc.LayerGradient 589 * @param {cc.Color} start starting color 590 * @param {cc.Color} end 591 * @param {cc.Point|Null} v 592 */ 593 ctor: function (start, end, v) { 594 var _t = this; 595 cc.LayerColor.prototype.ctor.call(_t); 596 597 _t._startColor = cc.color(0, 0, 0, 255); 598 _t._endColor = cc.color(0, 0, 0, 255); 599 _t._alongVector = cc.p(0, -1); 600 _t._startOpacity = 255; 601 _t._endOpacity = 255; 602 _t._gradientStartPoint = cc.p(0, 0); 603 _t._gradientEndPoint = cc.p(0, 0); 604 cc.LayerGradient.prototype.init.call(_t, start, end, v); 605 }, 606 607 /** 608 * @param {cc.Color} start starting color 609 * @param {cc.Color} end 610 * @param {cc.Point|Null} v 611 * @return {Boolean} 612 */ 613 init: function (start, end, v) { 614 start = start || cc.color(0, 0, 0, 255); 615 end = end || cc.color(0, 0, 0, 255); 616 v = v || cc.p(0, -1); 617 var _t = this; 618 619 // Initializes the CCLayer with a gradient between start and end in the direction of v. 620 var locStartColor = _t._startColor, locEndColor = _t._endColor; 621 locStartColor.r = start.r; 622 locStartColor.g = start.g; 623 locStartColor.b = start.b; 624 _t._startOpacity = start.a; 625 626 locEndColor.r = end.r; 627 locEndColor.g = end.g; 628 locEndColor.b = end.b; 629 _t._endOpacity = end.a; 630 631 _t._alongVector = v; 632 _t._compressedInterpolation = true; 633 _t._gradientStartPoint = cc.p(0, 0); 634 _t._gradientEndPoint = cc.p(0, 0); 635 636 cc.LayerColor.prototype.init.call(_t, cc.color(start.r, start.g, start.b, 255)); 637 cc.LayerGradient.prototype._updateColor.call(_t); 638 return true; 639 }, 640 641 /** 642 * Sets the untransformed size of the LayerGradient. 643 * @override 644 * @param {cc.Size|Number} size The untransformed size of the LayerGradient or The untransformed size's width of the LayerGradient. 645 * @param {Number} [height] The untransformed size's height of the LayerGradient. 646 */ 647 setContentSize: function (size, height) { 648 cc.LayerColor.prototype.setContentSize.call(this, size, height); 649 this._updateColor(); 650 }, 651 652 _setWidth: function (width) { 653 cc.LayerColor.prototype._setWidth.call(this, width); 654 this._updateColor(); 655 }, 656 _setHeight: function (height) { 657 cc.LayerColor.prototype._setHeight.call(this, height); 658 this._updateColor(); 659 }, 660 661 /** 662 * get the starting color 663 * @return {cc.Color} 664 */ 665 getStartColor: function () { 666 return this._realColor; 667 }, 668 669 /** 670 * set the starting color 671 * @param {cc.Color} color 672 * @example 673 * // Example 674 * myGradientLayer.setStartColor(cc.color(255,0,0)); 675 * //set the starting gradient to red 676 */ 677 setStartColor: function (color) { 678 this.color = color; 679 }, 680 681 /** 682 * set the end gradient color 683 * @param {cc.Color} color 684 * @example 685 * // Example 686 * myGradientLayer.setEndColor(cc.color(255,0,0)); 687 * //set the ending gradient to red 688 */ 689 setEndColor: function (color) { 690 this._endColor = color; 691 this._updateColor(); 692 }, 693 694 /** 695 * get the end color 696 * @return {cc.Color} 697 */ 698 getEndColor: function () { 699 return this._endColor; 700 }, 701 702 /** 703 * set starting gradient opacity 704 * @param {Number} o from 0 to 255, 0 is transparent 705 */ 706 setStartOpacity: function (o) { 707 this._startOpacity = o; 708 this._updateColor(); 709 }, 710 711 /** 712 * get the starting gradient opacity 713 * @return {Number} 714 */ 715 getStartOpacity: function () { 716 return this._startOpacity; 717 }, 718 719 /** 720 * set the end gradient opacity 721 * @param {Number} o 722 */ 723 setEndOpacity: function (o) { 724 this._endOpacity = o; 725 this._updateColor(); 726 }, 727 728 /** 729 * get the end gradient opacity 730 * @return {Number} 731 */ 732 getEndOpacity: function () { 733 return this._endOpacity; 734 }, 735 736 /** 737 * set vector 738 * @param {cc.Point} Var 739 */ 740 setVector: function (Var) { 741 this._alongVector.x = Var.x; 742 this._alongVector.y = Var.y; 743 this._updateColor(); 744 }, 745 746 /** 747 * @return {cc.Point} 748 */ 749 getVector: function () { 750 return cc.p(this._alongVector.x, this._alongVector.y); 751 }, 752 753 /** is Compressed Interpolation 754 * @return {Boolean} 755 */ 756 isCompressedInterpolation: function () { 757 return this._compressedInterpolation; 758 }, 759 760 /** 761 * @param {Boolean} compress 762 */ 763 setCompressedInterpolation: function (compress) { 764 this._compressedInterpolation = compress; 765 this._updateColor(); 766 }, 767 768 _draw: null, 769 770 _updateColor: null 771 }); 772 773 /** 774 * creates a gradient layer 775 * @param {cc.Color} start starting color 776 * @param {cc.Color} end ending color 777 * @param {cc.Point|Null} v 778 * @return {cc.LayerGradient} 779 */ 780 cc.LayerGradient.create = function (start, end, v) { 781 return new cc.LayerGradient(start, end, v); 782 }; 783 784 785 if (cc._renderType === cc._RENDER_TYPE_CANVAS) { 786 //cc.LayerGradient define start 787 var _p = cc.LayerGradient.prototype; 788 _p.draw = function (ctx) { 789 var context = ctx || cc._renderContext, _t = this; 790 if (_t._isLighterMode) 791 context.globalCompositeOperation = 'lighter'; 792 793 context.save(); 794 var locEGLViewer = cc.view, opacityf = _t._displayedOpacity / 255.0; 795 var tWidth = _t.width * locEGLViewer.getScaleX(), tHeight = _t.height * locEGLViewer.getScaleY(); 796 var tGradient = context.createLinearGradient(_t._gradientStartPoint.x, _t._gradientStartPoint.y, 797 _t._gradientEndPoint.x, _t._gradientEndPoint.y); 798 var locDisplayedColor = _t._displayedColor, locEndColor = _t._endColor; 799 tGradient.addColorStop(0, "rgba(" + Math.round(locDisplayedColor.r) + "," + Math.round(locDisplayedColor.g) + "," 800 + Math.round(locDisplayedColor.b) + "," + (opacityf * (_t._startOpacity / 255)).toFixed(4) + ")"); 801 tGradient.addColorStop(1, "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + "," 802 + Math.round(locEndColor.b) + "," + (opacityf * (_t._endOpacity / 255)).toFixed(4) + ")"); 803 context.fillStyle = tGradient; 804 context.fillRect(0, 0, tWidth, -tHeight); 805 806 if (_t._rotation != 0) 807 context.rotate(_t._rotationRadians); 808 context.restore(); 809 }; 810 _p._updateColor = function () { 811 var _t = this; 812 var locAlongVector = _t._alongVector, tWidth = _t.width * 0.5, tHeight = _t.height * 0.5; 813 814 _t._gradientStartPoint.x = tWidth * (-locAlongVector.x) + tWidth; 815 _t._gradientStartPoint.y = tHeight * locAlongVector.y - tHeight; 816 _t._gradientEndPoint.x = tWidth * locAlongVector.x + tWidth; 817 _t._gradientEndPoint.y = tHeight * (-locAlongVector.y) - tHeight; 818 }; 819 //cc.LayerGradient define end 820 _p = null; 821 } else { 822 cc.assert(typeof cc._tmp.WebGLLayerGradient === "function", cc._LogInfos.MissingFile, "CCLayerWebGL.js"); 823 cc._tmp.WebGLLayerGradient(); 824 delete cc._tmp.WebGLLayerGradient; 825 } 826 827 cc.assert(typeof cc._tmp.PrototypeLayerGradient === "function", cc._LogInfos.MissingFile, "CCLayerPropertyDefine.js"); 828 cc._tmp.PrototypeLayerGradient(); 829 delete cc._tmp.PrototypeLayerGradient; 830 831 /** 832 * CCMultipleLayer is a CCLayer with the ability to multiplex it's children.<br/> 833 * Features:<br/> 834 * <ul><li>- It supports one or more children</li> 835 * <li>- Only one children will be active a time</li></ul> 836 * @class 837 * @extends cc.Layer 838 */ 839 cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{ 840 _enabledLayer: 0, 841 _layers: null, 842 _className: "LayerMultiplex", 843 844 /** 845 * Constructor of cc.LayerMultiplex 846 * @param {Array} layers an array of cc.Layer 847 */ 848 ctor: function (layers) { 849 cc.Layer.prototype.ctor.call(this); 850 layers && cc.LayerMultiplex.prototype.initWithLayers.call(this, layers); 851 }, 852 853 /** 854 * @param {Array} layers an array of cc.Layer 855 * @return {Boolean} 856 */ 857 initWithLayers: function (layers) { 858 if ((layers.length > 0) && (layers[layers.length - 1] == null)) 859 cc.log(cc._LogInfos.LayerMultiplex_initWithLayers); 860 861 this._layers = layers; 862 this._enabledLayer = 0; 863 this.addChild(this._layers[this._enabledLayer]); 864 return true; 865 }, 866 867 /** 868 * switches to a certain layer indexed by n.<br/> 869 * The current (old) layer will be removed from it's parent with 'cleanup:YES'. 870 * @param {Number} n the layer index to switch to 871 */ 872 switchTo: function (n) { 873 if (n >= this._layers.length) { 874 cc.log(cc._LogInfos.LayerMultiplex_switchTo); 875 return; 876 } 877 878 this.removeChild(this._layers[this._enabledLayer], true); 879 this._enabledLayer = n; 880 this.addChild(this._layers[n]); 881 }, 882 883 /** release the current layer and switches to another layer indexed by n.<br/> 884 * The current (old) layer will be removed from it's parent with 'cleanup:YES'. 885 * @param {Number} n the layer index to switch to 886 */ 887 switchToAndReleaseMe: function (n) { 888 if (n >= this._layers.length) { 889 cc.log(cc._LogInfos.LayerMultiplex_switchToAndReleaseMe); 890 return; 891 } 892 893 this.removeChild(this._layers[this._enabledLayer], true); 894 895 //[layers replaceObjectAtIndex:_enabledLayer withObject:[NSNull null]]; 896 this._layers[this._enabledLayer] = null; 897 this._enabledLayer = n; 898 this.addChild(this._layers[n]); 899 }, 900 901 /** 902 * @param {cc.Layer} layer 903 */ 904 addLayer: function (layer) { 905 if (!layer) { 906 cc.log(cc._LogInfos.LayerMultiplex_addLayer); 907 return; 908 } 909 this._layers.push(layer); 910 } 911 }); 912 913 /** 914 * creates a cc.LayerMultiplex with one or more layers using a variable argument list. 915 * @return {cc.LayerMultiplex|Null} 916 * @example 917 * // Example 918 * var multiLayer = cc.LayerMultiple.create(layer1, layer2, layer3);//any number of layers 919 */ 920 cc.LayerMultiplex.create = function (/*Multiple Arguments*/) { 921 return new cc.LayerMultiplex(arguments); 922 }; 923 924