当前位置: 首页 > Web前端 > HTML5

H5摄影,选图上传组件核心

时间:2023-04-05 23:37:17 HTML5

背景前段时间项目重构改成SSR项目,但是之前使用的选图上传组件不支持SSR(server-side-render)。然后进行了研究,发现了很多工具。但有的太大了,有的用起来麻烦,有的不符合使用需要。决定自己写一个h5手机图片上传组件。上传图片是比较常见的需求。PC端还好,移动端就不是特别好做。下面简要记录过程中的一些关键问题。要点1、输入选择功能是使用标签实现的。属性accept='image/*',:capture表示系统默认的设备可以进行抓拍,如:camera--camera;camcorder——照相机;麦克风——录音。如果设置了capture="camera",则默认使用相机。有部分机型无法调用摄像头的问题,这里不设置。允许多选,加上onchange事件的回调函数。最终的输入看起来是这样的:,我们可以通过设置`opacity:0`和定位来覆盖我们需要的选择按钮样式。让它更迷人。2.关于选图预览功能选图后可以预览是常用功能。这里抛开样式不谈,只谈代码实现。在onchange的回调函数中,我们可以通过e.target.files获取选中的文件,但是页面上无法显示该文件。通常的做法是使用reader.readAsDataURL(file)将其转换为base64,然后显示在上级页面上。这里我使用九宫格来展示,每张图就是一张画布。考虑到不同图片的纵横比,我先通过reader.readAsDataURL(file)获取base64文件。然后创建一张以九宫格的canvas纵横比绘制的图片,让图片内容覆盖整个canvas而不失真。fileToCanvas(file,index){//文件letreader=newFileReader();reader.readAsDataURL(文件);reader.onload=(event)=>{letimage=newImage();image.src=event.target.result;image.onload=()=>{让imageCanvas=this['canvas'+index].getContext('2d');让canvas={宽度:imageCanvas.canvas.scrollWidth*2,高度:imageCanvas.canvas.scrollHeight*2};让比率=image.width/image.height;让canvasRatio=canvas.width/canvas.height;让xStart=0;让yStart=0;让可渲染宽度;让可渲染高度;if(ratio>canvasRatio){//横向过大,以高为准,缩小程度lethRatio=image.height/canvas.height;renderableHeight=image.height;renderableWidth=canvas.width*hRatio;xStart=(image.width-可渲染宽度)/2;}if(ratio{letreader=newFileReader();reader.onload=function(e){//e.target.result为base64编码的文件letview=newDataView(e.target.result);if(view.getUint16(0,false)!==0xffd8){returnresolve(-2);}letlength=view.byteLength;letoffset=2;while(offset{letreader=newFileReader();reader.readAsDataURL(file);reader.onload=(event)=>{letimage=newImage();image.src=event.target.result;image.onload=()=>{letwidth=image.width;letheight=image.height;letcanvas=document.createElement('canvas');letctx=canvas.getContext('2d');if(orientation>4&&orientation<9){canvas.width=height;canvas.height=width;}else{canvas.width=width;canvas.height=高度;}开关(方向){案例2:ctx.transform(-1,0,0,1,宽度,0);休息;案例3:ctx.transform(-1,0,0,-1,width,height);休息;案例4:ctx.transform(1,0,0,-1,0,height);休息;案例5:ctx.transform(0,1,1,0,0,0);休息;案例6:ctx.transform(0,1,-1,0,height,0);休息;案例7:ctx.transform(0,-1,-1,0,height,width);休息;案例8:ctx.transform(0,-1,1,0,0,width);休息;默认值:ctx.transform(1,0,0,1,0,0);}ctx.drawImage(图像,0,0,宽度,高度);让base64=canvas.toDataURL('image/png');让blob=this.dataURLtoBlob(base64);解决(斑点);};};});}最后上传图片,这部分应该比较容易上传FormData形式的文件。以上代码只是部分功能的伪代码,并非所有功能的最终实现。能折腾多少就折腾多少,到最后你会发现自己学到了很多东西,但是用别人的轮子还是很顺手的。