JSZip 是一款可以創(chuàng)建、讀取、修改 .zip 文件的 javaScript 工具。在 web 應(yīng)用中,免不了需要從 web 服務(wù)器中獲取資源,如果可以將所有的資源都合并到一個(gè) .zip 文件中,這時(shí)候只需要做一次請(qǐng)求,這樣既減少了服務(wù)器的壓力,同時(shí)也可以加快 web 應(yīng)用的呈現(xiàn)速度。
今天就來探討下 JSZip 如何與 HT 拓?fù)?/span>應(yīng)用結(jié)合。先來看看這期 Demo 的效果圖:
第一步、需要將應(yīng)用對(duì)相關(guān)資源打包成 .zip 文件,
這是我要壓縮的文件列表,把響應(yīng)的資源文件存放到對(duì)應(yīng)的文件夾下,然后在 loadorder 文件中標(biāo)明資源加載的順序,loadorder 文件內(nèi)容如下:
在資源加載順序中,要標(biāo)明響應(yīng)資源的相對(duì)于 .zip 文件的路徑,這樣方便在讀取 .zip 文件時(shí)快速找到相應(yīng)的資源文件。
第二步、在 html 文件中引入 JSZip 和 JSZipUtils 庫,接下來就是請(qǐng)求 .zip 文件,并對(duì) .zip 文件做解析處理。
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 | JSZipUtils.getBinaryContent( 'res/ImportObj.zip' , function (err, data) { if (err) { throw err; // or handle err } var zip = new JSZip(data); var loadorderStr = zip.file( 'loadorder' ).asText(), order; eval( 'order = [' + loadorderStr + ']' ); var len = order.length, image = {}, mtlStr = '' , objStr = '' ; for ( var i = 0; i < len; i++) { var fileName = order[i]; if (fileName.indexOf( 'js/' ) >= 0) { var js = document.createElement( 'script' ); js.innerHTML = zip.file(fileName).asText(); document.getElementsByTagName( 'head' )[0].appendChild(js); } else if (fileName.indexOf( 'image/' ) >= 0) { var buffer = zip.file(fileName).asArrayBuffer(), str = _arrayBufferToBase64(buffer), pIndex = fileName.indexOf( '.' ), type = fileName.substr(pIndex + 1), re = 'data:image/' + type + ';base64,' ; image[fileName] = re + str; } else if (fileName.indexOf( 'obj/' ) >= 0) { var str = zip.file(fileName).asText(); if (fileName.indexOf( '.mtl' ) > 0) { mtlStr = str; } else if (fileName.indexOf( '.obj' ) > 0) { objStr = str; } } } init(objStr, mtlStr, image); }); |
首先通過 JSZipUtils 獲取 .zip 文件,將獲取到的文件內(nèi)容通過 new JSZip(data) 方法加載到 zip 變量中,通過 zip.file(fileName) 讀取 loadorder 文件內(nèi)容,試用 eval 命令動(dòng)態(tài)執(zhí)行腳本,將文本內(nèi)容轉(zhuǎn)換為 js 變量 order,最后通過遍歷 order 變量,將 js 資源動(dòng)態(tài)引入到頁面中。
在 .zip 文件中有包含圖片文件,JSZip 只能獲取到圖片文件的 ArrayBuffer 數(shù)據(jù),這時(shí)需要將 ArrayBuffer 轉(zhuǎn)換為 Base64 才能夠?yàn)闉g覽器所識(shí)別,所以這里定義了一個(gè)轉(zhuǎn)換函數(shù):_arrayBufferToBase64
這次的案例中,有涉及到 3D 模型數(shù)據(jù)與 HT 3D 拓?fù)?/span>應(yīng)用的結(jié)合,在 .zip 文件中的 obj 目錄就是存放 3D 模型數(shù)據(jù),在文件讀取中,將 3D 模型數(shù)據(jù)以文本對(duì)形勢讀取出來存放到變量中,再將數(shù)據(jù)傳遞到 init 函數(shù)中,通過 ht.Default.parseObj() 方法將 3D 模型數(shù)據(jù)加載到 HT 中。
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 | function init(objStr, mtlStr, image) { dataModel = new ht.DataModel(); g3d = new ht.graph3d.Graph3dView(dataModel); view = g3d.getView(); view.className = 'main' ; document.body.appendChild(view); window.addEventListener( 'resize' , function (e) { g3d.invalidate(); }, false ); g3d.setEye([0, 500, 1000]); g3d.setCenter([0, 200, 0]); g3d.setGridVisible( true ); g3d.setGridColor( '#74AADA' ); var param = { shape3d: 'E1' , center: true , cube: true }; var modelMap = ht.Default.parseObj(objStr, mtlStr, param); for ( var model in modelMap) { var map = modelMap[model], i = map.image, index = i.lastIndexOf( '/' ), fileName = i.substr(index + 1), rawS3 = map.rawS3; for ( var imgName in image) { if (imgName.indexOf(fileName) >= 0) { ht.Default.setImage(i, 256, 256, image[imgName]); } } } var node = new ht.Node(); node.s({ 'shape3d' : 'E1' , 'wf.visible' : 'selected' , 'wf.width' : 3, 'wf.color' : '#F7F691' }); node.s3(param.rawS3); node.p3(0, param.rawS3[1]/2, 0); dataModel.add(node); } |
上述是生成 3D 拓?fù)?/span>、3D 模型引入和引用 3D 模型創(chuàng)建拓?fù)涔?jié)點(diǎn)的代碼。其中那段 setImage 的代碼需要特別注意,為什么我要大費(fèi)周張的去判斷 image 的文件名呢,那是因?yàn)樵?mtl 3D 模型描述文件中有一個(gè)設(shè)置貼圖的屬性,該屬性可以指定文件的絕對(duì)路徑,也可以指定文件的相對(duì)路徑,因?yàn)椴捎?JSZip 無法將 .zip 中的文件內(nèi)容寫回到本地目錄中,所以只能將貼圖屬性對(duì)應(yīng)的屬性名稱作為 HT 中的 image 名稱設(shè)置到 HT 中,以便 HT 模型加載的時(shí)候能夠獲取得到模型所需要的圖片資源。HT 3D 拓?fù)涞膽?yīng)用可以參考《3D拓?fù)渥詣?dòng)布局之Node.js篇》。
JSZip 在壓縮或解壓數(shù)據(jù)的時(shí)候,如果出現(xiàn)速度較慢的情況,可以考慮使用 Web Worker,Web Worker的具體應(yīng)用可以參考《3D拓?fù)渥詣?dòng)布局之Web Workers篇》。
聯(lián)系客服