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 return this._rectInPixels; 92 }, 93 94 /** 95 * @param {cc.Rect} rectInPixels 96 */ 97 setRectInPixels:function (rectInPixels) { 98 this._rectInPixels = rectInPixels; 99 this._rect = cc.RECT_PIXELS_TO_POINTS(rectInPixels); 100 }, 101 102 /** 103 * <p> 104 * return is rotated of SpriteFrame. <br/> 105 * </p> 106 * @return {Boolean} 107 */ 108 isRotated:function () { 109 return this._rotated; 110 }, 111 112 /** 113 * set SpriteFrame is rotated 114 * @param {Boolean} bRotated 115 */ 116 setRotated:function (bRotated) { 117 this._rotated = bRotated; 118 }, 119 120 /** 121 * get rect of the frame 122 * @return {cc.Rect} 123 */ 124 getRect:function () { 125 return this._rect; 126 }, 127 128 /** 129 * set rect of the frame 130 * @param {cc.Rect} rect 131 */ 132 setRect:function (rect) { 133 this._rect = rect; 134 this._rectInPixels = cc.RECT_POINTS_TO_PIXELS(this._rect); 135 }, 136 137 /** 138 * get offset of the frame 139 * @return {cc.Point} 140 */ 141 getOffsetInPixels:function () { 142 return cc.p(this._offsetInPixels.x, this._offsetInPixels.y); 143 }, 144 145 /** 146 * set offset of the frame 147 * @param {cc.Point} offsetInPixels 148 */ 149 setOffsetInPixels:function (offsetInPixels) { 150 this._offsetInPixels = offsetInPixels; 151 this._offset = cc.POINT_PIXELS_TO_POINTS(this._offsetInPixels); 152 }, 153 154 /** 155 * get original size of the trimmed image 156 * @const 157 * @return {cc.Size} 158 */ 159 getOriginalSizeInPixels:function () { 160 return this._originalSizeInPixels; 161 }, 162 163 /** 164 * set original size of the trimmed image 165 * @param {cc.Size} sizeInPixels 166 */ 167 setOriginalSizeInPixels:function (sizeInPixels) { 168 this._originalSizeInPixels = sizeInPixels; 169 }, 170 171 /** 172 * get original size of the trimmed image 173 * @const 174 * @return {cc.Size} 175 */ 176 getOriginalSize:function () { 177 return cc.size(this._originalSize.width, this._originalSize.height); 178 }, 179 180 /** 181 * set original size of the trimmed image 182 * @param {cc.Size} sizeInPixels 183 */ 184 setOriginalSize:function (sizeInPixels) { 185 this._originalSize = sizeInPixels; 186 }, 187 188 /** 189 * get texture of the frame 190 * @return {cc.Texture2D} 191 */ 192 getTexture:function () { 193 if (this._texture) 194 return this._texture; 195 if (this._textureFilename !== "") { 196 var locTexture = cc.TextureCache.getInstance().addImage(this._textureFilename); 197 if (locTexture) 198 this._textureLoaded = locTexture.isLoaded(); 199 return locTexture; 200 } 201 return null; 202 }, 203 204 /** 205 * set texture of the frame, the texture is retained 206 * @param {cc.Texture2D} texture 207 */ 208 setTexture:function (texture) { 209 if (this._texture != texture) { 210 var locLoaded = texture.isLoaded(); 211 this._textureLoaded = locLoaded; 212 this._texture = texture; 213 if(!locLoaded){ 214 texture.addLoadedEventListener(function(sender){ 215 this._textureLoaded = true; 216 if(this._rotated){ 217 var tempElement = sender.getHtmlElementObj(); 218 tempElement = cc.cutRotateImageToCanvas(tempElement, this.getRect()); 219 var tempTexture = new cc.Texture2D(); 220 tempTexture.initWithElement(tempElement); 221 tempTexture.handleLoadedTexture(); 222 this.setTexture(tempTexture); 223 224 var rect = this.getRect(); 225 this.setRect(cc.rect(0, 0, rect.width, rect.height)); 226 } 227 var locRect = this._rect; 228 if(locRect.width === 0 && locRect.height === 0){ 229 var locContentSize = sender.getContentSize(); 230 this._rect.width = locContentSize.width; 231 this._rect.height = locContentSize.height; 232 this._rectInPixels = cc.RECT_POINTS_TO_PIXELS(this._rect); 233 this._originalSizeInPixels.width = this._rectInPixels.width; 234 this._originalSizeInPixels.height = this._rectInPixels.height; 235 this._originalSize.width = locContentSize.width; 236 this._originalSize.height = locContentSize.height; 237 } 238 this._callLoadedEventCallbacks(); 239 }, this); 240 } 241 } 242 }, 243 244 /** 245 * Offset getter 246 * @const 247 * @return {cc.Point} 248 */ 249 getOffset:function () { 250 return cc.p(this._offset.x, this._offset.y); 251 }, 252 253 /** 254 * offset setter 255 * @param {cc.Point} offsets 256 */ 257 setOffset:function (offsets) { 258 this._offset.x = offsets.x; 259 this._offset.y = offsets.y; 260 }, 261 262 clone: function(){ 263 var frame = new cc.SpriteFrame(); 264 frame.initWithTextureFilename(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels); 265 frame.setTexture(this._texture); 266 return frame; 267 }, 268 269 /** 270 * copy a new SpriteFrame 271 * @return {cc.SpriteFrame} 272 */ 273 copyWithZone:function () { 274 var copy = new cc.SpriteFrame(); 275 copy.initWithTextureFilename(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels); 276 copy.setTexture(this._texture); 277 return copy; 278 }, 279 280 copy:function () { 281 return this.copyWithZone(); 282 }, 283 284 /** 285 * Initializes SpriteFrame with Texture, rect, rotated, offset and originalSize in pixels. 286 * @param {cc.Texture2D|HTMLImageElement} texture 287 * @param {cc.Rect} rect 288 * @param {Boolean} [rotated=false] 289 * @param {cc.Point} [offset=cc.size(0,0)] 290 * @param {cc.Size} [originalSize=rect.size] 291 * @return {Boolean} 292 */ 293 initWithTexture:function (texture, rect, rotated, offset, originalSize) { 294 rotated = rotated || false; 295 offset = offset || cc.size(0, 0); 296 originalSize = originalSize || rect.size; 297 298 this.setTexture(texture); 299 this._rectInPixels = rect; 300 this._rect = cc.RECT_PIXELS_TO_POINTS(rect); 301 this._offsetInPixels = offset; 302 this._offset = cc.POINT_PIXELS_TO_POINTS(offset); 303 this._originalSizeInPixels = originalSize; 304 this._originalSize = cc.SIZE_PIXELS_TO_POINTS(originalSize); 305 this._rotated = rotated; 306 return true; 307 }, 308 309 /** 310 * <p> 311 * Initializes a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.<br/> 312 * The originalSize is the size in pixels of the frame before being trimmed. 313 * </p> 314 * @param {string} filename 315 * @param {cc.Rect} rect 316 * @param {Boolean} rotated 317 * @param {cc.Point} [offset=cc.size(0,0)] 318 * @param {cc.Size} [originalSize=rect.size] 319 */ 320 initWithTextureFilename:function (filename, rect, rotated, offset, originalSize) { 321 offset = offset || cc.size(0, 0); 322 originalSize = originalSize || rect.size; 323 324 this._texture = null; 325 this._textureFilename = filename; 326 this._rectInPixels = rect; 327 this._rect = cc.RECT_PIXELS_TO_POINTS(rect); 328 this._rotated = rotated || false; 329 this._offsetInPixels = offset; 330 this._offset = cc.POINT_PIXELS_TO_POINTS(offset); 331 this._originalSizeInPixels = originalSize; 332 this._originalSize = cc.SIZE_PIXELS_TO_POINTS(originalSize); 333 334 return true; 335 } 336 }); 337 338 /** 339 * <p> 340 * Create a cc.SpriteFrame with a texture filename, rect, rotated, offset and originalSize in pixels.<br/> 341 * The originalSize is the size in pixels of the frame before being trimmed. 342 * </p> 343 * @param {string} filename 344 * @param {cc.Rect} rect 345 * @param {Boolean} rotated 346 * @param {cc.Point} offset 347 * @param {cc.Size} originalSize 348 * @return {cc.SpriteFrame} 349 */ 350 cc.SpriteFrame.create = function (filename, rect, rotated, offset, originalSize) { 351 var spriteFrame = new cc.SpriteFrame(); 352 switch (arguments.length) { 353 case 2: 354 spriteFrame.initWithTextureFilename(filename, rect); 355 break; 356 case 5: 357 spriteFrame.initWithTextureFilename(filename, rect, rotated, offset, originalSize); 358 break; 359 default: 360 throw "Argument must be non-nil "; 361 break; 362 } 363 return spriteFrame; 364 }; 365 366 /** 367 * Create a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels. 368 * @param {cc.Texture2D} texture 369 * @param {cc.Rect} rect 370 * @param {Boolean} [rotated=] 371 * @param {cc.Point} [offset=] 372 * @param {cc.Size} [originalSize=] 373 * @return {cc.SpriteFrame} 374 * @example 375 * //Create a cc.SpriteFrame with a texture, rect in texture. 376 * var frame1 = cc.SpriteFrame.createWithTexture("grossini_dance.png",cc.rect(0,0,90,128)); 377 * 378 * //Create a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels. 379 * var frame2 = cc.SpriteFrame.createWithTexture(texture, frameRect, rotated, offset, sourceSize); 380 */ 381 cc.SpriteFrame.createWithTexture = function (texture, rect, rotated, offset, originalSize) { 382 var spriteFrame = new cc.SpriteFrame(); 383 spriteFrame.initWithTexture(texture, rect, rotated, offset, originalSize); 384 return spriteFrame; 385 }; 386 387 cc.SpriteFrame._frameWithTextureForCanvas = function (texture, rect, rotated, offset, originalSize) { 388 var spriteFrame = new cc.SpriteFrame(); 389 spriteFrame._texture = texture; 390 spriteFrame._rectInPixels = rect; 391 spriteFrame._rect = cc.RECT_PIXELS_TO_POINTS(rect); 392 spriteFrame._offsetInPixels = offset; 393 spriteFrame._offset = cc.POINT_PIXELS_TO_POINTS(spriteFrame._offsetInPixels); 394 spriteFrame._originalSizeInPixels = originalSize; 395 spriteFrame._originalSize = cc.SIZE_PIXELS_TO_POINTS(spriteFrame._originalSizeInPixels); 396 spriteFrame._rotated = rotated; 397 return spriteFrame; 398 }; 399