使用ajax上传图片,并且使用canvas实现出上传进度效果
前端代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>使用ajax上传图片,并使用canvas实现出上传进度效果</title> <style> #myImg { border: 1px solid gray; border-radius: 8px; position: absolute; top: 0px; left: 0px; } #myCanvas { position: absolute; top: 0px; left: 0px } </style> </head> <body> <div> <input type="file" id="myFile" style="width: 70px"> <input type="button" onclick="clickUpload()" value="上传"> </div> <div style="position: relative"> <img src="" id="myImg" width="200px" height="200px" alt="请选择一张图片"> <canvas id="myCanvas" width="200px" height="200px">您的浏览器不支持 canvas</canvas> </div> </body> <script src="${pageContext.request.contextPath}/js/jquery-1.12.3.js"></script> <script> //图片预览 //function(ev) == (ev)=> $("#myFile").change((ev) => { //将图片的转成blob数据类型 var imgUrl = URL.createObjectURL(document.getElementById("myFile").files[0]); //给img标签的src赋值 document.getElementById("myImg").src = imgUrl; //当图片加载完成时,回收资源,避免浪费,这是一个回调函数 imgUrl.onload = () => URL.revokeObjectURL(imgUrl); }); /** * 压缩图片,然后执行某个任务 * */ function compressImgTaskCallback(blob, taskCallback) { //创建一个canvas容器 var canvas = document.createElement("canvas"); //设置这个容器的宽、高( 使用img的 宽高的一半 )。 var w = document.getElementById("myImg").naturalWidth / 2, h = document.getElementById("myImg").naturalHeight / 2; canvas.width = w; canvas.height = h; //获取在canvas容器绘制的对象 var ctx = canvas.getContext("2d"); //将向canvas容器绘制图像 ctx.drawImage(document.getElementById("myImg"), 0, 0, w, h); //导出在canvas容器绘制的图像,转成blob类型 //jpeg -> 有损压缩 canvas.toBlob(taskCallback, "image/jpeg"); }; /** * 文件上传进度 * */ function fileProgress(r) { console.log(r); //获取canvas容器 var mycanvas = document.getElementById("myCanvas"); //获取在canvas容器绘制的对象 var ctx = mycanvas.getContext("2d"); //保存当前绘制环境状态 ctx.save(); //清空指定矩形内的像素,参数:x(容器左上角的x坐标) y(容器左上角的y坐标) w(宽度)h(高度) ctx.clearRect(0, 0, 200, 200); //设置容器的透明度 ctx.globalAlpha = 0.6; //填充‘被绘制’的矩形 //参数:x(容器左上角的x坐标) y(容器左上角的y坐标) w(宽度)h(高度) ctx.fillRect(0, (1 - r) * 200, 200, 200); //设置透明度 ctx.globalAlpha = 1; //设置填充颜色 ctx.fillStyle = "white"; ctx.font = "20px 微软雅黑"; //绘制被填充的文本 //参数: tetx (绘制的文本) x 绘制文本的 x 坐标位置(相对于画布)y 绘制文本的 y 坐标位置(相对于画布) //显示百分比 ctx.fillText(parseInt(r * 100) + '%', 100, 100); //返回之前保存绘制的路径和属性 ctx.restore(); }; /** * 使用ajax上传blob类型文件 * @param blob * */ function uploadFile(blob) { //将blob存储在FormData中 var formData = new FormData(); formData.append("filename", blob);//形成键值对应,伪装成表单的数据 //发起ajax请求 $.ajax({ method: "post",//请求方法 url: "/imgUpload",//服务器地址 data: formData,//向服务器传输的数据 contentType: false,//避免ajax操作请求头部从而丢分界符,造成服务器无法正确识别请求的数据类型 processData: false,//告诉ajax不要把将传输的数据给序列化了。 cache: false,//不从浏览器缓存中加载请求头部信息 xhr: () => { //拿到jQuery产生的 XMLHttpRequest对象 var xhr = $.ajaxSettings.xhr(); //绑定上用于监听文件上传的进度事件 xhr.upload.onprogress = (ev) => { //ev.loaded = 当前文件上传的进度 //ev.total = 文件的总进度 fileProgress(ev.loaded/ev.total); }; return xhr; }, error: (error) => { alert("出现错误啦。"); } }); }; //上传按钮事件 function clickUpload() { compressImgTaskCallback($("#myFile")[0].files[0], uploadFile); }; </script> </html>
后端接收数据:
运行效果:
这是一瞬间就完成了加载,
直接下来我们限制一下浏览器传输速度。
在浏览器按F12,(我这里使用的是谷歌浏览器)
使用完后记得恢复回去哦。
设置浏览器传输速度后的运行效果:
写得有点乱,^_^,继续加油。