mapbox-gl
Version:
A WebGL interactive maps library
92 lines (72 loc) • 2.42 kB
JavaScript
'use strict';
const Evented = require('../util/evented');
const ajax = require('../util/ajax');
const browser = require('../util/browser');
const normalizeURL = require('../util/mapbox').normalizeSpriteURL;
class SpritePosition {
constructor() {
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
this.pixelRatio = 1;
this.sdf = false;
}
}
class ImageSprite extends Evented {
constructor(base, eventedParent) {
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});
return;
}
this.data = data;
if (this.imgData) this.fire('data', {dataType: 'style'});
});
ajax.getImage(normalizeURL(base, format, '.png'), (err, img) => {
if (err) {
this.fire('error', {error: err});
return;
}
this.imgData = browser.getImageData(img);
// premultiply the sprite
for (let i = 0; i < this.imgData.length; i += 4) {
const alpha = this.imgData[i + 3] / 255;
this.imgData[i + 0] *= alpha;
this.imgData[i + 1] *= alpha;
this.imgData[i + 2] *= alpha;
}
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) {
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;