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