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         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
 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 _tmp.PrototypeLayerRGBA();
332 delete _tmp.PrototypeLayerRGBA;
333 
334 /**
335  * <p>
336  * CCLayerColor is a subclass of CCLayer that implements the CCRGBAProtocol protocol.       <br/>
337  *  All features from CCLayer are valid, plus the following new features:                   <br/>
338  * <ul><li>opacity</li>                                                                     <br/>
339  * <li>RGB colors</li></ul>                                                                 <br/>
340  * </p>
341  * @class
342  * @extends cc.LayerRGBA
343  */
344 cc.LayerColor = cc.LayerRGBA.extend(/** @lends cc.LayerColor# */{
345     _blendFunc: null,
346     _className: "LayerColor",
347 
348     /**
349      * blendFunc getter
350      * @return {cc.BlendFunc}
351      */
352     getBlendFunc: function () {
353         return this._blendFunc;
354     },
355 
356     /**
357      * change width and height in Points
358      * @deprecated
359      * @param {Number} w width
360      * @param {Number} h height
361      */
362     changeWidthAndHeight: function (w, h) {
363         this.width = w;
364         this.height = h;
365     },
366 
367     /**
368      * change width in Points
369      * @deprecated
370      * @param {Number} w width
371      */
372     changeWidth: function (w) {
373         this.width = w;
374     },
375 
376     /**
377      * change height in Points
378      * @deprecated
379      * @param {Number} h height
380      */
381     changeHeight: function (h) {
382         this.height = h;
383     },
384 
385     /**
386      * set OpacityModifyRGB of cc.LayerColor
387      * @param {Boolean}  value
388      */
389     setOpacityModifyRGB: function (value) {
390     },
391 
392     /**
393      * is OpacityModifyRGB
394      * @return {Boolean}
395      */
396     isOpacityModifyRGB: function () {
397         return false;
398     },
399 
400     setColor: function (color) {
401         cc.LayerRGBA.prototype.setColor.call(this, color);
402         this._updateColor();
403     },
404 
405     setOpacity: function (opacity) {
406         cc.LayerRGBA.prototype.setOpacity.call(this, opacity);
407         this._updateColor();
408     },
409 
410     _isLighterMode: false,
411     /**
412      * @constructor
413      * @function
414      * @param {cc.Color} [color=]
415      * @param {Number} [width=]
416      * @param {Number} [height=]
417      */
418     ctor: null,
419 
420     /**
421      * @param {cc.Color} [color=]
422      * @param {Number} [width=]
423      * @param {Number} [height=]
424      * @return {Boolean}
425      */
426     init: function (color, width, height) {
427         if (cc._renderType !== cc._RENDER_TYPE_CANVAS)
428             this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
429 
430         var winSize = cc.director.getWinSize();
431         color = color || cc.color(0, 0, 0, 255);
432         width = width === undefined ? winSize.width : width;
433         height = height === undefined ? winSize.height : height;
434 
435         var locDisplayedColor = this._displayedColor;
436         locDisplayedColor.r = color.r;
437         locDisplayedColor.g = color.g;
438         locDisplayedColor.b = color.b;
439 
440         var locRealColor = this._realColor;
441         locRealColor.r = color.r;
442         locRealColor.g = color.g;
443         locRealColor.b = color.b;
444 
445         this._displayedOpacity = color.a;
446         this._realOpacity = color.a;
447 
448         var proto = cc.LayerColor.prototype;
449         proto.setContentSize.call(this, width, height);
450         proto._updateColor.call(this);
451         return true;
452     },
453 
454     /**
455      * blendFunc setter
456      * @param {Number} src
457      * @param {Number} dst
458      */
459     setBlendFunc: function (src, dst) {
460         var _t = this;
461         if (dst === undefined)
462             _t._blendFunc = src;
463         else
464             _t._blendFunc = {src: src, dst: dst};
465         if (cc._renderType === cc._RENDER_TYPE_CANVAS)
466             _t._isLighterMode = (_t._blendFunc && (_t._blendFunc.src == 1) && (_t._blendFunc.dst == 771));
467     },
468 
469     _setWidth: null,
470 
471     _setHeight: null,
472 
473     _updateColor: null,
474 
475     updateDisplayedColor: function (parentColor) {
476         cc.LayerRGBA.prototype.updateDisplayedColor.call(this, parentColor);
477         this._updateColor();
478     },
479 
480     updateDisplayedOpacity: function (parentOpacity) {
481         cc.LayerRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity);
482         this._updateColor();
483     },
484 
485     /**
486      * Renders the layer
487      * @function
488      * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx
489      */
490     draw: null
491 });
492 
493 /**
494  * creates a cc.Layer with color, width and height in Points
495  * @param {cc.Color} color
496  * @param {Number|Null} [width=]
497  * @param {Number|Null} [height=]
498  * @return {cc.LayerColor}
499  * @example
500  * // Example
501  * //Create a yellow color layer as background
502  * var yellowBackground = cc.LayerColor.create(cc.color(255,255,0,255));
503  * //If you didnt pass in width and height, it defaults to the same size as the canvas
504  *
505  * //create a yellow box, 200 by 200 in size
506  * var yellowBox = cc.LayerColor.create(cc.color(255,255,0,255), 200, 200);
507  */
508 cc.LayerColor.create = function (color, width, height) {
509     return new cc.LayerColor(color, width, height);
510 };
511 
512 
513 if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
514     //cc.LayerColor define start
515     var _p = cc.LayerColor.prototype;
516     _p.ctor = function (color, width, height) {
517         cc.LayerRGBA.prototype.ctor.call(this);
518         this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
519         cc.LayerColor.prototype.init.call(this, color, width, height);
520     }
521     _p._setWidth = cc.LayerRGBA.prototype._setWidth;
522     _p._setHeight = cc.LayerRGBA.prototype._setHeight;
523     _p._updateColor = function () {
524     };
525     _p.draw = function (ctx) {
526         var context = ctx || cc._renderContext, _t = this;
527         var locEGLViewer = cc.view, locDisplayedColor = _t._displayedColor;
528 
529         context.fillStyle = "rgba(" + (0 | locDisplayedColor.r) + "," + (0 | locDisplayedColor.g) + ","
530             + (0 | locDisplayedColor.b) + "," + _t._displayedOpacity / 255 + ")";
531         context.fillRect(0, 0, _t.width * locEGLViewer.getScaleX(), -_t.height * locEGLViewer.getScaleY());
532         cc.g_NumberOfDraws++;
533     };
534     //cc.LayerGradient define end
535     _p = null;
536 } else {
537     _tmp.WebGLLayerColor();
538     delete _tmp.WebGLLayerColor;
539 }
540 
541 _tmp.PrototypeLayerColor();
542 delete _tmp.PrototypeLayerColor;
543 
544 /**
545  * <p>
546  * CCLayerGradient is a subclass of cc.LayerColor that draws gradients across the background.<br/>
547  *<br/>
548  * All features from cc.LayerColor are valid, plus the following new features:<br/>
549  * <ul><li>direction</li>
550  * <li>final color</li>
551  * <li>interpolation mode</li></ul>
552  * <br/>
553  * Color is interpolated between the startColor and endColor along the given<br/>
554  * vector (starting at the origin, ending at the terminus).  If no vector is<br/>
555  * supplied, it defaults to (0, -1) -- a fade from top to bottom.<br/>
556  * <br/>
557  * If 'compressedInterpolation' is disabled, you will not see either the start or end color for<br/>
558  * non-cardinal vectors; a smooth gradient implying both end points will be still<br/>
559  * be drawn, however.<br/>
560  *<br/>
561  * If 'compressedInterpolation' is enabled (default mode) you will see both the start and end colors of the gradient.
562  * </p>
563  * @class
564  * @extends cc.LayerColor
565  *
566  * @property {cc.Color} startColor              - Start color of the color gradient
567  * @property {cc.Color} endColor                - End color of the color gradient
568  * @property {Number}   startOpacity            - Start opacity of the color gradient
569  * @property {Number}   endOpacity              - End opacity of the color gradient
570  * @property {Number}   vector                  - Direction vector of the color gradient
571  * @property {Number}   compresseInterpolation  - Indicate whether or not the interpolation will be compressed
572  */
573 cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
574     _startColor: null,
575     _endColor: null,
576     _startOpacity: 255,
577     _endOpacity: 255,
578     _alongVector: null,
579     _compressedInterpolation: false,
580     _gradientStartPoint: null,
581     _gradientEndPoint: null,
582     _className: "LayerGradient",
583 
584     /**
585      * @constructor
586      * @param {cc.Color} start starting color
587      * @param {cc.Color} end
588      * @param {cc.Point|Null} v
589      */
590     ctor: function (start, end, v) {
591         var _t = this;
592         cc.LayerColor.prototype.ctor.call(_t);
593 
594         _t._startColor = cc.color(0, 0, 0, 255);
595         _t._endColor = cc.color(0, 0, 0, 255);
596         _t._alongVector = cc.p(0, -1);
597         _t._startOpacity = 255;
598         _t._endOpacity = 255;
599         _t._gradientStartPoint = cc.p(0, 0);
600         _t._gradientEndPoint = cc.p(0, 0);
601         cc.LayerGradient.prototype.init.call(_t, start, end, v);
602     },
603 
604     /**
605      * @param {cc.Color} start starting color
606      * @param {cc.Color} end
607      * @param {cc.Point|Null} v
608      * @return {Boolean}
609      */
610     init: function (start, end, v) {
611         start = start || cc.color(0, 0, 0, 255);
612         end = end || cc.color(0, 0, 0, 255);
613         v = v || cc.p(0, -1);
614         var _t = this;
615 
616         // Initializes the CCLayer with a gradient between start and end in the direction of v.
617         var locStartColor = _t._startColor, locEndColor = _t._endColor;
618         locStartColor.r = start.r;
619         locStartColor.g = start.g;
620         locStartColor.b = start.b;
621         _t._startOpacity = start.a;
622 
623         locEndColor.r = end.r;
624         locEndColor.g = end.g;
625         locEndColor.b = end.b;
626         _t._endOpacity = end.a;
627 
628         _t._alongVector = v;
629         _t._compressedInterpolation = true;
630         _t._gradientStartPoint = cc.p(0, 0);
631         _t._gradientEndPoint = cc.p(0, 0);
632 
633         cc.LayerColor.prototype.init.call(_t, cc.color(start.r, start.g, start.b, 255));
634         cc.LayerGradient.prototype._updateColor.call(_t);
635         return true;
636     },
637 
638     /**
639      * Sets the untransformed size of the LayerGradient.
640      * @override
641      * @param {cc.Size|Number} size The untransformed size of the LayerGradient or The untransformed size's width of the LayerGradient.
642      * @param {Number} [height] The untransformed size's height of the LayerGradient.
643      */
644     setContentSize: function (size, height) {
645         cc.LayerColor.prototype.setContentSize.call(this, size, height);
646         this._updateColor();
647     },
648 
649     _setWidth: function (width) {
650         cc.LayerColor.prototype._setWidth.call(this, width);
651         this._updateColor();
652     },
653     _setHeight: function (height) {
654         cc.LayerColor.prototype._setHeight.call(this, height);
655         this._updateColor();
656     },
657 
658     /**
659      * get the starting color
660      * @return {cc.Color}
661      */
662     getStartColor: function () {
663         return this._realColor;
664     },
665 
666     /**
667      * set the starting color
668      * @param {cc.Color} color
669      * @example
670      * // Example
671      * myGradientLayer.setStartColor(cc.color(255,0,0));
672      * //set the starting gradient to red
673      */
674     setStartColor: function (color) {
675         this.color = color;
676     },
677 
678     /**
679      * set the end gradient color
680      * @param {cc.Color} color
681      * @example
682      * // Example
683      * myGradientLayer.setEndColor(cc.color(255,0,0));
684      * //set the ending gradient to red
685      */
686     setEndColor: function (color) {
687         this._endColor = color;
688         this._updateColor();
689     },
690 
691     /**
692      * get the end color
693      * @return {cc.Color}
694      */
695     getEndColor: function () {
696         return this._endColor;
697     },
698 
699     /**
700      * set starting gradient opacity
701      * @param {Number} o from 0 to 255, 0 is transparent
702      */
703     setStartOpacity: function (o) {
704         this._startOpacity = o;
705         this._updateColor();
706     },
707 
708     /**
709      * get the starting gradient opacity
710      * @return {Number}
711      */
712     getStartOpacity: function () {
713         return this._startOpacity;
714     },
715 
716     /**
717      * set the end gradient opacity
718      * @param {Number} o
719      */
720     setEndOpacity: function (o) {
721         this._endOpacity = o;
722         this._updateColor();
723     },
724 
725     /**
726      * get the end gradient opacity
727      * @return {Number}
728      */
729     getEndOpacity: function () {
730         return this._endOpacity;
731     },
732 
733     /**
734      * set vector
735      * @param {cc.Point} Var
736      */
737     setVector: function (Var) {
738         this._alongVector.x = Var.x;
739         this._alongVector.y = Var.y;
740         this._updateColor();
741     },
742 
743     /**
744      * @return {cc.Point}
745      */
746     getVector: function () {
747         return cc.p(this._alongVector.x, this._alongVector.y);
748     },
749 
750     /** is Compressed Interpolation
751      * @return {Boolean}
752      */
753     isCompressedInterpolation: function () {
754         return this._compressedInterpolation;
755     },
756 
757     /**
758      * @param {Boolean} compress
759      */
760     setCompressedInterpolation: function (compress) {
761         this._compressedInterpolation = compress;
762         this._updateColor();
763     },
764 
765     _draw: null,
766 
767     _updateColor: null
768 });
769 
770 /**
771  * creates a gradient layer
772  * @param {cc.Color} start starting color
773  * @param {cc.Color} end ending color
774  * @param {cc.Point|Null} v
775  * @return {cc.LayerGradient}
776  */
777 cc.LayerGradient.create = function (start, end, v) {
778     return new cc.LayerGradient(start, end, v);
779 };
780 
781 
782 if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
783     //cc.LayerGradient define start
784     var _p = cc.LayerGradient.prototype;
785     _p.draw = function (ctx) {
786         var context = ctx || cc._renderContext, _t = this;
787         if (_t._isLighterMode)
788             context.globalCompositeOperation = 'lighter';
789 
790         context.save();
791         var locEGLViewer = cc.view, opacityf = _t._displayedOpacity / 255.0;
792         var tWidth = _t.width * locEGLViewer.getScaleX(), tHeight = _t.height * locEGLViewer.getScaleY();
793         var tGradient = context.createLinearGradient(_t._gradientStartPoint.x, _t._gradientStartPoint.y,
794             _t._gradientEndPoint.x, _t._gradientEndPoint.y);
795         var locDisplayedColor = _t._displayedColor, locEndColor = _t._endColor;
796         tGradient.addColorStop(0, "rgba(" + Math.round(locDisplayedColor.r) + "," + Math.round(locDisplayedColor.g) + ","
797             + Math.round(locDisplayedColor.b) + "," + (opacityf * (_t._startOpacity / 255)).toFixed(4) + ")");
798         tGradient.addColorStop(1, "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + ","
799             + Math.round(locEndColor.b) + "," + (opacityf * (_t._endOpacity / 255)).toFixed(4) + ")");
800         context.fillStyle = tGradient;
801         context.fillRect(0, 0, tWidth, -tHeight);
802 
803         if (_t._rotation != 0)
804             context.rotate(_t._rotationRadians);
805         context.restore();
806     };
807     _p._updateColor = function () {
808         var _t = this;
809         var locAlongVector = _t._alongVector, tWidth = _t.width * 0.5, tHeight = _t.height * 0.5;
810 
811         _t._gradientStartPoint.x = tWidth * (-locAlongVector.x) + tWidth;
812         _t._gradientStartPoint.y = tHeight * locAlongVector.y - tHeight;
813         _t._gradientEndPoint.x = tWidth * locAlongVector.x + tWidth;
814         _t._gradientEndPoint.y = tHeight * (-locAlongVector.y) - tHeight;
815     };
816     //cc.LayerGradient define end
817     _p = null;
818 } else {
819     _tmp.WebGLLayerGradient();
820     delete _tmp.WebGLLayerGradient;
821 }
822 _tmp.PrototypeLayerGradient();
823 delete _tmp.PrototypeLayerGradient;
824 
825 /**
826  * CCMultipleLayer is a CCLayer with the ability to multiplex it's children.<br/>
827  * Features:<br/>
828  *  <ul><li>- It supports one or more children</li>
829  *  <li>- Only one children will be active a time</li></ul>
830  *  @class
831  *  @extends cc.Layer
832  */
833 cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{
834     _enabledLayer: 0,
835     _layers: null,
836     _className: "LayerMultiplex",
837 
838     /**
839      * @constructor
840      * @param {Array} layers an array of cc.Layer
841      */
842     ctor: function (layers) {
843         cc.Layer.prototype.ctor.call(this);
844         layers && cc.LayerMultiplex.prototype.initWithLayers.call(this, layers);
845     },
846 
847     /**
848      * @param {Array} layers an array of cc.Layer
849      * @return {Boolean}
850      */
851     initWithLayers: function (layers) {
852         if ((layers.length > 0) && (layers[layers.length - 1] == null))
853             cc.log(cc._LogInfos.LayerMultiplex_initWithLayers);
854 
855         this._layers = layers;
856         this._enabledLayer = 0;
857         this.addChild(this._layers[this._enabledLayer]);
858         return true;
859     },
860 
861     /**
862      * switches to a certain layer indexed by n.<br/>
863      * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
864      * @param {Number} n the layer index to switch to
865      */
866     switchTo: function (n) {
867         if (n >= this._layers.length) {
868             cc.log(cc._LogInfos.LayerMultiplex_switchTo);
869             return;
870         }
871 
872         this.removeChild(this._layers[this._enabledLayer], true);
873         this._enabledLayer = n;
874         this.addChild(this._layers[n]);
875     },
876 
877     /** release the current layer and switches to another layer indexed by n.<br/>
878      * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
879      * @param {Number} n the layer index to switch to
880      */
881     switchToAndReleaseMe: function (n) {
882         if (n >= this._layers.length) {
883             cc.log(cc._LogInfos.LayerMultiplex_switchToAndReleaseMe);
884             return;
885         }
886 
887         this.removeChild(this._layers[this._enabledLayer], true);
888 
889         //[layers replaceObjectAtIndex:_enabledLayer withObject:[NSNull null]];
890         this._layers[this._enabledLayer] = null;
891         this._enabledLayer = n;
892         this.addChild(this._layers[n]);
893     },
894 
895     /**
896      * @param {cc.Layer} layer
897      */
898     addLayer: function (layer) {
899         if (!layer) {
900             cc.log(cc._LogInfos.LayerMultiplex_addLayer);
901             return;
902         }
903         this._layers.push(layer);
904     }
905 });
906 
907 /**
908  * creates a cc.LayerMultiplex with one or more layers using a variable argument list.
909  * @return {cc.LayerMultiplex|Null}
910  * @example
911  * // Example
912  * var multiLayer = cc.LayerMultiple.create(layer1, layer2, layer3);//any number of layers
913  */
914 cc.LayerMultiplex.create = function (/*Multiple Arguments*/) {
915     return new cc.LayerMultiplex(arguments);
916 };
917 
918