2017-04-11 12 views
0

現在のThree.js(R84)ビルドでは、イメージタグを使用してonProgressイベントをサポートしていないテクスチャを読み込みます。私はいくつのファイルが読み込まれたのかを判断することができますが、ロードされたバイトに関する細かい情報を公開することはできません。XHR進捗イベントでThree.jsにテクスチャをロード

onProgressイベントサポートでテクスチャを読み込む最良の方法は何ですか?広範囲のモバイルクライアントをサポートしたいと思いますが、従来のデスクトップサポートは問題にはなりません。

+0

は、[この](http://blogs.adobe.com/webplatform/2012/01/13/html5-image-progress-events/) – 2pha

答えて

2

解決策の1つは、ファイルをFileLoader経由でロードしてから、TextureLoaderでキャッシュからロードすることです。メモリ内キャッシュとは、サーバーからキャッシュヘッダーが取得されない場合でも、ファイルが一度だけロードされることを意味します。

その結果、FileLoaderの最初のAJAXフェッチを介して進捗イベントが取得されますが、適切なTextureLoader(JPEGテクスチャのアルファチャンネルの無効化などの最適化)のすべての有用な動作を引き続き活用できます。

/** 
* Loads THREE Textures with progress events 
* @augments THREE.TextureLoader 
*/ 
function AjaxTextureLoader() { 
    /** 
    * Three's texture loader doesn't support onProgress events, because it uses image tags under the hood. 
    * 
    * A relatively simple workaround is to AJAX the file into the cache with a FileLoader, create an image from the Blob, 
    * then extract that into a texture with a separate TextureLoader call. 
    * 
    * The cache is in memory, so this will work even if the server doesn't return a cache-control header. 
    */ 

    const cache = THREE.Cache; 

    // Turn on shared caching for FileLoader, ImageLoader and TextureLoader 
    cache.enabled = true; 

    const textureLoader = new THREE.TextureLoader(); 
    const fileLoader = new THREE.FileLoader(); 
    fileLoader.setResponseType('blob'); 

    function load(url, onLoad, onProgress, onError) { 
     fileLoader.load(url, cacheImage, onProgress, onError); 

     /** 
     * The cache is currently storing a Blob, but we need to cast it to an Image 
     * or else it won't work as a texture. TextureLoader won't do this automatically. 
     */ 
     function cacheImage(blob) { 
      // ObjectURLs should be released as soon as is safe, to free memory 
      const objUrl = URL.createObjectURL(blob); 
      const image = document.createElementNS('http://www.w3.org/1999/xhtml', 'img'); 

      image.onload =()=> { 
       cache.add(url, image); 
       URL.revokeObjectURL(objUrl); 
       document.body.removeChild(image); 
       loadImageAsTexture(); 
      }; 

      image.src = objUrl; 
      image.style.visibility = 'hidden'; 
      document.body.appendChild(image); 
     } 

     function loadImageAsTexture() { 
      textureLoader.load(url, onLoad,()=> {}, onError); 
     } 
    } 

    return Object.assign({}, textureLoader, {load}); 
} 

module.exports = AjaxTextureLoader; 
+1

かなり甘いソリューションを見てみましょう! – pailhead

関連する問題