CCSpriteFrame.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /****************************************************************************
  2. Copyright (c) 2010-2012 cocos2d-x.org
  3. Copyright (c) 2008-2010 Ricardo Quesada
  4. Copyright (c) 2011 Zynga Inc.
  5. http://www.cocos2d-x.org
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. ****************************************************************************/
  22. /**
  23. * <p>
  24. * A cc.SpriteFrame has:<br/>
  25. * - texture: A cc.Texture2D that will be used by the cc.Sprite<br/>
  26. * - rectangle: A rectangle of the texture<br/>
  27. * <br/>
  28. * You can modify the frame of a cc.Sprite by doing:<br/>
  29. * </p>
  30. * @class
  31. * @extends cc.Class
  32. *
  33. * @example
  34. * var texture = cc.TextureCache.getInstance().addImage(s_dragon_animation);
  35. * var frame0 = cc.SpriteFrame.createWithTexture(texture, cc.rect(132 * 0, 132 * 0, 132, 132));
  36. */
  37. cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
  38. _offset:null,
  39. _originalSize:null,
  40. _rectInPixels:null,
  41. _rotated:false,
  42. _rect:null,
  43. _offsetInPixels:null,
  44. _originalSizeInPixels:null,
  45. _texture:null,
  46. _textureFilename:"",
  47. _textureLoaded:false,
  48. _eventListeners:null,
  49. ctor:function () {
  50. this._offset = cc.p(0, 0);
  51. this._offsetInPixels = cc.p(0, 0);
  52. this._originalSize = cc.size(0, 0);
  53. this._rotated = false;
  54. this._originalSizeInPixels = cc.size(0, 0);
  55. this._textureFilename = "";
  56. this._texture = null;
  57. this._textureLoaded = false;
  58. },
  59. // attributes
  60. textureLoaded:function(){
  61. return this._textureLoaded;
  62. },
  63. addLoadedEventListener:function(callback, target){
  64. if (this._eventListeners == null){
  65. this._eventListeners = [];
  66. }
  67. this._eventListeners.push({eventCallback:callback, eventTarget:target});
  68. },
  69. _callLoadedEventCallbacks:function(){
  70. var locListeners = this._eventListeners;
  71. if (!locListeners) return;
  72. for(var i = 0, len = locListeners.length; i < len; i++){
  73. var selCallback = locListeners[i];
  74. cc.doCallback(selCallback.eventCallback, selCallback.eventTarget, this);
  75. }
  76. locListeners.length = 0;
  77. },
  78. /**
  79. * @return {cc.Rect}
  80. */
  81. getRectInPixels:function () {
  82. var locRectInPixels = this._rectInPixels;
  83. return cc.rect(locRectInPixels.x, locRectInPixels.y, locRectInPixels.width, locRectInPixels.height);
  84. },
  85. /**
  86. * @param {cc.Rect} rectInPixels
  87. */
  88. setRectInPixels:function (rectInPixels) {
  89. if (!this._rectInPixels){
  90. this._rectInPixels = cc.rect(0,0,0,0);
  91. }
  92. this._rectInPixels.x = rectInPixels.x;
  93. this._rectInPixels.y = rectInPixels.y;
  94. this._rectInPixels.width = rectInPixels.width;
  95. this._rectInPixels.height = rectInPixels.height;
  96. this._rect = cc.RECT_PIXELS_TO_POINTS(rectInPixels);
  97. },
  98. /**
  99. * <p>
  100. * return is rotated of SpriteFrame. <br/>
  101. * </p>
  102. * @return {Boolean}
  103. */
  104. isRotated:function () {
  105. return this._rotated;
  106. },
  107. /**
  108. * set SpriteFrame is rotated
  109. * @param {Boolean} bRotated
  110. */
  111. setRotated:function (bRotated) {
  112. this._rotated = bRotated;
  113. },
  114. /**
  115. * get rect of the frame
  116. * @return {cc.Rect}
  117. */
  118. getRect:function () {
  119. var locRect = this._rect;
  120. return cc.rect(locRect.x, locRect.y, locRect.width, locRect.height);
  121. },
  122. /**
  123. * set rect of the frame
  124. * @param {cc.Rect} rect
  125. */
  126. setRect:function (rect) {
  127. if (!this._rect){
  128. this._rect = cc.rect(0,0,0,0);
  129. }
  130. this._rect.x = rect.x;
  131. this._rect.y = rect.y;
  132. this._rect.width = rect.width;
  133. this._rect.height = rect.height;
  134. this._rectInPixels = cc.RECT_POINTS_TO_PIXELS(this._rect);
  135. },
  136. /**
  137. * get offset of the frame
  138. * @return {cc.Point}
  139. */
  140. getOffsetInPixels:function () {
  141. return cc.p(this._offsetInPixels);
  142. },
  143. /**
  144. * set offset of the frame
  145. * @param {cc.Point} offsetInPixels
  146. */
  147. setOffsetInPixels:function (offsetInPixels) {
  148. this._offsetInPixels.x = offsetInPixels.x;
  149. this._offsetInPixels.y = offsetInPixels.y;
  150. this._offset = cc.POINT_PIXELS_TO_POINTS(this._offsetInPixels);
  151. },
  152. /**
  153. * get original size of the trimmed image
  154. * @const
  155. * @return {cc.Size}
  156. */
  157. getOriginalSizeInPixels:function () {
  158. return cc.size(this._originalSizeInPixels);
  159. },
  160. /**
  161. * set original size of the trimmed image
  162. * @param {cc.Size} sizeInPixels
  163. */
  164. setOriginalSizeInPixels:function (sizeInPixels) {
  165. this._originalSizeInPixels.width = sizeInPixels.width;
  166. this._originalSizeInPixels.height = sizeInPixels.height;
  167. },
  168. /**
  169. * get original size of the trimmed image
  170. * @const
  171. * @return {cc.Size}
  172. */
  173. getOriginalSize:function () {
  174. return cc.size(this._originalSize);
  175. },
  176. /**
  177. * set original size of the trimmed image
  178. * @param {cc.Size} sizeInPixels
  179. */
  180. setOriginalSize:function (sizeInPixels) {
  181. this._originalSize.width = sizeInPixels.width;
  182. this._originalSize.height = sizeInPixels.height;
  183. },
  184. /**
  185. * get texture of the frame
  186. * @return {cc.Texture2D}
  187. */
  188. getTexture:function () {
  189. if (this._texture)
  190. return this._texture;
  191. if (this._textureFilename !== "") {
  192. var locTexture = cc.TextureCache.getInstance().addImage(this._textureFilename);
  193. if (locTexture)
  194. this._textureLoaded = locTexture.isLoaded();
  195. return locTexture;
  196. }
  197. return null;
  198. },
  199. /**
  200. * set texture of the frame, the texture is retained
  201. * @param {cc.Texture2D} texture
  202. */
  203. setTexture:function (texture) {
  204. if (this._texture != texture) {
  205. var locLoaded = texture.isLoaded();
  206. this._textureLoaded = locLoaded;
  207. this._texture = texture;
  208. if(!locLoaded){
  209. texture.addLoadedEventListener(function(sender){
  210. this._textureLoaded = true;
  211. if(this._rotated && cc.renderContextType === cc.CANVAS){
  212. var tempElement = sender.getHtmlElementObj();
  213. tempElement = cc.cutRotateImageToCanvas(tempElement, this.getRect());
  214. var tempTexture = new cc.Texture2D();
  215. tempTexture.initWithElement(tempElement);
  216. tempTexture.handleLoadedTexture();
  217. this.setTexture(tempTexture);
  218. var rect = this.getRect();
  219. this.setRect(cc.rect(0, 0, rect.width, rect.height));
  220. }
  221. var locRect = this._rect;
  222. if(locRect.width === 0 && locRect.height === 0){
  223. var locContentSize = sender.getContentSize();
  224. this._rect.width = locContentSize.width;
  225. this._rect.height = locContentSize.height;
  226. this._rectInPixels = cc.RECT_POINTS_TO_PIXELS(this._rect);
  227. this._originalSizeInPixels.width = this._rectInPixels.width;
  228. this._originalSizeInPixels.height = this._rectInPixels.height;
  229. this._originalSize.width = locContentSize.width;
  230. this._originalSize.height = locContentSize.height;
  231. }
  232. this._callLoadedEventCallbacks();
  233. }, this);
  234. }
  235. }
  236. },
  237. /**
  238. * Offset getter
  239. * @const
  240. * @return {cc.Point}
  241. */
  242. getOffset:function () {
  243. return cc.p(this._offset);
  244. },
  245. /**
  246. * offset setter
  247. * @param {cc.Point} offsets
  248. */
  249. setOffset:function (offsets) {
  250. this._offset.x = offsets.x;
  251. this._offset.y = offsets.y;
  252. },
  253. clone: function(){
  254. var frame = new cc.SpriteFrame();
  255. frame.initWithTextureFilename(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels);
  256. frame.setTexture(this._texture);
  257. return frame;
  258. },
  259. /**
  260. * copy a new SpriteFrame
  261. * @return {cc.SpriteFrame}
  262. */
  263. copyWithZone:function () {
  264. var copy = new cc.SpriteFrame();
  265. copy.initWithTextureFilename(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels);
  266. copy.setTexture(this._texture);
  267. return copy;
  268. },
  269. copy:function () {
  270. return this.copyWithZone();
  271. },
  272. /**
  273. * Initializes SpriteFrame with Texture, rect, rotated, offset and originalSize in pixels.
  274. * @param {cc.Texture2D} texture
  275. * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels
  276. * @param {Boolean} [rotated=false]
  277. * @param {cc.Point} [offset=cc.p(0,0)]
  278. * @param {cc.Size} [originalSize=rect.size]
  279. * @return {Boolean}
  280. */
  281. initWithTexture:function (texture, rect, rotated, offset, originalSize) {
  282. if(arguments.length === 2)
  283. rect = cc.RECT_POINTS_TO_PIXELS(rect);
  284. offset = offset || cc.p(0, 0);
  285. originalSize = originalSize || rect._size;
  286. this.setTexture(texture);
  287. this._rectInPixels = rect;
  288. this._rect = cc.RECT_PIXELS_TO_POINTS(rect);
  289. this._offsetInPixels.x = offset.x;
  290. this._offsetInPixels.y = offset.y;
  291. this._offset = cc.POINT_PIXELS_TO_POINTS(offset);
  292. this._originalSizeInPixels.width = originalSize.width;
  293. this._originalSizeInPixels.height = originalSize.height;
  294. this._originalSize = cc.SIZE_PIXELS_TO_POINTS(originalSize);
  295. this._rotated = rotated || false;
  296. return true;
  297. },
  298. /**
  299. * <p>
  300. * Initializes a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.<br/>
  301. * The originalSize is the size in pixels of the frame before being trimmed.
  302. * </p>
  303. * @param {string} filename
  304. * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels
  305. * @param {Boolean} rotated
  306. * @param {cc.Point} [offset=cc.p(0,0)]
  307. * @param {cc.Size} [originalSize=rect.size]
  308. */
  309. initWithTextureFilename:function (filename, rect, rotated, offset, originalSize) {
  310. if(arguments.length === 2)
  311. rect = cc.RECT_POINTS_TO_PIXELS(rect);
  312. offset = offset || cc.p(0, 0);
  313. originalSize = originalSize || rect._size;
  314. this._texture = null;
  315. this._textureFilename = filename;
  316. this._rectInPixels = rect;
  317. this._rect = cc.RECT_PIXELS_TO_POINTS(rect);
  318. this._rotated = rotated || false;
  319. this._offsetInPixels.x = offset.x;
  320. this._offsetInPixels.y = offset.y;
  321. this._offset = cc.POINT_PIXELS_TO_POINTS(offset);
  322. this._originalSizeInPixels.width = originalSize.width;
  323. this._originalSizeInPixels.height = originalSize.height;
  324. this._originalSize = cc.SIZE_PIXELS_TO_POINTS(originalSize);
  325. return true;
  326. }
  327. });
  328. /**
  329. * <p>
  330. * Create a cc.SpriteFrame with a texture filename, rect, rotated, offset and originalSize in pixels.<br/>
  331. * The originalSize is the size in pixels of the frame before being trimmed.
  332. * </p>
  333. * @param {string} filename
  334. * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels
  335. * @param {Boolean} rotated
  336. * @param {cc.Point} offset
  337. * @param {cc.Size} originalSize
  338. * @return {cc.SpriteFrame}
  339. */
  340. cc.SpriteFrame.create = function (filename, rect, rotated, offset, originalSize) {
  341. var spriteFrame = new cc.SpriteFrame();
  342. switch (arguments.length) {
  343. case 2:
  344. spriteFrame.initWithTextureFilename(filename, rect);
  345. break;
  346. case 5:
  347. spriteFrame.initWithTextureFilename(filename, rect, rotated, offset, originalSize);
  348. break;
  349. default:
  350. throw "Argument must be non-nil ";
  351. break;
  352. }
  353. return spriteFrame;
  354. };
  355. /**
  356. * Create a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.
  357. * @param {cc.Texture2D} texture
  358. * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels
  359. * @param {Boolean} [rotated=]
  360. * @param {cc.Point} [offset=]
  361. * @param {cc.Size} [originalSize=]
  362. * @return {cc.SpriteFrame}
  363. * @example
  364. * //Create a cc.SpriteFrame with a texture, rect in texture.
  365. * var frame1 = cc.SpriteFrame.createWithTexture("grossini_dance.png",cc.rect(0,0,90,128));
  366. *
  367. * //Create a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.
  368. * var frame2 = cc.SpriteFrame.createWithTexture(texture, frameRect, rotated, offset, sourceSize);
  369. */
  370. cc.SpriteFrame.createWithTexture = function (texture, rect, rotated, offset, originalSize) {
  371. var spriteFrame = new cc.SpriteFrame();
  372. switch (arguments.length) {
  373. case 2:
  374. spriteFrame.initWithTexture(texture, rect);
  375. break;
  376. case 5:
  377. spriteFrame.initWithTexture(texture, rect, rotated, offset, originalSize);
  378. break;
  379. default:
  380. throw "Argument must be non-nil ";
  381. break;
  382. }
  383. return spriteFrame;
  384. };
  385. cc.SpriteFrame._frameWithTextureForCanvas = function (texture, rect, rotated, offset, originalSize) {
  386. var spriteFrame = new cc.SpriteFrame();
  387. spriteFrame._texture = texture;
  388. spriteFrame._rectInPixels = rect;
  389. spriteFrame._rect = cc.RECT_PIXELS_TO_POINTS(rect);
  390. spriteFrame._offsetInPixels.x = offset.x;
  391. spriteFrame._offsetInPixels.y = offset.y;
  392. spriteFrame._offset = cc.POINT_PIXELS_TO_POINTS(spriteFrame._offsetInPixels);
  393. spriteFrame._originalSizeInPixels.width = originalSize.width;
  394. spriteFrame._originalSizeInPixels.height = originalSize.height;
  395. spriteFrame._originalSize = cc.SIZE_PIXELS_TO_POINTS(spriteFrame._originalSizeInPixels);
  396. spriteFrame._rotated = rotated;
  397. return spriteFrame;
  398. };