1 
  2 /**
  3  * @class TextureAtlas纹理集是将许多小的纹理图片整合到一起的一张大图。这个类可根据一个纹理集数据读取纹理小图、精灵动画等。
  4  * @param {Image} image 纹理集图片。
  5  * @param {Array} frameData 纹理集帧数据。每帧的数据格式为:[x, y, width, height]。
  6  * @param {Object} spriteData 纹理集精灵数据。
  7  * @module hilo/util/TextureAtlas
  8  * @require hilo/core/Class
  9  */
 10 var TextureAtlas = (function(){
 11 
 12 return Class.create(/** @lends TextureAtlas.prototype */{
 13     constructor: function TextureAtlas(image, frameData, spriteData){
 14         var result = parseAtlasData(image, frameData, spriteData);
 15         this._frames = result.frames;
 16         this._sprites = result.sprites;
 17     },
 18 
 19     _frames: null,
 20     _sprites: null,
 21 
 22     /**
 23      * 获取指定索引位置index的帧数据。
 24      * @param {Int} index 要获取帧的索引位置。
 25      * @returns {Object} 帧数据。
 26      */
 27     getFrame: function(index){
 28         var frames = this._frames;
 29         return frames && frames[index];
 30     },
 31 
 32     /**
 33      * 获取指定id的精灵数据。
 34      * @param {String} id 要获取精灵的id。
 35      * @returns {Object} 精灵数据。
 36      */
 37     getSprite: function(id){
 38         var sprites = this._sprites;
 39         return sprites && sprites[id];
 40     }
 41 });
 42 
 43 /**
 44  * 解析纹理集帧和精灵数据。
 45  * @private
 46  */
 47 function parseAtlasData(image, frameData, spriteData){
 48     if(frameData === undefined){
 49         var data = image;
 50         image = data.image;
 51         frameData = data.frames;
 52         spriteData = data.sprites;
 53     }
 54 
 55     //frames
 56     if(frameData){
 57         var frames = [], frame, obj;
 58 
 59         for(var i = 0, len = frameData.length; i < len; i++){
 60             obj = frameData[i];
 61             frame = {
 62                 image: image,
 63                 rect: [obj[0], obj[1], obj[2], obj[3]],
 64                 pivotX: obj[4] || 0,
 65                 pivotY: obj[5] || 0
 66             };
 67             frames[i] = frame;
 68         }
 69     }
 70 
 71     //sprite frames
 72     if(spriteData){
 73         var sprites = {}, sprite, spriteFrames, spriteFrame;
 74 
 75         for(var s in spriteData){
 76             sprite = spriteData[s];
 77             if(isNumber(sprite)){
 78                 spriteFrames = translateSpriteFrame(frames[sprite]);
 79             }else if(sprite instanceof Array){
 80                 spriteFrames = [];
 81                 for(var i = 0, len = sprite.length; i < len; i++){
 82                     var spriteObj = sprite[i], frameObj;
 83                     if(isNumber(spriteObj)){
 84                         spriteFrame = translateSpriteFrame(frames[spriteObj]);
 85                     }else{
 86                         frameObj = spriteObj.rect;
 87                         if(isNumber(frameObj)) frameObj = frames[spriteObj.rect];
 88                         spriteFrame = translateSpriteFrame(frameObj, spriteObj);
 89                     }
 90                     spriteFrames[i] = spriteFrame;
 91                 }
 92             }
 93             sprites[s] = spriteFrames;
 94         }
 95     }
 96 
 97     return {frames:frames, sprites:sprites};
 98 }
 99 
100 function isNumber(value){
101     return typeof value === 'number';
102 }
103 
104 function translateSpriteFrame(frameObj, spriteObj){
105     var spriteFrame = {
106         image: frameObj.image,
107         rect: frameObj.rect,
108         pivotX: frameObj.pivotX || 0,
109         pivotY: frameObj.pivotY || 0
110     };
111 
112     if(spriteObj){
113         spriteFrame.name = spriteObj.name || null;
114         spriteFrame.duration = spriteObj.duration || 0;
115         spriteFrame.stop = !!spriteObj.stop;
116         spriteFrame.next = spriteObj.next || null;
117     }
118 
119     return spriteFrame;
120 }
121 
122 })();