Skip to content

Commit c9f79ea

Browse files
Merge pull request pixijs#444 from MKelm/dev-atlas
Atlas spritesheet file loader
2 parents dd0974c + b41af9f commit c9f79ea

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

Gruntfile.js

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module.exports = function(grunt) {
5454
'<%= dirs.src %>/textures/RenderTexture.js',
5555
'<%= dirs.src %>/loaders/AssetLoader.js',
5656
'<%= dirs.src %>/loaders/JsonLoader.js',
57+
'<%= dirs.src %>/loaders/AtlasLoader.js',
5758
'<%= dirs.src %>/loaders/SpriteSheetLoader.js',
5859
'<%= dirs.src %>/loaders/ImageLoader.js',
5960
'<%= dirs.src %>/loaders/BitmapFontLoader.js',

src/pixi/loaders/AssetLoader.js

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ PIXI.AssetLoader = function(assetURLs, crossorigin)
5050
"png": PIXI.ImageLoader,
5151
"gif": PIXI.ImageLoader,
5252
"json": PIXI.JsonLoader,
53+
"atlas": PIXI.AtlasLoader,
5354
"anim": PIXI.SpineLoader,
5455
"xml": PIXI.BitmapFontLoader,
5556
"fnt": PIXI.BitmapFontLoader

src/pixi/loaders/AtlasLoader.js

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/**
2+
* @author Martin Kelm http://mkelm.github.com
3+
*/
4+
5+
/**
6+
* The atlas file loader is used to load in Atlas data and parsing it
7+
* When loaded this class will dispatch a "loaded" event
8+
* If load failed this class will dispatch a "error" event
9+
* @class AtlasLoader
10+
* @extends EventTarget
11+
* @constructor
12+
* @param {String} url the url of the JSON file
13+
* @param {Boolean} crossorigin
14+
*/
15+
16+
PIXI.AtlasLoader = function (url, crossorigin) {
17+
PIXI.EventTarget.call(this);
18+
this.url = url;
19+
this.baseUrl = url.replace(/[^\/]*$/, "");
20+
this.crossorigin = crossorigin;
21+
this.loaded = false;
22+
23+
};
24+
25+
// constructor
26+
PIXI.AtlasLoader.constructor = PIXI.AtlasLoader;
27+
28+
/**
29+
* This will begin loading the JSON file
30+
*/
31+
PIXI.AtlasLoader.prototype.load = function () {
32+
this.ajaxRequest = new AjaxRequest();
33+
var scope = this;
34+
this.ajaxRequest.onreadystatechange = function () {
35+
scope.onAtlasLoaded();
36+
};
37+
38+
this.ajaxRequest.open("GET", this.url, true);
39+
if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType("application/json");
40+
this.ajaxRequest.send(null);
41+
};
42+
43+
/**
44+
* Invoke when JSON file is loaded
45+
* @private
46+
*/
47+
PIXI.AtlasLoader.prototype.onAtlasLoaded = function () {
48+
if (this.ajaxRequest.readyState == 4) {
49+
if (this.ajaxRequest.status == 200 || window.location.href.indexOf("http") == -1) {
50+
this.atlas = {
51+
meta : {
52+
image : []
53+
},
54+
frames : []
55+
};
56+
var result = this.ajaxRequest.responseText.split(/\r?\n/);
57+
var lineCount = -3;
58+
59+
var currentImageId = 0;
60+
var currentFrame = null;
61+
var nameInNextLine = false;
62+
// parser without rotation support yet!
63+
for (var i = 0; i < result.length; i++) {
64+
result[i] = result[i].replace(/^\s+|\s+$/g, '');
65+
if (result[i] == "") {
66+
nameInNextLine = i+1;
67+
}
68+
if (result[i].length > 0) {
69+
if (nameInNextLine == i) {
70+
this.atlas.meta.image.push(result[i]);
71+
currentImageId = this.atlas.meta.image.length - 1;
72+
this.atlas.frames.push({});
73+
lineCount = -3;
74+
} else if (lineCount > 0) {
75+
if (lineCount % 7 == 1) { // frame name
76+
if (currentFrame != null) {
77+
this.atlas.frames[currentImageId][currentFrame.name] = currentFrame;
78+
}
79+
currentFrame = { name: result[i], frame : {} };
80+
} else {
81+
var text = result[i].split(" ");
82+
if (lineCount % 7 == 3) { // position
83+
currentFrame.frame.x = Number(text[1].replace(",", ""));
84+
currentFrame.frame.y = Number(text[2]);
85+
} else if (lineCount % 7 == 4) { // size
86+
currentFrame.frame.w = Number(text[1].replace(",", ""));
87+
currentFrame.frame.h = Number(text[2]);
88+
} else if (lineCount % 7 == 5) { // real size
89+
var realSize = {
90+
x : 0,
91+
y : 0,
92+
w : Number(text[1].replace(",", "")),
93+
h : Number(text[2])
94+
}
95+
if (realSize.w > currentFrame.frame.w || realSize.h > currentFrame.frame.h) {
96+
currentFrame.trimmed = true;
97+
currentFrame.realSize = realSize;
98+
} else {
99+
currentFrame.trimmed = false;
100+
}
101+
}
102+
}
103+
}
104+
lineCount++;
105+
}
106+
}
107+
if (currentFrame != null) {
108+
this.atlas.frames[currentImageId][currentFrame.name] = currentFrame;
109+
}
110+
111+
if (this.atlas.meta.image.length > 0) {
112+
this.images = [];
113+
for (var j = 0; j < this.atlas.meta.image.length; j++) {
114+
// sprite sheet
115+
var scope = this;
116+
var textureUrl = this.baseUrl + this.atlas.meta.image[j];
117+
var frameData = this.atlas.frames[j];
118+
this.images.push(new PIXI.ImageLoader(textureUrl, this.crossorigin));
119+
120+
for (var i in frameData) {
121+
var rect = frameData[i].frame;
122+
if (rect) {
123+
PIXI.TextureCache[i] = new PIXI.Texture(this.images[j].texture.baseTexture, {
124+
x: rect.x,
125+
y: rect.y,
126+
width: rect.w,
127+
height: rect.h
128+
});
129+
if (frameData[i].trimmed == true) {
130+
PIXI.TextureCache[i].realSize = frameData[i].realSize;
131+
// trim in pixi not supported yet, todo update trim properties if it is done ...
132+
PIXI.TextureCache[i].trim.x = 0;
133+
PIXI.TextureCache[i].trim.y = 0;
134+
}
135+
}
136+
}
137+
}
138+
139+
this.currentImageId = 0;
140+
for (var j = 0; j < this.images.length; j++) {
141+
this.images[j].addEventListener(
142+
"loaded", function (event) { scope.onLoaded(); }
143+
);
144+
}
145+
this.images[this.currentImageId].load();
146+
147+
} else {
148+
this.onLoaded();
149+
}
150+
151+
} else {
152+
this.onError();
153+
}
154+
}
155+
};
156+
157+
/**
158+
* Invoke when json file loaded
159+
* @private
160+
*/
161+
PIXI.AtlasLoader.prototype.onLoaded = function () {
162+
if (this.images.length - 1 > this.currentImageId) {
163+
this.currentImageId++;
164+
this.images[this.currentImageId].load();
165+
} else {
166+
this.loaded = true;
167+
this.dispatchEvent({
168+
type: "loaded",
169+
content: this
170+
});
171+
}
172+
};
173+
174+
/**
175+
* Invoke when error occured
176+
* @private
177+
*/
178+
PIXI.AtlasLoader.prototype.onError = function () {
179+
this.dispatchEvent({
180+
type: "error",
181+
content: this
182+
});
183+
};

0 commit comments

Comments
 (0)