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 /** 28 * <p> 29 * A cc.SpriteFrame has:<br/> 30 * - texture: A cc.Texture2D that will be used by the cc.Sprite<br/> 31 * - rectangle: A rectangle of the texture<br/> 32 * <br/> 33 * You can modify the frame of a cc.Sprite by doing:<br/> 34 * </p> 35 * @class 36 * @extends cc.Class 37 * 38 * @example 39 * var texture = cc.TextureCache.getInstance().addImage(s_dragon_animation); 40 * var frame0 = cc.SpriteFrame.createWithTexture(texture, cc.rect(132 * 0, 132 * 0, 132, 132)); 41 */ 42 cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{ 43 _offset:null, 44 _originalSize:null, 45 _rectInPixels:null, 46 _rotated:false, 47 _rect:null, 48 _offsetInPixels:null, 49 _originalSizeInPixels:null, 50 _texture:null, 51 _textureFilename:"", 52 _textureLoaded:false, 53 _eventListeners:null, 54 55 ctor:function () { 56 this._offset = cc.p(0, 0); 57 this._offsetInPixels = cc.p(0, 0); 58 this._originalSize = cc.size(0, 0); 59 this._rectInPixels = cc.rect(0, 0, 0, 0); 60 this._rotated = false; 61 this._rect = cc.rect(0, 0, 0, 0); 62 this._originalSizeInPixels = cc.size(0, 0); 63 this._textureFilename = ""; 64 this._texture = null; 65 this._textureLoaded = false; 66 this._eventListeners = []; 67 }, 68 69 // attributes 70 textureLoaded:function(){ 71 return this._textureLoaded; 72 }, 73 74 addLoadedEventListener:function(callback, target){ 75 this._eventListeners.push({eventCallback:callback, eventTarget:target}); 76 }, 77 78 _callLoadedEventCallbacks:function(){ 79 var locListeners = this._eventListeners; 80 for(var i = 0, len = locListeners.length; i < len; i++){ 81 var selCallback = locListeners[i]; 82 selCallback.eventCallback.call(selCallback.eventTarget, this); 83 } 84 locListeners.length = 0; 85 }, 86 87 /** 88 * @return {cc.Rect} 89 */ 90 getRectInPixels:function () { 91 var locRectInPixels = this._rectInPixels; 92 return cc.rect(locRectInPixels.x, locRectInPixels.y, locRectInPixels.width, locRectInPixels.height); 93 }, 94 95 /** 96 * @param {cc.Rect} rectInPixels 97 */ 98 setRectInPixels:function (rectInPixels) { 99 this._rectInPixels.x = rectInPixels.x; 100 this._rectInPixels.y = rectInPixels.y; 101 this._rectInPixels.width = rectInPixels.width; 102 this._rectInPixels.height = rectInPixels.height; 103 this._rect = cc.RECT_PIXELS_TO_POINTS(rectInPixels); 104 }, 105 106 /** 107 * <p> 108 * return is rotated of SpriteFrame. <br/> 109 * </p> 110 * @return {Boolean} 111 */ 112 isRotated:function () { 113 return this._rotated; 114 }, 115 116 /** 117 * set SpriteFrame is rotated 118 * @param {Boolean} bRotated 119 */ 120 setRotated:function (bRotated) { 121 this._rotated = bRotated; 122 }, 123 124 /** 125 * get rect of the frame 126 * @return {cc.Rect} 127 */ 128 getRect:function () { 129 var locRect = this._rect; 130 return cc.rect(locRect.x, locRect.y, locRect.width, locRect.height); 131 }, 132 133 /** 134 * set rect of the frame 135 * @param {cc.Rect} rect 136 */ 137 setRect:function (rect) { 138 this._rect.x = rect.x; 139 this._rect.y = rect.y; 140 this._rect.width = rect.width; 141 this._rect.height = rect.height; 142 this._rectInPixels = cc.RECT_POINTS_TO_PIXELS(this._rect); 143 }, 144 145 /** 146 * get offset of the frame 147 * @return {cc.Point} 148 */ 149 getOffsetInPixels:function () { 150 return cc.p(this._offsetInPixels.x, this._offsetInPixels.y); 151 }, 152 153 /** 154 * set offset of the frame 155 * @param {cc.Point} offsetInPixels 156 */ 157 setOffsetInPixels:function (offsetInPixels) { 158 this._offsetInPixels.x = offsetInPixels.x; 159 this._offsetInPixels.y = offsetInPixels.y; 160 this._offset = cc.POINT_PIXELS_TO_POINTS(this._offsetInPixels); 161 }, 162 163 /** 164 * get original size of the trimmed image 165 * @const 166 * @return {cc.Size} 167 */ 168 getOriginalSizeInPixels:function () { 169 return cc.size(this._originalSizeInPixels.width, this._originalSizeInPixels.height); 170 }, 171 172 /** 173 * set original size of the trimmed image 174 * @param {cc.Size} sizeInPixels 175 */ 176 setOriginalSizeInPixels:function (sizeInPixels) { 177 this._originalSizeInPixels.width = sizeInPixels.width; 178 this._originalSizeInPixels.height = sizeInPixels.height; 179 }, 180 181 /** 182 * get original size of the trimmed image 183 * @const 184 * @return {cc.Size} 185 */ 186 getOriginalSize:function () { 187 return cc.size(this._originalSize.width, this._originalSize.height); 188 }, 189 190 /** 191 * set original size of the trimmed image 192 * @param {cc.Size} sizeInPixels 193 */ 194 setOriginalSize:function (sizeInPixels) { 195 this._originalSize.width = sizeInPixels.width; 196 this._originalSize.height = sizeInPixels.height; 197 }, 198 199 /** 200 * get texture of the frame 201 * @return {cc.Texture2D} 202 */ 203 getTexture:function () { 204 if (this._texture) 205 return this._texture; 206 if (this._textureFilename !== "") { 207 var locTexture = cc.TextureCache.getInstance().addImage(this._textureFilename); 208 if (locTexture) 209 this._textureLoaded = locTexture.isLoaded(); 210 return locTexture; 211 } 212 return null; 213 }, 214 215 /** 216 * set texture of the frame, the texture is retained 217 * @param {cc.Texture2D} texture 218 */ 219 setTexture:function (texture) { 220 if (this._texture != texture) { 221 var locLoaded = texture.isLoaded(); 222 this._textureLoaded = locLoaded; 223 this._texture = texture; 224 if(!locLoaded){ 225 texture.addLoadedEventListener(function(sender){ 226 this._textureLoaded = true; 227 if(this._rotated){ 228 var tempElement = sender.getHtmlElementObj(); 229 tempElement = cc.cutRotateImageToCanvas(tempElement, this.getRect()); 230 var tempTexture = new cc.Texture2D(); 231 tempTexture.initWithElement(tempElement); 232 tempTexture.handleLoadedTexture(); 233 this.setTexture(tempTexture); 234 235 var rect = this.getRect(); 236 this.setRect(cc.rect(0, 0, rect.width, rect.height)); 237 } 238 var locRect = this._rect; 239 if(locRect.width === 0 && locRect.height === 0){ 240 var locContentSize = sender.getContentSize(); 241 this._rect.width = locContentSize.width; 242 this._rect.height = locContentSize.height; 243 this._rectInPixels = cc.RECT_POINTS_TO_PIXELS(this._rect); 244 this._originalSizeInPixels.width = this._rectInPixels.width; 245 this._originalSizeInPixels.height = this._rectInPixels.height; 246 this._originalSize.width = locContentSize.width; 247 this._originalSize.height = locContentSize.height; 248 } 249 this._callLoadedEventCallbacks(); 250 }, this); 251 } 252 } 253 }, 254 255 /** 256 * Offset getter 257 * @const 258 * @return {cc.Point} 259 */ 260 getOffset:function () { 261 return cc.p(this._offset.x, this._offset.y); 262 }, 263 264 /** 265 * offset setter 266 * @param {cc.Point} offsets 267 */ 268 setOffset:function (offsets) { 269 this._offset.x = offsets.x; 270 this._offset.y = offsets.y; 271 }, 272 273 clone: function(){ 274 var frame = new cc.SpriteFrame(); 275 frame.initWithTextureFilename(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels); 276 frame.setTexture(this._texture); 277 return frame; 278 }, 279 280 /** 281 * copy a new SpriteFrame 282 * @return {cc.SpriteFrame} 283 */ 284 copyWithZone:function () { 285 var copy = new cc.SpriteFrame(); 286 copy.initWithTextureFilename(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels); 287 copy.setTexture(this._texture); 288 return copy; 289 }, 290 291 copy:function () { 292 return this.copyWithZone(); 293 }, 294 295 /** 296 * Initializes SpriteFrame with Texture, rect, rotated, offset and originalSize in pixels. 297 * @param {cc.Texture2D} texture 298 * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels 299 * @param {Boolean} [rotated=false] 300 * @param {cc.Point} [offset=cc.size(0,0)] 301 * @param {cc.Size} [originalSize=rect.size] 302 * @return {Boolean} 303 */ 304 initWithTexture:function (texture, rect, rotated, offset, originalSize) { 305 if(arguments.length === 2) 306 rect = cc.RECT_POINTS_TO_PIXELS(rect); 307 308 offset = offset || cc.size(0, 0); 309 originalSize = originalSize || rect.size; 310 311 this.setTexture(texture); 312 this._rectInPixels = rect; 313 this._rect = cc.RECT_PIXELS_TO_POINTS(rect); 314 this._offsetInPixels = offset; 315 this._offset = cc.POINT_PIXELS_TO_POINTS(offset); 316 this._originalSizeInPixels = originalSize; 317 this._originalSize = cc.SIZE_PIXELS_TO_POINTS(originalSize); 318 this._rotated = rotated || false; 319 return true; 320 }, 321 322 /** 323 * <p> 324 * Initializes a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.<br/> 325 * The originalSize is the size in pixels of the frame before being trimmed. 326 * </p> 327 * @param {string} filename 328 * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels 329 * @param {Boolean} rotated 330 * @param {cc.Point} [offset=cc.size(0,0)] 331 * @param {cc.Size} [originalSize=rect.size] 332 */ 333 initWithTextureFilename:function (filename, rect, rotated, offset, originalSize) { 334 if(arguments.length === 2) 335 rect = cc.RECT_POINTS_TO_PIXELS(rect); 336 337 offset = offset || cc.size(0, 0); 338 originalSize = originalSize || rect.size; 339 340 this._texture = null; 341 this._textureFilename = filename; 342 this._rectInPixels = rect; 343 this._rect = cc.RECT_PIXELS_TO_POINTS(rect); 344 this._rotated = rotated || false; 345 this._offsetInPixels = offset; 346 this._offset = cc.POINT_PIXELS_TO_POINTS(offset); 347 this._originalSizeInPixels = originalSize; 348 this._originalSize = cc.SIZE_PIXELS_TO_POINTS(originalSize); 349 350 return true; 351 } 352 }); 353 354 /** 355 * <p> 356 * Create a cc.SpriteFrame with a texture filename, rect, rotated, offset and originalSize in pixels.<br/> 357 * The originalSize is the size in pixels of the frame before being trimmed. 358 * </p> 359 * @param {string} filename 360 * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels 361 * @param {Boolean} rotated 362 * @param {cc.Point} offset 363 * @param {cc.Size} originalSize 364 * @return {cc.SpriteFrame} 365 */ 366 cc.SpriteFrame.create = function (filename, rect, rotated, offset, originalSize) { 367 var spriteFrame = new cc.SpriteFrame(); 368 switch (arguments.length) { 369 case 2: 370 spriteFrame.initWithTextureFilename(filename, rect); 371 break; 372 case 5: 373 spriteFrame.initWithTextureFilename(filename, rect, rotated, offset, originalSize); 374 break; 375 default: 376 throw "Argument must be non-nil "; 377 break; 378 } 379 return spriteFrame; 380 }; 381 382 /** 383 * Create a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels. 384 * @param {cc.Texture2D} texture 385 * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels 386 * @param {Boolean} [rotated=] 387 * @param {cc.Point} [offset=] 388 * @param {cc.Size} [originalSize=] 389 * @return {cc.SpriteFrame} 390 * @example 391 * //Create a cc.SpriteFrame with a texture, rect in texture. 392 * var frame1 = cc.SpriteFrame.createWithTexture("grossini_dance.png",cc.rect(0,0,90,128)); 393 * 394 * //Create a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels. 395 * var frame2 = cc.SpriteFrame.createWithTexture(texture, frameRect, rotated, offset, sourceSize); 396 */ 397 cc.SpriteFrame.createWithTexture = function (texture, rect, rotated, offset, originalSize) { 398 var spriteFrame = new cc.SpriteFrame(); 399 switch (arguments.length) { 400 case 2: 401 spriteFrame.initWithTexture(texture, rect); 402 break; 403 case 5: 404 spriteFrame.initWithTexture(texture, rect, rotated, offset, originalSize); 405 break; 406 default: 407 throw "Argument must be non-nil "; 408 break; 409 } 410 return spriteFrame; 411 }; 412 413 cc.SpriteFrame._frameWithTextureForCanvas = function (texture, rect, rotated, offset, originalSize) { 414 var spriteFrame = new cc.SpriteFrame(); 415 spriteFrame._texture = texture; 416 spriteFrame._rectInPixels = rect; 417 spriteFrame._rect = cc.RECT_PIXELS_TO_POINTS(rect); 418 spriteFrame._offsetInPixels = offset; 419 spriteFrame._offset = cc.POINT_PIXELS_TO_POINTS(spriteFrame._offsetInPixels); 420 spriteFrame._originalSizeInPixels = originalSize; 421 spriteFrame._originalSize = cc.SIZE_PIXELS_TO_POINTS(spriteFrame._originalSizeInPixels); 422 spriteFrame._rotated = rotated; 423 return spriteFrame; 424 }; 425