-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
image_sprite.js
94 lines (76 loc) · 2.36 KB
/
image_sprite.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// @flow
const Evented = require('../util/evented');
const ajax = require('../util/ajax');
const browser = require('../util/browser');
const normalizeURL = require('../util/mapbox').normalizeSpriteURL;
class SpritePosition {
x: number;
y: number;
width: number;
height: number;
pixelRatio: number;
sdf: boolean;
constructor() {
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
this.pixelRatio = 1;
this.sdf = false;
}
}
class ImageSprite extends Evented {
base: string;
retina: boolean;
data: ?{[string]: SpritePosition};
imgData: ?HTMLImageElement;
width: ?number;
constructor(base: string, eventedParent?: Evented) {
super();
this.base = base;
this.retina = browser.devicePixelRatio > 1;
this.setEventedParent(eventedParent);
const format = this.retina ? '@2x' : '';
ajax.getJSON(normalizeURL(base, format, '.json'), (err, data) => {
if (err) {
this.fire('error', {error: err});
} else if (data) {
this.data = (data : any);
if (this.imgData) this.fire('data', {dataType: 'style'});
}
});
ajax.getImage(normalizeURL(base, format, '.png'), (err, img) => {
if (err) {
this.fire('error', {error: err});
} else if (img) {
this.imgData = browser.getImageData(img);
this.width = img.width;
if (this.data) this.fire('data', {dataType: 'style'});
}
});
}
toJSON() {
return this.base;
}
loaded() {
return !!(this.data && this.imgData);
}
resize(/*gl*/) {
if (browser.devicePixelRatio > 1 !== this.retina) {
const newSprite = new ImageSprite(this.base);
newSprite.on('data', () => {
this.data = newSprite.data;
this.imgData = newSprite.imgData;
this.width = newSprite.width;
this.retina = newSprite.retina;
});
}
}
getSpritePosition(name: string) {
if (!this.loaded()) return new SpritePosition();
const pos = this.data && this.data[name];
if (pos && this.imgData) return pos;
return new SpritePosition();
}
}
module.exports = ImageSprite;