vega-scenegraph
Version:
Vega scenegraph and renderers.
80 lines (65 loc) • 1.88 kB
JavaScript
import {image} from 'vega-canvas';
import {loader} from 'vega-loader';
import {hasOwnProperty} from 'vega-util';
export default class ResourceLoader {
constructor(customLoader) {
this._pending = 0;
this._loader = customLoader || loader();
}
pending() {
return this._pending;
}
sanitizeURL(uri) {
const loader = this;
increment(loader);
return loader._loader.sanitize(uri, { context: 'href' })
.then(opt => {
decrement(loader);
return opt;
})
.catch(() => {
decrement(loader);
return null;
});
}
loadImage(uri) {
const loader = this, Image = image();
increment(loader);
return loader._loader
.sanitize(uri, { context: 'image' })
.then(opt => {
const url = opt.href;
if (!url || !Image) throw { url: url };
const img = new Image();
// set crossOrigin only if cors is defined; empty string sets anonymous mode
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/crossOrigin
const cors = hasOwnProperty(opt, 'crossOrigin') ? opt.crossOrigin : 'anonymous';
if (cors != null) img.crossOrigin = cors;
// attempt to load image resource
img.onload = () => decrement(loader);
img.onerror = () => decrement(loader);
img.src = url;
return img;
})
.catch(e => {
decrement(loader);
return { complete: false, width: 0, height: 0, src: e && e.url || '' };
});
}
ready() {
const loader = this;
return new Promise(accept => {
function poll(value) {
if (!loader.pending()) accept(value);
else setTimeout(() => { poll(true); }, 10);
}
poll(false);
});
}
}
function increment(loader) {
loader._pending += 1;
}
function decrement(loader) {
loader._pending -= 1;
}