HTML5向量實現檔案上傳進度條
在HTML中,在檔案上傳的過程中,很多情況都是沒有任何的提示,這在體驗上很不好,使用者都不知道到時有沒有在上傳、上傳成功了沒有,所以今天給大家介紹的內容是通過HT for Web向量來實現HTML5檔案上傳進度條,向量在《向量Chart圖表嵌入HTML5網路拓撲圖的應用》一文中已經講述了關於setCompType()方法的應用,今天我們用setImage()方法充分利用系統中定義好的向量資源來實現檔案上傳進度條,我們先來看下效果圖:
從效果圖可以看到,向伺服器上傳了一個mp4檔案,並在最下方顯示當前上傳進度。
那麼接下來我們就來探討下具體實現:
首先,我們來分析下進度條的結構:
1. 需要一個背景,background
2. 需要一個當前進度值,value
3. 需要一個前景,foreground,根據當前進度值,繪製前景,蓋過背景
結構就這麼簡單,那麼接下來就是具體的實現了,看碼:
ht.Default.setImage(`progress`, {
width : 150,
height : 12,
comps : [
// 繪製背景
{
type : `rect`,
rect : {x : 0, y : 0, width : 115, height : 12},
background : {func : function(data) {return data.a(`background`);}}
},
// 繪製前景
{
rect : {x : 0, y : 0, width : 115, height : 12},
type : function(g, rect, comp, data, view) {
var width = rect.width, height = rect.height, value = data.getValue(),
foreWidth = width / 100 * value;
g.fillStyle = data.a(`foreground`);
g.fillRect(0, 0, foreWidth, height);
}
}
]
});
我們定義了一個名字為progress的向量物件,向量物件由兩部分組成,一個是背景,一個是前景。
繪製背景採用了資料繫結的方式,繫結了data的background屬性;繪製前景則採用自定義型別的方法繪製,是setCompType()方法的一種縮寫,繪製是根據data中的value值計算繪製寬度。
向量的大體設計已經完成,那麼我們把他用起來,看看效果如何。
var dataModel = new ht.DataModel(),
node = new ht.Node();
node.setValue(0);
node.setImage(`progress`);
node.a(`background`, `#5F6870`);
node.a(`foreground`, `#58B6DA`);
node.p(85, 87);
dataModel.add(node);
var graphView = new ht.graph.GraphView(dataModel);
graphView.addToDOM();
graphView.layout({x : 0, y : 80, width : 170, height : 30});
我們建立了一個node,並將node的image屬性設定成我們定義的向量,然後建立一個graphView元件,將node顯示在graphView網路拓撲圖中。
那麼接下來我們來模擬檔案上傳進度,讓進度條動起來。
function setProgressValue(node) {
var value = node.getValue();
if (value !== 100) {
node.setValue(value + 1);
var second = Math.round(Math.random() * 500);
setTimeout(setProgressValue, second, node);
}
}
我們通過setTimeout()方法不斷設定node的value值,但是,程式碼執行起來你會發現,進度條根本沒有在動,一致處於初始狀態,當我們縮放graphView時,可以看到進度條在改變,這是為什麼呢?其實原因很簡單,我們在修改value值時,並沒有通知graphView要更新,因此進度條並不會因為node的value值改變而有所改變,那麼我們該如何通知graphView更新呢?方法很簡單,在修改node的value值後,派發一個propertyChange事件就可以了,在建立node程式碼後新增如下程式碼:
node.getValue = function() {
return this._value;
};
node.setValue = function(value) {
var self = this,
oV = self._value;
self._value = value;
self.fp(`value`, oV, value);
};
程式碼中,通過fp()方法來派發propertyChange事件,如此,進度條就可以正常工作,隨著node的value的變化而變化,效果圖如下:
但是還有一點不足,進度條雖然在跑了,但是我們還是不知道當前進度值是多少,只能通過進度條的比重來大致估計當前進度值,我們能否在進度條上新增一個文字,用來顯示當前進度值呢,答案是肯定的,我們只需要在向量的comps中新增如下程式碼就可以:
// 繪製文字
{
rect : {x : 118, y : 0, width : 32, height : 12},
type : `text`,
text : {func : function(data) {return data.getValue() + `%`;}},
font : `12px arial, sans-ferif`,
color : `black`
}
程式碼中同樣適用了繫結,繫結node當前的value值,具體的效果圖如下:
現在的進度條與最終效果就差圓角了,那麼圓角要如何實現呢?其實也不難,只需要繪製出一個圓角矩形,並結合clip()方法將超出圓角矩形區域的部分擷取掉即可,clip()方法的詳細介紹可以參考MDN中的介紹。
1. 首先,我們需要建立一個揮之圓角矩形的方法:
/***
* 繪製圓邊矩形
* @param ctx 畫筆
* @param x 座標 x
* @param y 座標 y
* @param width 寬度
* @param height 高度
* @param radius 圓角半徑
*/
function roundRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x, y + radius);
ctx.lineTo(x, y + height - radius);
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
ctx.lineTo(x + width - radius, y + height);
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
ctx.lineTo(x + width, y + radius);
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
ctx.lineTo(x + radius, y);
ctx.quadraticCurveTo(x, y, x, y + radius);
}
2. 採用自定義型別的方法,呼叫roundRect()方法,繪製一個圓角矩形區域,然後再呼叫clip()方法,截掉圓角矩形區域外部分。有一點需要注意,clip()方法擷取的內容只對呼叫該方法後繪製的內容有效,呼叫該方法之前繪製的內容並不會被截掉。因此以下程式碼必須放在繪製背景的程式碼前。
// 繪製圓角矩形
{
rect : {x : 0, y : 0, width : 115, height : 12},
type : function(g, rect, comp, data, view) {
var width = rect.width, height = rect.height;
roundRect(g, 0, 0, width, height, height / 2);
g.clip();
}
}
看下效果如何
至此,進度條的設計就結束了,那麼接下來就來看下進度條如何與檔案上傳結合起來:
1. 首先,我們需要有個伺服器來接收檔案,伺服器中除了使用常規的web伺服器外(web伺服器的簡單配置可參考:HT for Web的HTML5樹元件延遲載入技術實現),還使用了formidable模組,以下是伺服器的程式碼:
var express = require(`express`),
app = express(),
server = require(`http`).createServer(app),
io = require(`socket.io`)(server),
path = require(`path`),
root = path.join(__dirname, `../../../`),
formidable = require(`formidable`);
// io監聽connection事件
io.on(`connection`, function(socket){
// 定義socket名稱
socket.join(`upload`);
});
// 設定伺服器的工作路徑
app.use(express.static(root));
app.post(`/`, function(req, res){
var form = new formidable.IncomingForm();
form.on(`end`, function(){
res.end(`upload complete!`);
});
form.on(`progress`, function(bytesReceived, bytesExpected){
var percent = Math.floor(bytesReceived / bytesExpected * 100);
// 獲取指定的socket,並派發事件
io.sockets.in(`upload`).emit(`progress`, percent);
});
form.parse(req);
});
// 伺服器監聽4000埠
server.listen(3000, function(){
console.log(`server is listening at port 3000`);
});
2. 其次,我們需要設計一個檔案上傳的表單:
<form method="post" action="/" enctype="multipart/form-data" name="fileForm"> <p><input type="file" name="file"/></p> <p><input type="submit" value="Upload"/></p> </form>
3. 再者,我們需要結合ajax無重新整理向伺服器上傳檔案,並結合socket技術監聽伺服器事件,在瀏覽器如何使用socket可以參考:HT for Web的HTML5樹元件延遲載入技術實現。
var fileForm = document.forms.namedItem(`fileForm`);
fileForm.addEventListener(`submit`, function(e) {
var httpRequest;
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
httpRequest = new XMLHttpRequest();
}
else if (window.ActiveXObject) { // IE 6 and older
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
httpRequest.open(`POST`, `/`, true);
httpRequest.send(new FormData(fileForm));
socket.on(`progress`, function(val) {
progress.setValue(val);
});
e.preventDefault();
}, false);
如此,基於HT for Web自定義類實現HTML5檔案上傳進度條的頁面設計及程式碼設計全部完成,由於篇幅的關係,在fromidable方面講得比較少,還望見諒,下面我講附上完整的程式碼,有興趣的同學可以下載下來研究研究。
相關文章
- 向量HTML5實現檔案上傳進度條HTML
- 基於HT for Web向量實現HTML5檔案上傳進度條WebHTML
- 基於HT for Web向量實現HTML5上傳檔案進度條WebHTML
- jQuery監聽檔案上傳實現進度條效果jQuery
- 上傳檔案帶進度條
- 帶進度條的檔案上傳
- PHP檔案上傳進度條完整程式實現 jQuery Ajax apcPHPjQuery
- js實現帶上傳進度的檔案上傳JS
- 基於uploadify.js實現多檔案上傳和上傳進度條的顯示JS
- 檔案上傳進度提示
- 【方法】Html5實現檔案非同步上傳HTML非同步
- OSS實現檔案下載進度條顯示
- Simple WPF: S3實現MINIO大檔案上傳並顯示上傳進度S3
- Flex4/Flash多檔案上傳(帶進度條)例項分享Flex
- Html5 檔案上傳HTML
- html5檔案上傳HTML
- HTML5 進階系列:檔案上傳下載HTML
- Node.js:上傳檔案,服務端如何獲取檔案上傳進度Node.js服務端
- ajax實現檔案上傳
- HttpWebChilent上傳與下載進度條HTTPWeb
- PHP實現單檔案、多檔案上傳 封裝 物件導向實現檔案上傳PHP封裝物件
- HTML5拖拽檔案上傳HTML
- vue中檔案上傳阿里雲並獲取上傳進度Vue阿里
- Http 檔案上傳進度為什麼不準HTTP
- AngularJS實現的檔案檔案上傳AngularJS
- HttpFileCollection 實現多檔案上傳HTTP
- 檔案上傳原理和實現
- springmvc實現檔案上傳SpringMVC
- bat檔案進度條程式碼BAT
- 贊!帶進度條的 jQuery 檔案拖放上傳外掛jQuery
- Jsp+Servlet實現檔案上傳下載(一)--檔案上傳JSServlet
- golang 進度條功能實現Golang
- clip實現圓環進度條
- 命令列進度條實現命令列
- 通過配置檔案(.htaccess)實現檔案上傳
- 使用java的MultipartFile實現layui官網檔案上傳實現全部示例,java檔案上傳JavaUI
- H5拖放非同步檔案上傳之二——上傳進度監聽H5非同步
- PHP實現圖片(檔案)上傳PHP