我最近做了一个项目,这个项目要实现的功能之一是:用户自定义头像(用户在本地选择一张图片,本地剪切图片,使其符合系统要求的大小)。这个功能的要求是头像最初被切割成正方形。如果所选图片小于头像所需大小,则整个图片将用作头像。如果大于指定尺寸,用户可以选择要切割的区域。当用户点击确定按钮时,剪切的图像数据将被发送到服务器,图像数据将在后端保存为文件。
为了完成上述功能,所涉及的知识是:html5中的ajax、canvas和文件接口。我把实现这个功能的代码封装成四个模块,分别是ajax.js、preview.js、shear.js和customerImg.js
Ajax.js:用于发送Ajax请求。
Preview.js:用于图片预览
Shear.js:用于裁剪图片
Customer.js:自定义头像。在这个模块中引入ajax.js、preview.js和shear.js
我使用webpack进行包装。我还使用了jquery和jquery-ui。
我从这个项目中提取了这个功能。下面是这个函数的详细代码。
1.HTML代码
Div class=' m-warp ' id=' warp ' Div class=' item '输入类型=' file' name=' img' id=' img '隐藏标签为=' img '选择图片/标签/Div class=' item clear fix ' Div class=' col-1 ' Div class=' preview ' id=' preview ' Div class=' mask '/Div canvas class=' cvsMove ' id=' cvsMove '/canvas/Div/Div class=' thumcol-2 col ' p preview/p img SRG
{ content : }之后的clearfix:afterdisplay:块;clear:两者;高度: 0;飞越:隐藏;visibility:隐藏;} img {垂直对齐:中间;最大宽度:100%}。m-warp { width : 800 px;}.项目{ margin-top : 20px;}.col{ float:左侧;}.col-1{ position:相对;宽度: 450 px;高度: 450 px;outline: 1px实心# 333;}.预览{ display : inline-block;}.col-2 { width : 300 px;左边距left: 50px}标签{ display: block文本对齐:中心;宽度: 100 px;font-size : 16px;color: # fff背景色: # 888888;height: 30px线高: 30px;}.mask{ position:绝对值;z-index : 1;top:0left : 0;bottom : 0;right : 0;背景-color: rgba(0,0,0, 4);}.cvsMove{ position:绝对值;z-index : 2;outline: 2px虚线# 333;光标:移动;display:无;}使用css和html,运行结果如下:
3.js代码
customerImg.js
var $=require(' jquery ');var ajax=require(' ./Ajax。js’);var preview=require(' ./预览。js’);变化剪切=需要切变。js’);/** * 自定义头像* @ constructor */function CustomerImg(){ this。issupport=nullthis . previewbox=null this . warp=null }/* * *入口* @param warp操作区域jquery节点*/customerimg。原型。start=function(warp){ var info,me,warpBox我=这个;这个.问题支持=这个._ _ isSupport();if(!this.isSupport) { info=$('p你的浏览器不支持自定义头像,可更换高版本的浏览器自定义头像/p ');$(“正文”).html(信息);归还这个;} //判断操作区域示范存在如果(翘曲翘曲。长度0){ this。翘曲=翘曲;}else{返回此;} //预览preview.start(翘曲,剪切。start.bind(剪切,翘曲));这个。预览框=扭曲。查找(' # preview ');//确定翘曲。查找(“#submit”).解除绑定("单击")。打开('点击,我_ _提交。捆绑(我));};/** * 提交* @ private */customerimg。原型。_ _ submit=function(){ var CVS move,data,FD;CVS移动=这个。预览框。查找(# CVS move’);data=cvsMove[0]。todaytaul(' image/jpg ',1);FD={ ' customerImg ' : data };Ajax。上传(FD);};/** * 判断是否支持自定义头像* @返回{ boolean } * @ private */customerimg。原型。_ _ isSupport=function(){ var canvas,contextcanvas=document。创建元素(“画布”);if(文件读取器的类型==' function ' canvas。getcontext画布。todaytaul){ return true;} else {返回false } }var customerImg=new customerImg();module . exports=customerimgpreview . js
/** *由星星于2017年3月七日创建*/var $=require(' jquery ');/** * 预览类* @构造函数*/函数Preview(){ this。Boxelem=nullthis . callback=null this . type=null }/* * *入口* @param boxElem操作区域* @param回调预览结束的回调函数*/预览。原型。start=function(Boxelem,回调){ var chooseFile,me;我=这个;if(!boxElem || boxElem.length=0)返回这个;this.boxElem=boxElemif(回调类型==' function '){ this。回调=回调;}如果(这个_ _ isSupport()){选择文件=Boxelem。find(' input[type=' file ']');选择文件打开(改变),我。文件更改。bind(me))} };/** * 选择图片的事件处理程序* @ param事件*/预览。原型。文件更改=函数(事件){ var target,reader,file,me,typetarget=event.target我=这个;文件=目标。文件[0];type=file.typethis.type=typeif(键入!=='image/png '类型!=='image/jpg '类型!=='image/jpeg'){ alert('文件格式不正确');归还这个;} reader=new FileReader();如果(文件){ reader.readAsDataURL(文件);}读者。onload=function(){ me。show(reader);}};/** * 显示从本地选择的图片* @param reader fileReader对象*/preView。原型。show=function(reader){ var preView,img,me;preView=这个。Boxelem。find(' # PreView ');img=PreView。find(' # PreImg ');我=这个;if(img。长度=0){ PreView。追加($(' img id=' preImg '));} img=PreView。find(' # PreImg ');//确保图片加载完成后再执行回调img.on('load ',function(){ if(me。回调){我。回调(我。类型);} });img.attr('src ',阅读器。结果);};/** * 是否支持预览* @返回{布尔} * @ private */preview。原型。_ _ isSupport=function(){文件读取器的返回类型===' function};var Preview=new Preview();module.exports=previewshear.js
var $=require(' jquery ');//由于要使用jquery-ui,所以将$暴露到窗户上窗户。$=$;要求('。/jquery-ui。量滴js’);/** * 切割* @ constructor */函数Shear(){ this。预览框=空;这个。CVS移动=空;this . MaxW=200 this . MaxH=200 this . thum=null this。FileType=' image/JPEG ';}/** * 入口* @param预览框预览元素的父元素* @param fileType裁剪的图片的类型如:' image/jpg ' * @返回{剪切} */剪切。原型。start=函数(预览框,文件类型){ if(!参数. length)返回此值;var me=这。预览框=预览框;if(fileType){ this。fileType=文件类型;}这个。thum=这个。预览框。find(' # thum ');这个。CVS移动=这个。预览框。查找(# CVS move’);这个。showcanvas();归还这个;};/** * 显示出画布*/剪切。原型。show canvas=function(){ var preImg,h,w,me,cvsH,cvsW,rateH,rateW,naturalH,naturalW,preview我=这个;preImg=这个。预览框。find(# PreImg ');预览=这个。预览框。查找(' # preview ');naturalH=preImg[0].自然高度;naturalW=preImg[0].自然宽度;//将帆布显示出来这个。cvsmove。show();//将帆布置于(0,0) this.cvsMove .css({ 'left':'0 ',' top':'0' })。h=preImg。高度();w=preImg。宽度();//规定裁剪出的图片尺寸为200px*200px //要保证裁剪的图片不变形如果这个。MaxH | | w这个。MaxW){这个。CVS移动[0].width=cvsW=Math.min(h,w);this.cvsMove[0].高度=cvsH=Math.min(h,w);} else { this。CVS live[0].width=cvsW=this . maxwthis . cvsmove[0].高度=cvsH=this . MaxH } RateH=H/自然H;ratEw=w/NaturalW;这个__drawImg(preImg,0,0,cvsW/rateW,cvsH/rateH,0,0,cvsW,cvsH);//使用jquery-ui中的功能使帆布可以移动这个。CVS移动。可拖动({ containment : ' parent ',drag:function (event,ui) { var left,topleft=ui。位置。向左;top=ui。位置。顶部;//画布每次移动都有从新绘制图案我_ _图纸IMg(preImg,左/速率w顶/速率h,cvsW/速率w,cvsH/速率h,0,0,cvsW,cvsH);} } )};/** * 在帆布上显示图片* @param myImg要显示的图片节点* @param sx图片的起点在原图片上的x坐标* @param sy图片的起点在原图上的y坐标* @param sW在原图上的宽度* @param sH在原图上的高度* @param dx起点在帆布上的x坐标* @param dy起点在帆布上的y坐标* @param dW在帆布上的宽度* @param dH在帆布上的高度* @ private */shear。原型。_ _ draw img=function(myImg,sx,sy,sW,sH,dx,dy,dW,dH) { var cxt,thum,me;我=这个;cxt=这个。CVS live[0].getContext(' 2d ');cxt.drawImage(myImg[0],sx,sy,sW,sH,dx,dy,dW,dH);图姆=this.thum//将帆布上的图案显示到右侧图姆attr('src ',this.cvsMove[0].今天(我。文件类型,1)).宽度(this.maxW).高度(这个。MaxH)};var Shear=new Shear();module . exports=sherajax . js
var $=require(' jquery ');函数Ajax() {}/** *上传图片数据*/Ajax.prototype.upload=函数(数据){ $。ajax({ type:'POST ',data:data,dataType:'json ',url:'/test/PHP/upload.php ',success : function(result){ if(result。状态){位置。重载();} else { alert(结果。味精);} } });};var Ajax=new Ajax();module.exports=ajax最后在另一个文件中,调用customerImg对象的开始方法
var $=require(' jquery ');var customerImg=require(' ./customerimg。js’);定制。start($(' # warp ');webpack的配置文件如下:
var web pack=require(' web pack ');模块。导出={ entry : { ' customerImg ' : } ./js/test.js ',' jQuery':['jquery'] },输出: { filename : '[name].js '、library:'jQuery '、libraryTarget: ' umd ' }、plugins :[新的web pack。优化。commonschunk插件({ name : ' jQuery '、filename : ' jQuery。js ' })]};效果:
4.php代码
if(!空($ _ POST)已设置($ _ POST[' customerImg ']){ $ img=$ _ POST[' customerImg '];$imgdata=explode(',',$ img);$ uniName=MD5(uniqid(micro time(true),true));$a=file_put_contents(' ././上传/.$ uniName . jpg ',base64 _ decode($ img data[1]);}以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。