1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga 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 43 */ 44 ctor: function () { 45 cc.Node.prototype.ctor.call(this); 46 this.anchorX = 0.5; 47 this.anchorY = 0.5; 48 this._ignoreAnchorPointForPosition = true; 49 this.setContentSize(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 95 */ 96 ctor: function () { 97 this._displayedColor = cc.color(255, 255, 255, 255); 98 this._realColor = cc.color(255, 255, 255, 255); 99 cc.Layer.prototype.ctor.call(this); 100 }, 101 102 init: function () { 103 if(cc.Layer.prototype.init.call(this)){ 104 this.cascadeOpacity = false; 105 this.cascadeColor = false; 106 return true; 107 } 108 return false; 109 }, 110 111 /** 112 * Get the opacity of Layer 113 * @returns {number} opacity 114 */ 115 getOpacity: function () { 116 return this._realOpacity; 117 }, 118 119 /** 120 * Get the displayed opacity of Layer 121 * @returns {number} displayed opacity 122 */ 123 getDisplayedOpacity: function () { 124 return this._displayedOpacity; 125 }, 126 127 /** 128 * Override synthesized setOpacity to recurse items 129 * @param {Number} opacity 130 */ 131 setOpacity: function (opacity) { 132 this._displayedOpacity = this._realOpacity = opacity; 133 134 var parentOpacity = 255, locParent = this._parent; 135 if (locParent && locParent.RGBAProtocol && locParent.cascadeOpacity) 136 parentOpacity = locParent.getDisplayedOpacity(); 137 this.updateDisplayedOpacity(parentOpacity); 138 139 this._displayedColor.a = this._realColor.a = opacity; 140 }, 141 142 /** 143 * Update displayed opacity of Layer 144 * @param {Number} parentOpacity 145 */ 146 updateDisplayedOpacity: function (parentOpacity) { 147 this._displayedOpacity = 0 | (this._realOpacity * parentOpacity / 255.0); 148 149 if (this._cascadeOpacityEnabled) { 150 var locChildren = this._children; 151 for (var i = 0; i < locChildren.length; i++) { 152 var selItem = locChildren[i]; 153 if (selItem && selItem.RGBAProtocol) 154 selItem.updateDisplayedOpacity(this._displayedOpacity); 155 } 156 } 157 }, 158 159 /** 160 * whether or not it will set cascade opacity. 161 * @returns {boolean} 162 */ 163 isCascadeOpacityEnabled: function () { 164 return this._cascadeOpacityEnabled; 165 }, 166 167 /** 168 * Enable or disable cascade opacity 169 * @param {boolean} cascadeOpacityEnabled 170 */ 171 setCascadeOpacityEnabled: function (cascadeOpacityEnabled) { 172 if(this._cascadeOpacityEnabled === cascadeOpacityEnabled) 173 return; 174 175 this._cascadeOpacityEnabled = cascadeOpacityEnabled; 176 if(cascadeOpacityEnabled) 177 this._enableCascadeOpacity(); 178 else 179 this._disableCascadeOpacity(); 180 }, 181 182 _enableCascadeOpacity:function(){ 183 var parentOpacity = 255, locParent = this._parent; 184 if (locParent && locParent.RGBAProtocol && locParent.cascadeOpacity) 185 parentOpacity = locParent.getDisplayedOpacity(); 186 this.updateDisplayedOpacity(parentOpacity); 187 }, 188 189 _disableCascadeOpacity:function(){ 190 this._displayedOpacity = this._realOpacity; 191 var selChildren = this._children; 192 for(var i = 0; i< selChildren.length;i++){ 193 var item = selChildren[i]; 194 if(item && item.RGBAProtocol) 195 item.updateDisplayedOpacity(255); 196 } 197 }, 198 199 /** 200 * Get the color of Layer 201 * @returns {cc.Color} 202 */ 203 getColor: function () { 204 var locRealColor = this._realColor; 205 return cc.color(locRealColor.r, locRealColor.g, locRealColor.b, locRealColor.a); 206 }, 207 208 /** 209 * Get the displayed color of Layer 210 * @returns {cc.Color} 211 */ 212 getDisplayedColor: function () { 213 var locDisplayedColor = this._displayedColor; 214 return cc.color(locDisplayedColor.r, locDisplayedColor.g, locDisplayedColor.b); 215 }, 216 217 /** 218 * Set the color of Layer 219 * @param {cc.Color} color 220 */ 221 setColor: function (color) { 222 var locDisplayed = this._displayedColor, locRealColor = this._realColor; 223 locDisplayed.r = locRealColor.r = color.r; 224 locDisplayed.g = locRealColor.g = color.g; 225 locDisplayed.b = locRealColor.b = color.b; 226 227 var parentColor, locParent = this._parent; 228 if (locParent && locParent.RGBAProtocol && locParent.cascadeColor) 229 parentColor = locParent.getDisplayedColor(); 230 else 231 parentColor = cc.color.WHITE; 232 this.updateDisplayedColor(parentColor); 233 234 if (color.a !== undefined && !color.a_undefined) { 235 this.setOpacity(color.a); 236 } 237 }, 238 239 /** 240 * update the displayed color of Node 241 * @param {cc.Color} parentColor 242 */ 243 updateDisplayedColor: function (parentColor) { 244 var locDisplayedColor = this._displayedColor, locRealColor = this._realColor; 245 locDisplayedColor.r = 0 | (locRealColor.r * parentColor.r / 255.0); 246 locDisplayedColor.g = 0 | (locRealColor.g * parentColor.g / 255.0); 247 locDisplayedColor.b = 0 | (locRealColor.b * parentColor.b / 255.0); 248 249 if (this._cascadeColorEnabled) { 250 var locChildren = this._children; 251 for (var i = 0; i < locChildren.length; i++) { 252 var selItem = locChildren[i]; 253 if (selItem && selItem.RGBAProtocol) 254 selItem.updateDisplayedColor(locDisplayedColor); 255 } 256 } 257 }, 258 259 /** 260 * whether or not it will set cascade color. 261 * @returns {boolean} 262 */ 263 isCascadeColorEnabled: function () { 264 return this._cascadeColorEnabled; 265 }, 266 267 /** 268 * Enable or disable cascade color 269 * @param {boolean} cascadeColorEnabled 270 */ 271 setCascadeColorEnabled: function (cascadeColorEnabled) { 272 if(this._cascadeColorEnabled === cascadeColorEnabled) 273 return; 274 this._cascadeColorEnabled = cascadeColorEnabled; 275 if(this._cascadeColorEnabled) 276 this._enableCascadeColor(); 277 else 278 this._disableCascadeColor(); 279 }, 280 281 _enableCascadeColor: function(){ 282 var parentColor , locParent = this._parent; 283 if (locParent && locParent.RGBAProtocol && locParent.cascadeColor) 284 parentColor = locParent.getDisplayedColor(); 285 else 286 parentColor = cc.color.WHITE; 287 this.updateDisplayedColor(parentColor); 288 }, 289 290 _disableCascadeColor: function(){ 291 var locDisplayedColor = this._displayedColor, locRealColor = this._realColor; 292 locDisplayedColor.r = locRealColor.r; 293 locDisplayedColor.g = locRealColor.g; 294 locDisplayedColor.b = locRealColor.b; 295 296 var selChildren = this._children, whiteColor = cc.color.WHITE; 297 for(var i = 0; i< selChildren.length;i++){ 298 var item = selChildren[i]; 299 if(item && item.RGBAProtocol) 300 item.updateDisplayedColor(whiteColor); 301 } 302 }, 303 304 /** 305 * add a child to layer 306 * @overried 307 * @param {cc.Node} child A child node 308 * @param {Number} [zOrder=] Z order for drawing priority. Please refer to setLocalZOrder(int) 309 * @param {Number} [tag=] A integer to identify the node easily. Please refer to setTag(int) 310 */ 311 addChild:function(child, zOrder, tag){ 312 cc.Node.prototype.addChild.call(this, child, zOrder, tag); 313 314 if(this._cascadeColorEnabled) 315 this._enableCascadeColor(); 316 if(this._cascadeOpacityEnabled) 317 this._enableCascadeOpacity(); 318 }, 319 320 setOpacityModifyRGB: function (bValue) { 321 }, 322 323 isOpacityModifyRGB: function () { 324 return false; 325 } 326 }); 327 328 window._p = cc.LayerRGBA.prototype; 329 // Extended properties 330 /** @expose */ 331 _p.opacityModifyRGB; 332 cc.defineGetterSetter(_p, "opacityModifyRGB", _p.isOpacityModifyRGB, _p.setOpacityModifyRGB); 333 /** @expose */ 334 _p.opacity; 335 cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity); 336 /** @expose */ 337 _p.cascadeOpacity; 338 cc.defineGetterSetter(_p, "cascadeOpacity", _p.isCascadeOpacityEnabled, _p.setCascadeOpacityEnabled); 339 /** @expose */ 340 _p.color; 341 cc.defineGetterSetter(_p, "color", _p.getColor, _p.setColor); 342 /** @expose */ 343 _p.cascadeColor; 344 cc.defineGetterSetter(_p, "cascadeColor", _p.isCascadeColorEnabled, _p.setCascadeColorEnabled); 345 delete window._p; 346 347 /** 348 * <p> 349 * CCLayerColor is a subclass of CCLayer that implements the CCRGBAProtocol protocol. <br/> 350 * All features from CCLayer are valid, plus the following new features: <br/> 351 * <ul><li>opacity</li> <br/> 352 * <li>RGB colors</li></ul> <br/> 353 * </p> 354 * @class 355 * @extends cc.LayerRGBA 356 */ 357 cc.LayerColor = cc.LayerRGBA.extend(/** @lends cc.LayerColor# */{ 358 _blendFunc:null, 359 _className:"LayerColor", 360 361 /** 362 * blendFunc getter 363 * @return {cc.BlendFunc} 364 */ 365 getBlendFunc:function () { 366 return this._blendFunc; 367 }, 368 369 /** 370 * change width and height in Points 371 * @deprecated 372 * @param {Number} w width 373 * @param {Number} h height 374 */ 375 changeWidthAndHeight:function (w, h) { 376 this.width = w; 377 this.height = h; 378 }, 379 380 /** 381 * change width in Points 382 * @deprecated 383 * @param {Number} w width 384 */ 385 changeWidth:function (w) { 386 this.width = w; 387 }, 388 389 /** 390 * change height in Points 391 * @deprecated 392 * @param {Number} h height 393 */ 394 changeHeight:function (h) { 395 this.height = h; 396 }, 397 398 /** 399 * set OpacityModifyRGB of cc.LayerColor 400 * @param {Boolean} value 401 */ 402 setOpacityModifyRGB:function (value) { 403 }, 404 405 /** 406 * is OpacityModifyRGB 407 * @return {Boolean} 408 */ 409 isOpacityModifyRGB:function () { 410 return false; 411 }, 412 413 setColor:function(color){ 414 cc.LayerRGBA.prototype.setColor.call(this, color); 415 this._updateColor(); 416 }, 417 418 setOpacity:function(opacity){ 419 cc.LayerRGBA.prototype.setOpacity.call(this, opacity); 420 this._updateColor(); 421 }, 422 423 _isLighterMode:false, 424 _squareVertices:null, 425 _squareColors:null, 426 _verticesFloat32Buffer:null, 427 _colorsUint8Buffer:null, 428 _squareVerticesAB:null, 429 _squareColorsAB:null, 430 431 /** 432 * @constructor 433 * @function 434 * @param {cc.Color} [color=] 435 * @param {Number} [width=] 436 * @param {Number} [height=] 437 */ 438 ctor: null, 439 440 _ctorForCanvas: function (color, width, height) { 441 cc.LayerRGBA.prototype.ctor.call(this); 442 this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST); 443 444 cc.LayerColor.prototype.init.call(this, color, width, height); 445 }, 446 447 _ctorForWebGL: function (color, width, height) { 448 this._squareVerticesAB = new ArrayBuffer(32); 449 this._squareColorsAB = new ArrayBuffer(16); 450 451 var locSquareVerticesAB = this._squareVerticesAB, locSquareColorsAB = this._squareColorsAB; 452 var locVertex2FLen = cc.Vertex2F.BYTES_PER_ELEMENT, locColorLen = cc.Color.BYTES_PER_ELEMENT; 453 this._squareVertices = [new cc.Vertex2F(0, 0, locSquareVerticesAB, 0), 454 new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen), 455 new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 2), 456 new cc.Vertex2F(0, 0, locSquareVerticesAB, locVertex2FLen * 3)]; 457 this._squareColors = [cc.color(0, 0, 0, 255, locSquareColorsAB, 0), 458 cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen), 459 cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * 2), 460 cc.color(0, 0, 0, 255, locSquareColorsAB, locColorLen * 3)]; 461 this._verticesFloat32Buffer = cc._renderContext.createBuffer(); 462 this._colorsUint8Buffer = cc._renderContext.createBuffer(); 463 464 cc.LayerRGBA.prototype.ctor.call(this); 465 this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST); 466 467 cc.LayerColor.prototype.init.call(this, color, width, height); 468 }, 469 470 /** 471 * @param {cc.Color} [color=] 472 * @param {Number} [width=] 473 * @param {Number} [height=] 474 * @return {Boolean} 475 */ 476 init: function (color, width, height) { 477 if(cc._renderType !== cc._RENDER_TYPE_CANVAS) 478 this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR); 479 480 var winSize = cc.director.getWinSize(); 481 color = color || cc.color(0, 0, 0, 255); 482 width = width === undefined ? winSize.width : width; 483 height = height === undefined ? winSize.height : height; 484 this.setContentSize(width, height); 485 486 var locDisplayedColor = this._displayedColor; 487 locDisplayedColor.r = color.r; 488 locDisplayedColor.g = color.g; 489 locDisplayedColor.b = color.b; 490 491 var locRealColor = this._realColor; 492 locRealColor.r = color.r; 493 locRealColor.g = color.g; 494 locRealColor.b = color.b; 495 496 this._displayedOpacity = color.a; 497 this._realOpacity = color.a; 498 499 this._updateColor(); 500 501 return true; 502 }, 503 504 /** 505 * blendFunc setter 506 * @param {Number} src 507 * @param {Number} dst 508 */ 509 setBlendFunc:function (src, dst) { 510 if (dst === undefined) 511 this._blendFunc = src; 512 else 513 this._blendFunc = {src:src, dst:dst}; 514 if(cc._renderType === cc._RENDER_TYPE_CANVAS) 515 this._isLighterMode = (this._blendFunc && (this._blendFunc.src == 1) && (this._blendFunc.dst == 771)); 516 }, 517 518 /** 519 * Sets the untransformed size of the LayerColor. 520 * @override 521 * @function 522 * @param {cc.Size|Number} size The untransformed size of the LayerColor or The untransformed size's width of the LayerColor. 523 * @param {Number} [height] The untransformed size's height of the LayerColor. 524 */ 525 setContentSize:null, 526 527 _setContentSizeForWebGL:function (size, height) { 528 var locSquareVertices = this._squareVertices; 529 530 if (height === undefined) { 531 locSquareVertices[1].x = size.width; 532 locSquareVertices[2].y = size.height; 533 locSquareVertices[3].x = size.width; 534 locSquareVertices[3].y = size.height; 535 } else { 536 locSquareVertices[1].x = size; 537 locSquareVertices[2].y = height; 538 locSquareVertices[3].x = size; 539 locSquareVertices[3].y = height; 540 } 541 this._bindLayerVerticesBufferData(); 542 cc.Layer.prototype.setContentSize.call(this, size, height); 543 }, 544 545 _setWidthForWebGL:function (width) { 546 var locSquareVertices = this._squareVertices; 547 locSquareVertices[1].x = width; 548 locSquareVertices[3].x = width; 549 this._bindLayerVerticesBufferData(); 550 cc.Layer.prototype._setWidth.call(this, width); 551 }, 552 _setHeightForWebGL:function (height) { 553 var locSquareVertices = this._squareVertices; 554 locSquareVertices[2].y = height; 555 locSquareVertices[3].y = height; 556 this._bindLayerVerticesBufferData(); 557 cc.Layer.prototype._setHeight.call(this, height); 558 }, 559 560 _updateColor:null, 561 562 _updateColorForCanvas:function () { 563 }, 564 565 _updateColorForWebGL:function () { 566 var locDisplayedColor = this._displayedColor; 567 var locDisplayedOpacity = this._displayedOpacity, locSquareColors = this._squareColors; 568 for (var i = 0; i < 4; i++) { 569 locSquareColors[i].r = locDisplayedColor.r; 570 locSquareColors[i].g = locDisplayedColor.g; 571 locSquareColors[i].b = locDisplayedColor.b; 572 locSquareColors[i].a = locDisplayedOpacity; 573 } 574 this._bindLayerColorsBufferData(); 575 }, 576 577 updateDisplayedColor:function(parentColor){ 578 cc.LayerRGBA.prototype.updateDisplayedColor.call(this, parentColor); 579 this._updateColor(); 580 }, 581 582 updateDisplayedOpacity: function(parentOpacity){ 583 cc.LayerRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity); 584 this._updateColor(); 585 }, 586 587 _bindLayerVerticesBufferData:function () { 588 var glContext = cc._renderContext; 589 glContext.bindBuffer(glContext.ARRAY_BUFFER, this._verticesFloat32Buffer); 590 glContext.bufferData(glContext.ARRAY_BUFFER, this._squareVerticesAB , glContext.STATIC_DRAW); 591 }, 592 593 _bindLayerColorsBufferData:function () { 594 var glContext = cc._renderContext; 595 glContext.bindBuffer(glContext.ARRAY_BUFFER, this._colorsUint8Buffer); 596 glContext.bufferData(glContext.ARRAY_BUFFER, this._squareColorsAB, glContext.STATIC_DRAW); 597 }, 598 599 /** 600 * Renders the layer 601 * @function 602 * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx 603 */ 604 draw:null, 605 606 _drawForCanvas:function (ctx) { 607 var context = ctx || cc._renderContext; 608 609 var locEGLViewer = cc.view; 610 var locDisplayedColor = this._displayedColor; 611 612 context.fillStyle = "rgba(" + (0 | locDisplayedColor.r) + "," + (0 | locDisplayedColor.g) + "," 613 + (0 | locDisplayedColor.b) + "," + this._displayedOpacity / 255 + ")"; 614 context.fillRect(0, 0, this.width * locEGLViewer.getScaleX(), -this.height * locEGLViewer.getScaleY()); 615 616 cc.g_NumberOfDraws++; 617 }, 618 619 _drawForWebGL:function (ctx) { 620 var context = ctx || cc._renderContext; 621 622 cc.NODE_DRAW_SETUP(this); 623 cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR); 624 625 // 626 // Attributes 627 // 628 context.bindBuffer(context.ARRAY_BUFFER, this._verticesFloat32Buffer); 629 context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, context.FLOAT, false, 0, 0); 630 631 context.bindBuffer(context.ARRAY_BUFFER, this._colorsUint8Buffer); 632 context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, 0, 0); 633 634 cc.glBlendFunc(this._blendFunc.src, this._blendFunc.dst); 635 context.drawArrays(context.TRIANGLE_STRIP, 0, 4); 636 } 637 }); 638 639 window._p = cc.LayerColor.prototype; 640 if (cc._renderType === cc._RENDER_TYPE_WEBGL) { 641 _p.ctor = _p._ctorForWebGL; 642 _p.setContentSize = _p._setContentSizeForWebGL; 643 _p._setWidth = _p._setWidthForWebGL; 644 _p._setHeight = _p._setHeightForWebGL; 645 _p._updateColor = _p._updateColorForWebGL; 646 _p.draw = _p._drawForWebGL; 647 } else { 648 _p.ctor = _p._ctorForCanvas; 649 _p.setContentSize = cc.LayerRGBA.prototype.setContentSize; 650 _p._setWidth = cc.LayerRGBA.prototype._setWidth; 651 _p._setHeight = cc.LayerRGBA.prototype._setHeight; 652 _p._updateColor = _p._updateColorForCanvas; 653 _p.draw = _p._drawForCanvas; 654 } 655 656 // Override properties 657 cc.defineGetterSetter(_p, "width", _p._getWidth, _p._setWidth); 658 cc.defineGetterSetter(_p, "height", _p._getHeight, _p._setHeight); 659 660 delete window._p; 661 662 /** 663 * creates a cc.Layer with color, width and height in Points 664 * @param {cc.Color} color 665 * @param {Number|Null} [width=] 666 * @param {Number|Null} [height=] 667 * @return {cc.LayerColor} 668 * @example 669 * // Example 670 * //Create a yellow color layer as background 671 * var yellowBackground = cc.LayerColor.create(cc.color(255,255,0,255)); 672 * //If you didnt pass in width and height, it defaults to the same size as the canvas 673 * 674 * //create a yellow box, 200 by 200 in size 675 * var yellowBox = cc.LayerColor.create(cc.color(255,255,0,255), 200, 200); 676 */ 677 cc.LayerColor.create = function (color, width, height) { 678 return new cc.LayerColor(color, width, height); 679 }; 680 681 /** 682 * <p> 683 * CCLayerGradient is a subclass of cc.LayerColor that draws gradients across the background.<br/> 684 *<br/> 685 * All features from cc.LayerColor are valid, plus the following new features:<br/> 686 * <ul><li>direction</li> 687 * <li>final color</li> 688 * <li>interpolation mode</li></ul> 689 * <br/> 690 * Color is interpolated between the startColor and endColor along the given<br/> 691 * vector (starting at the origin, ending at the terminus). If no vector is<br/> 692 * supplied, it defaults to (0, -1) -- a fade from top to bottom.<br/> 693 * <br/> 694 * If 'compressedInterpolation' is disabled, you will not see either the start or end color for<br/> 695 * non-cardinal vectors; a smooth gradient implying both end points will be still<br/> 696 * be drawn, however.<br/> 697 *<br/> 698 * If 'compressedInterpolation' is enabled (default mode) you will see both the start and end colors of the gradient. 699 * </p> 700 * @class 701 * @extends cc.LayerColor 702 * 703 * @property {cc.Color} startColor - Start color of the color gradient 704 * @property {cc.Color} endColor - End color of the color gradient 705 * @property {Number} startOpacity - Start opacity of the color gradient 706 * @property {Number} endOpacity - End opacity of the color gradient 707 * @property {Number} vector - Direction vector of the color gradient 708 * @property {Number} compresseInterpolation - Indicate whether or not the interpolation will be compressed 709 */ 710 cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{ 711 _startColor:null, 712 _endColor:null, 713 _startOpacity:255, 714 _endOpacity:255, 715 _alongVector:null, 716 _compressedInterpolation:false, 717 _gradientStartPoint:null, 718 _gradientEndPoint:null, 719 _className:"LayerGradient", 720 721 /** 722 * @constructor 723 * @param {cc.Color} start starting color 724 * @param {cc.Color} end 725 * @param {cc.Point|Null} v 726 */ 727 ctor:function (start, end, v) { 728 this._startColor = cc.color(0, 0, 0, 255); 729 this._endColor = cc.color(0, 0, 0, 255); 730 this._alongVector = cc.p(0, -1); 731 this._startOpacity = 255; 732 this._endOpacity = 255; 733 this._gradientStartPoint = cc.p(0, 0); 734 this._gradientEndPoint = cc.p(0, 0); 735 736 cc.LayerColor.prototype.ctor.call(this); 737 cc.LayerGradient.prototype.init.call(this, start, end, v); 738 }, 739 740 /** 741 * @param {cc.Color} start starting color 742 * @param {cc.Color} end 743 * @param {cc.Point|Null} v 744 * @return {Boolean} 745 */ 746 init:function (start, end, v) { 747 start = start || cc.color(0,0,0,255); 748 end = end || cc.color(0,0,0,255); 749 v = v || cc.p(0, -1); 750 751 // Initializes the CCLayer with a gradient between start and end in the direction of v. 752 var locStartColor = this._startColor, locEndColor = this._endColor; 753 locStartColor.r = start.r; 754 locStartColor.g = start.g; 755 locStartColor.b = start.b; 756 this._startOpacity = start.a; 757 758 locEndColor.r = end.r; 759 locEndColor.g = end.g; 760 locEndColor.b = end.b; 761 this._endOpacity = end.a; 762 763 this._alongVector = v; 764 this._compressedInterpolation = true; 765 this._gradientStartPoint = cc.p(0, 0); 766 this._gradientEndPoint = cc.p(0, 0); 767 768 cc.LayerColor.prototype.init.call(this,cc.color(start.r, start.g, start.b, 255)); 769 return true; 770 }, 771 772 /** 773 * Sets the untransformed size of the LayerGradient. 774 * @override 775 * @param {cc.Size|Number} size The untransformed size of the LayerGradient or The untransformed size's width of the LayerGradient. 776 * @param {Number} [height] The untransformed size's height of the LayerGradient. 777 */ 778 setContentSize:function(size, height){ 779 cc.LayerColor.prototype.setContentSize.call(this,size, height); 780 this._updateColor(); 781 }, 782 783 _setWidth:function(width){ 784 cc.LayerColor.prototype._setWidth.call(this, width); 785 this._updateColor(); 786 }, 787 _setHeight:function(height){ 788 cc.LayerColor.prototype._setHeight.call(this, height); 789 this._updateColor(); 790 }, 791 792 /** 793 * get the starting color 794 * @return {cc.Color} 795 */ 796 getStartColor:function () { 797 return this._realColor; 798 }, 799 800 /** 801 * set the starting color 802 * @param {cc.Color} color 803 * @example 804 * // Example 805 * myGradientLayer.setStartColor(cc.color(255,0,0)); 806 * //set the starting gradient to red 807 */ 808 setStartColor:function (color) { 809 this.color = color; 810 }, 811 812 /** 813 * set the end gradient color 814 * @param {cc.Color} color 815 * @example 816 * // Example 817 * myGradientLayer.setEndColor(cc.color(255,0,0)); 818 * //set the ending gradient to red 819 */ 820 setEndColor:function (color) { 821 this._endColor = color; 822 this._updateColor(); 823 }, 824 825 /** 826 * get the end color 827 * @return {cc.Color} 828 */ 829 getEndColor:function () { 830 return this._endColor; 831 }, 832 833 /** 834 * set starting gradient opacity 835 * @param {Number} o from 0 to 255, 0 is transparent 836 */ 837 setStartOpacity:function (o) { 838 this._startOpacity = o; 839 this._updateColor(); 840 }, 841 842 /** 843 * get the starting gradient opacity 844 * @return {Number} 845 */ 846 getStartOpacity:function () { 847 return this._startOpacity; 848 }, 849 850 /** 851 * set the end gradient opacity 852 * @param {Number} o 853 */ 854 setEndOpacity:function (o) { 855 this._endOpacity = o; 856 this._updateColor(); 857 }, 858 859 /** 860 * get the end gradient opacity 861 * @return {Number} 862 */ 863 getEndOpacity:function () { 864 return this._endOpacity; 865 }, 866 867 /** 868 * set vector 869 * @param {cc.Point} Var 870 */ 871 setVector:function (Var) { 872 this._alongVector.x = Var.x; 873 this._alongVector.y = Var.y; 874 this._updateColor(); 875 }, 876 877 /** 878 * @return {cc.Point} 879 */ 880 getVector:function () { 881 return cc.p(this._alongVector.x, this._alongVector.y); 882 }, 883 884 /** is Compressed Interpolation 885 * @return {Boolean} 886 */ 887 isCompressedInterpolation:function () { 888 return this._compressedInterpolation; 889 }, 890 891 /** 892 * @param {Boolean} compress 893 */ 894 setCompressedInterpolation:function (compress) { 895 this._compressedInterpolation = compress; 896 this._updateColor(); 897 }, 898 899 draw:function (ctx) { 900 if (cc._renderType === cc._RENDER_TYPE_WEBGL){ 901 cc.LayerColor.prototype.draw.call(this, ctx); 902 return; 903 } 904 905 var context = ctx || cc._renderContext; 906 if (this._isLighterMode) 907 context.globalCompositeOperation = 'lighter'; 908 909 context.save(); 910 var locEGLViewer = cc.view, opacityf = this._displayedOpacity / 255.0; 911 var tWidth = this.width * locEGLViewer.getScaleX(); 912 var tHeight = this.height * locEGLViewer.getScaleY(); 913 var tGradient = context.createLinearGradient(this._gradientStartPoint.x, this._gradientStartPoint.y, 914 this._gradientEndPoint.x, this._gradientEndPoint.y); 915 var locDisplayedColor = this._displayedColor; 916 var locEndColor = this._endColor; 917 tGradient.addColorStop(0, "rgba(" + Math.round(locDisplayedColor.r) + "," + Math.round(locDisplayedColor.g) + "," 918 + Math.round(locDisplayedColor.b) + "," + (opacityf * (this._startOpacity / 255)).toFixed(4) + ")"); 919 tGradient.addColorStop(1, "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + "," 920 + Math.round(locEndColor.b) + "," + (opacityf * (this._endOpacity / 255)).toFixed(4) + ")"); 921 context.fillStyle = tGradient; 922 context.fillRect(0, 0, tWidth, -tHeight); 923 924 if (this._rotation != 0) 925 context.rotate(this._rotationRadians); 926 context.restore(); 927 }, 928 929 _updateColor:function () { 930 var locAlongVector = this._alongVector; 931 if (cc._renderType === cc._RENDER_TYPE_CANVAS) { 932 var tWidth = this.width * 0.5; 933 var tHeight = this.height * 0.5; 934 935 this._gradientStartPoint.x = tWidth * (-locAlongVector.x) + tWidth; 936 this._gradientStartPoint.y = tHeight * locAlongVector.y - tHeight; 937 this._gradientEndPoint.x = tWidth * locAlongVector.x + tWidth; 938 this._gradientEndPoint.y = tHeight * (-locAlongVector.y) - tHeight; 939 } else { 940 var h = cc.pLength(locAlongVector); 941 if (h === 0) 942 return; 943 944 var c = Math.sqrt(2.0); 945 var u = cc.p(locAlongVector.x / h, locAlongVector.y / h); 946 947 // Compressed Interpolation mode 948 if (this._compressedInterpolation) { 949 var h2 = 1 / ( Math.abs(u.x) + Math.abs(u.y) ); 950 u = cc.pMult(u, h2 * c); 951 } 952 953 var opacityf = this._displayedOpacity / 255.0; 954 var locDisplayedColor = this._displayedColor, locEndColor = this._endColor; 955 var S = { r: locDisplayedColor.r, g: locDisplayedColor.g, b: locDisplayedColor.b, a: this._startOpacity * opacityf}; 956 var E = {r: locEndColor.r, g: locEndColor.g, b: locEndColor.b, a: this._endOpacity * opacityf}; 957 958 // (-1, -1) 959 var locSquareColors = this._squareColors; 960 var locSquareColor0 = locSquareColors[0], locSquareColor1 = locSquareColors[1], locSquareColor2 = locSquareColors[2],locSquareColor3 = locSquareColors[3]; 961 locSquareColor0.r = ((E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0 * c)))); 962 locSquareColor0.g = ((E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0 * c)))); 963 locSquareColor0.b = ((E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0 * c)))); 964 locSquareColor0.a = ((E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0 * c)))); 965 // (1, -1) 966 locSquareColor1.r = ((E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0 * c)))); 967 locSquareColor1.g = ((E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0 * c)))); 968 locSquareColor1.b = ((E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0 * c)))); 969 locSquareColor1.a = ((E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0 * c)))); 970 // (-1, 1) 971 locSquareColor2.r = ((E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0 * c)))); 972 locSquareColor2.g = ((E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0 * c)))); 973 locSquareColor2.b = ((E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0 * c)))); 974 locSquareColor2.a = ((E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0 * c)))); 975 // (1, 1) 976 locSquareColor3.r = ((E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0 * c)))); 977 locSquareColor3.g = ((E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0 * c)))); 978 locSquareColor3.b = ((E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0 * c)))); 979 locSquareColor3.a = ((E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0 * c)))); 980 981 this._bindLayerColorsBufferData(); 982 } 983 } 984 }); 985 986 window._p = cc.LayerGradient.prototype; 987 988 // Extended properties 989 /** @expose */ 990 _p.startColor; 991 cc.defineGetterSetter(_p, "startColor", _p.getStartColor, _p.setStartColor); 992 /** @expose */ 993 _p.endColor; 994 cc.defineGetterSetter(_p, "endColor", _p.getEndColor, _p.setEndColor); 995 /** @expose */ 996 _p.startOpacity; 997 cc.defineGetterSetter(_p, "startOpacity", _p.getStartOpacity, _p.setStartOpacity); 998 /** @expose */ 999 _p.endOpacity; 1000 cc.defineGetterSetter(_p, "endOpacity", _p.getEndOpacity, _p.setEndOpacity); 1001 /** @expose */ 1002 _p.vector; 1003 cc.defineGetterSetter(_p, "vector", _p.getVector, _p.setVector); 1004 1005 delete window._p; 1006 1007 /** 1008 * creates a gradient layer 1009 * @param {cc.Color} start starting color 1010 * @param {cc.Color} end ending color 1011 * @param {cc.Point|Null} v 1012 * @return {cc.LayerGradient} 1013 */ 1014 cc.LayerGradient.create = function (start, end, v) { 1015 return new cc.LayerGradient(start, end, v); 1016 }; 1017 1018 /** 1019 * CCMultipleLayer is a CCLayer with the ability to multiplex it's children.<br/> 1020 * Features:<br/> 1021 * <ul><li>- It supports one or more children</li> 1022 * <li>- Only one children will be active a time</li></ul> 1023 * @class 1024 * @extends cc.Layer 1025 */ 1026 cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{ 1027 _enabledLayer:0, 1028 _layers:null, 1029 _className:"LayerMultiplex", 1030 1031 /** 1032 * @constructor 1033 * @param {Array} layers an array of cc.Layer 1034 */ 1035 ctor: function (layers) { 1036 cc.Layer.prototype.ctor.call(this); 1037 layers && cc.LayerMultiplex.prototype.initWithLayers.call(this, layers); 1038 }, 1039 1040 /** 1041 * @param {Array} layers an array of cc.Layer 1042 * @return {Boolean} 1043 */ 1044 initWithLayers:function (layers) { 1045 if((layers.length > 0) && (layers[layers.length-1] == null)) 1046 cc.log("parameters should not be ending with null in Javascript"); 1047 1048 this._layers = layers; 1049 this._enabledLayer = 0; 1050 this.addChild(this._layers[this._enabledLayer]); 1051 return true; 1052 }, 1053 1054 /** 1055 * switches to a certain layer indexed by n.<br/> 1056 * The current (old) layer will be removed from it's parent with 'cleanup:YES'. 1057 * @param {Number} n the layer index to switch to 1058 */ 1059 switchTo:function (n) { 1060 if(n >= this._layers.length){ 1061 cc.log("cc.LayerMultiplex.switchTo():Invalid index in MultiplexLayer switchTo message"); 1062 return; 1063 } 1064 1065 this.removeChild(this._layers[this._enabledLayer], true); 1066 this._enabledLayer = n; 1067 this.addChild(this._layers[n]); 1068 }, 1069 1070 /** release the current layer and switches to another layer indexed by n.<br/> 1071 * The current (old) layer will be removed from it's parent with 'cleanup:YES'. 1072 * @param {Number} n the layer index to switch to 1073 */ 1074 switchToAndReleaseMe:function (n) { 1075 if(n >= this._layers.length){ 1076 cc.log("cc.LayerMultiplex.switchToAndReleaseMe():Invalid index in MultiplexLayer switchTo message"); 1077 return; 1078 } 1079 1080 this.removeChild(this._layers[this._enabledLayer], true); 1081 1082 //[layers replaceObjectAtIndex:_enabledLayer withObject:[NSNull null]]; 1083 this._layers[this._enabledLayer] = null; 1084 this._enabledLayer = n; 1085 this.addChild(this._layers[n]); 1086 }, 1087 1088 /** 1089 * @param {cc.Layer} layer 1090 */ 1091 addLayer:function (layer) { 1092 if(!layer){ 1093 cc.log("cc.Layer.addLayer(): layer should be non-null"); 1094 return; 1095 } 1096 this._layers.push(layer); 1097 } 1098 }); 1099 1100 /** 1101 * creates a cc.LayerMultiplex with one or more layers using a variable argument list. 1102 * @return {cc.LayerMultiplex|Null} 1103 * @example 1104 * // Example 1105 * var multiLayer = cc.LayerMultiple.create(layer1, layer2, layer3);//any number of layers 1106 */ 1107 cc.LayerMultiplex.create = function (/*Multiple Arguments*/) { 1108 return new cc.LayerMultiplex(arguments); 1109 }; 1110 1111