In the HTML, in the process of file upload, a lot of things are not any hint, this experience is very bad, users do not know when the upload, upload succeeded No, so today to introduce the content is through the HT for web vector to achieve HTML5 file upload progress bar, vector in the Vector chart embedded in the application of HTML5 network topology diagram, the article has described the application of the Setcomptype () method, today we use the SetImage () method to make full use of the system's defined vector resources to implement the file upload progress bar, we first look at:
As you can see, a MP4 file is uploaded to the server and the current upload progress is displayed at the bottom.
So, let's explore the following specific implementations:
First, let's analyze the structure of the progress bar:
1. Need a background, background
2. A current progress value is required and value
3. Need a foreground, foreground, based on the current progress value, draw the foreground, cover the background
structure is so simple, then the next step is to implement the specific, look at the code:
Ht. Default.setimage (' Progress ', { width : 150, height : 12, comps : [ // Drawing Background { type : ' rect ', rect : {x : 0, y : 0, width : 115, Height : 12}, background : {func : function (data) {return data.a (' Background ');}} }, // Drawing Prospects { 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); } } ]});
We define a vector object named progress, a vector object consisting of two parts, a background and a foreground.
The drawing background is based on the data binding, the Background property of the database is bound, the drawing foreground is drawn by the method of the custom type, and is an abbreviation of the Setcomptype () method, which calculates the drawing width based on the value values in data.
The general design of the vector has been completed, so let's use it to see how it works.
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 ();d Atamodel.add (node), var graphview = new Ht.graph.GraphView (Datamodel); Graphview.addtodom (); Graphview.layout ({x:0, y:80, width:170, height:30});
We created a node, set the Image property of node to our defined vector, and then created a Graphview component that displays node in the Graphview network topology diagram.
Then let's simulate the file upload progress and let the progress bar move up.
function Setprogressvalue (node) {var value = Node.getvalue (); if (value!==) {node.setvalue (value + 1); var second = Math.Round (Math.random () * 500); SetTimeout (Setprogressvalue, Second, node); }}
We keep setting the value of node by using the SetTimeout () method, but as the code runs you will find that the progress bar is not moving at all, consistent in its initial state, and when we zoom Graphview, we can see that the progress bar is changing. In fact, the reason is very simple, when we modify the value, we do not notify Graphview to update, so the progress bar will not be changed because of the value of node change, then how can we notify the Graphview update? The method is simple, after you modify the value of node, dispatch a PropertyChange event, and add the following code after creating the node code:
Node.getvalue = function () {return this._value;}; Node.setvalue = function (value) {var self = this, OV = Self._value; Self._value = value; SELF.FP (' value ', OV, value);};
In the code, the PropertyChange event is distributed through the FP () method, so that the progress bar works correctly and changes as node's value changes, as follows:
But there is a little bit, although the progress bar is running, but we still do not know the current progress value is how much, only through the proportion of the progress bar to approximate the current progress value, we can add a text on the progress bar to display the current progress value, the answer is yes, We just need to add the following code to the comps of the vector:
Draw Text {rect: {x:118, y:0, width:32, Height:12}, type: ' Text ', text: {func:function (data) {return D Ata.getvalue () + '% ';}, font: ' 12px Arial, Sans-ferif ', Color: ' Black '}
The Code also applies the binding, which binds the current value of node, as follows:
Now the progress bar and the final effect is a round angle, then how to achieve the fillet angle? In fact, it is not difficult, only need to draw a rounded rectangle, and combined with the clip () method will be outside the corner of the rectangular area to intercept, the clip () method of the detailed description can refer to the introduction of the MDN.
1. First, we need to create a method of waving rounded rectangles:
/*** * draw round edge rectangles * @param ctx brushes * @param x coordinates x * @param y coordinates y * @param width width * @param height Height * @param radius fillet 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,&nbsP;y + radius); ctx.quadraticcurveto (x + width, y, x + width - radius, y); ctx.lineto (x + radius, y); ctx.quadraticcurveto (X, y, x, y + radius);}
2. Using a custom type method, call the RoundRect () method, draw a rounded rectangular area, and then call the clip () method to truncate the outer part of the rounded rectangular area. It is important to note that the clip () method intercepts only the content that is drawn after the method is used, and the content drawn before the method is called will not be truncated. So the following code must be placed before the code that paints the background.
Draw Rounded Rectangle {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 (); }}
See how it works.
At this point, the design of the progress bar is over, so let's look at how the progress bar is combined with the file upload:
1. First, we need to have a server to receive files, in addition to using a regular Web server (Web server simple configuration can refer to: HT for Web HTML5 Tree Component delay loading technology implementation), also uses the formidable module, The following is the code for the server:
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 monitoring Connection event Io.on (' Connection ', function (socket) { // define socket name Socket.join (' upload ');}); / set the server's working path 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); // gets the specified socket and dispatches the event io.sockets.in (' upload '). Emit (' Progress ', percent); }); form.parse (req);}); / server listens on 4000 port Server.listen (3000, function () { console.log (' Server is listening at port 3000 ');});
2. Secondly, we need to design a file upload form:
<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. Furthermore, we need to combine Ajax with no flush to upload files to the server, and in conjunction with socket technology to listen to server events, in the browser how to use the socket can refer to: HT for Web HTML5 Tree Component delay loading technology implementation.
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);
So, based on the HT for Web custom class implementation of the HTML5 file upload progress bar page design and code design complete, due to the length of the relationship, in the fromidable aspect of less, also hope forgive me, below I say attached complete code, interested students can download down research and research.
Click to download the source code
Implementation of HTML5 file upload progress bar based on HT for web vector