我有一个图像库项目,用户可以在3D空间中移动图像,并且当他靠近它们时就开始下载图像。由于他可以一直走动,远离已经开始下载的图像,因此我需要取消这些下载(不再需要下载,因为它们不再可见了)。
我使用Three.TextureLoader下载了它们,希望找到一些方法来停止/取消/中止下载,但似乎不存在。我发现这些线程与该主题有关:
https://github.com/mrdoob/three.js/pull/6649
https://github.com/mrdoob/three.js/issues/6641
但是,在我的Three版本中,我找不到在Three代码中添加建议的“返回请求”的位置。我认为这是应该在其中找到的部分,但是我不太清楚应该在哪里添加这样的return语句:
Object.assign(Ja.prototype, {
load: function(a, b, c, d) {
void 0 === a && (a = "");
void 0 !== this.path && (a = this.path + a);
a = this.manager.resolveURL(a);
var e = this
, f = jd.get(a);
if (void 0 !== f)
return e.manager.itemStart(a),
setTimeout(function() {
b && b(f);
e.manager.itemEnd(a)
}, 0),
f;
if (void 0 !== Ta[a])
Ta[a].push({
onLoad: b,
onProgress: c,
onError: d
});
else {
var g = a.match(/^data:(.*?)(;base64)?,(.*)$/);
if (g) {
c = g[1];
var h = !!g[2]
, g = g[3]
, g = window.decodeURIComponent(g);
h && (g = window.atob(g));
try {
var k = (this.responseType || "").toLowerCase();
switch (k) {
case "arraybuffer":
case "blob":
for (var l = new Uint8Array(g.length), h = 0; h < g.length; h++)
l[h] = g.charCodeAt(h);
var m = "blob" === k ? new Blob([l.buffer],{
type: c
}) : l.buffer;
break;
case "document":
m = (new DOMParser).parseFromString(g, c);
break;
case "json":
m = JSON.parse(g);
break;
default:
m = g
}
window.setTimeout(function() {
b && b(m);
e.manager.itemEnd(a)
}, 0)
} catch (t) {
window.setTimeout(function() {
d && d(t);
e.manager.itemEnd(a);
e.manager.itemError(a)
}, 0)
}
} else {
Ta[a] = [];
Ta[a].push({
onLoad: b,
onProgress: c,
onError: d
});
var n = new XMLHttpRequest;
n.open("GET", a, !0);
n.addEventListener("load", function(b) {
var c = b.target.response;
jd.add(a, c);
var d = Ta[a];
delete Ta[a];
if (200 === this.status) {
for (var f = 0, g = d.length; f < g; f++) {
var h = d[f];
if (h.onLoad)
h.onLoad(c)
}
e.manager.itemEnd(a)
} else if (0 === this.status) {
console.warn("THREE.FileLoader: HTTP Status 0 received.");
f = 0;
for (g = d.length; f < g; f++)
if (h = d[f],
h.onLoad)
h.onLoad(c);
e.manager.itemEnd(a)
} else {
f = 0;
for (g = d.length; f < g; f++)
if (h = d[f],
h.onError)
h.onError(b);
e.manager.itemEnd(a);
e.manager.itemError(a)
}
}, !1);
n.addEventListener("progress", function(b) {
for (var c = Ta[a], d = 0, e = c.length; d < e; d++) {
var f = c[d];
if (f.onProgress)
f.onProgress(b)
}
}, !1);
n.addEventListener("error", function(b) {
var c = Ta[a];
delete Ta[a];
for (var d = 0, f = c.length; d < f; d++) {
var g = c[d];
if (g.onError)
g.onError(b)
}
e.manager.itemEnd(a);
e.manager.itemError(a)
}, !1);
void 0 !== this.responseType && (n.responseType = this.responseType);
void 0 !== this.withCredentials && (n.withCredentials = this.withCredentials);
n.overrideMimeType && n.overrideMimeType(void 0 !== this.mimeType ? this.mimeType : "text/plain");
for (h in this.requestHeader)
n.setRequestHeader(h, this.requestHeader[h]);
n.send(null)
}
e.manager.itemStart(a);
return n
}
return n
},
setPath: function(a) {
this.path = a;
return this
},
setResponseType: function(a) {
this.responseType = a;
return this
},
setWithCredentials: function(a) {
this.withCredentials = a;
return this
},
setMimeType: function(a) {
this.mimeType = a;
return this
},
setRequestHeader: function(a) {
this.requestHeader = a;
return this
}
});
有人能指出我正确的方向吗?还是另一种解决方案,例如以另一种方式加载图像(也许是jQuery?),然后以某种方式将纹理传递给我的材质?这是我当前对TextureLaoder的回调:
obj.handleTexture = function (size, texture) {
obj.mesh.material.map = texture;
obj.mesh.material.needsUpdate = true;
};
非常感谢
答案 0 :(得分:0)
如果需要中止图像加载器,请查看源代码:https://github.com/mrdoob/three.js/blob/dev/src/loaders/ImageLoader.js
new ImageLoader().load(...)
函数返回一个XHTML图像元素(<img />
)。但是该元素不能从外部访问。因此,您可以轻松编写自己的函数来加载纹理,并覆盖现有的函数。
下面的函数主要从以下地方复制:https://github.com/mrdoob/three.js/blob/dev/src/loaders/TextureLoader.js确保在最新版本的ThreeJS中,您检查下面的源代码是否相同(除了附加的中止功能之外)。
THREE.TextureLoader.prototype.load = function(url, onLoad, onProgress, onError)
{
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader(this.manager);
loader.setCrossOrigin(this.crossOrigin);
loader.setPath(this.path);
var image = loader.load(url, function(image)
{
texture.image = image;
// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.
var isJPEG = url.search( /\.jpe?g($|\?)/i ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
texture.format = isJPEG ? THREE.RGBFormat : THREE.RGBAFormat;
texture.needsUpdate = true;
if(onLoad !== undefined)
{
onLoad( texture );
}
}, onProgress, onError);
// add this function to the texture
texture.abort = function()
{
if(image && typeof image.hasAttribute === 'function')
{
image.src = '';
}
};
return texture;
};
用法:
var texLoader = new THREE.TextureLoader();
var texRequest = texLoader.load('https://example.com/image.jpg', function(texture)
{
clearTimeout(texTimer);
// use loaded texture
...
});
// For example, abort after 200ms if still loading:
var texTimer = setTimeout(function()
{
texRequest.abort();
}, 200);