拿来就用,基于jq的pc+移动端头像上传插件

Git地址:https://github.com/luguidong/melonImageCrop.git
请在服务器环境下使用,建议wampserver
头像上传,几乎涉及到会员系统的网站都会用到的功能。在16年做公司商城项目因思维新智能产品商城的时候,我就负责过头像上传这一块的功能,当时是在网上找了一个使用比较广的头像插件,cropbox.js,但是里面的功能较为单一,主要就是放大与缩小功能,当时基于这个插件进行了一定的扩展,然而始终觉得写的插件使用起来不是那么的顺手。于是趁最近有时间,就自己写了一个专门的头像上传插件。
名称:melonImageBox;兼容性:ie10+,基于jq;主要功能:上传预览、剪切、滚轮/按钮/双指触摸放大与缩小、旋转功能,插件本身也可以设置放大缩小的倍率、缩放系数、头像尺寸。另外我以前在使用cropbox.js的过程中,发现很多提问都是有关于这个插件获取的图片如何上传到后台,因此为了方便使用,在本插件中我也写了一个基于php+json模拟存取数据的过程,在wampserver的环境下运行可以直接在上传后查看上传的图片,这里需要注意的是传输的数据是图像的base64,可以直接存入数据库。
使用配置:

 

关于本插件
以前学习过一段时间的php,其中有个经典的架构叫MVC,分别代表模型、视图、控制层,这样子代码的层级结构非常清晰,而写这个插件的时候,我也试着融入了一点MVC的想法,前台调用插件时,只在return时绑定事件,然后调用fnTotal中相应的方法,相当于控制层,业务逻辑则统一写到fnTotal中,以便调用。
下图是fnTotal中包含的所有方法
拿来就用,基于jq的pc+移动端头像上传插件_第1张图片

控制层中绑定事件调用方法
拿来就用,基于jq的pc+移动端头像上传插件_第2张图片

而对于插件中使用到的参数,定义为melonTouchConfig。
拿来就用,基于jq的pc+移动端头像上传插件_第3张图片
melonTouchConfig为插件默认的配置,可以在前台调用的时候修改,param则是插件内进行计算的时候所需要的一些变量,之所以专门设置了这样一个变量的集合,主要原因在于,虽然各个事件(拖拽、滑动、放大、缩小等等)的方法之间相对独立,但是又会互相影响,因此专门独立出一个变量集,每次方法要用到相应的数据的时候就从param里面取,进行相应计算之后再改变里面的变量,这样就使得各个方法之间耦合度很低。
插件的核心功能:剪切图片
本插件最根本的目的就是剪切出用户想要的图片,剪切图片的方法为fnTotal.getCropImage()。通过js创建一个canvas元素,然后使用context.translate()来移动原点,使画布的原点位于canvas的中央,再根据当前的param.curImgRotate来进行旋转,这里由于单位不同需要进行一下转换。在canvas中根据用户的操作绘制相应的图片,这里就要介绍canvas中绘制图片的功能了,context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);这个方法参数非常的多,w3c上的解释也很绕,我自己的理解就是img:绘制的图片。Sx/Sy:原始图片上截取的起点。swidth/sheight:原始图片上截取的终点。x/y:画布上绘制的起点。Width/height:画布上绘制图片的宽高。简单来说,2~5个参数是针对图片源文件的设置,后面4个参数是针对绘制图形的设置。绘制后利用canvas.toDataUrl()方法取得图片的base64,并在浏览器端预览。

 getCropImage: function (elCrop, cropImgBox, backSize) {
     
                    elCrop.on('click', function () {
     
                        var canvas = document.createElement("canvas");
                        canvas.width = backSize;
                        canvas.height = backSize;

                        var context = canvas.getContext("2d");

                        context.translate(backSize / 2, backSize / 2);

                        //旋转
                        context.rotate(param.curImgRotate * Math.PI / 180);
                        var cropX = param.backPosX - (param.mainBoxWidth - param.curImgWidth) / 2;
                        var cropY = param.backPosY - (param.mainBoxHeight - param.curImgHeight) / 2;
                        context.drawImage(imgObj, 0, 0, imgObj.width, imgObj.height, cropX - param.curImgWidth / 2, cropY - param.curImgHeight / 2, param.curImgWidth, param.curImgHeight);

                        var imageData = canvas.toDataURL('image/png');
                        cropImgBox.html('');
                        //生成预览图

                        cropImgBox.append('
'" ">
'
); param.imgData = imageData; }); },

旋转之后的拖拽、触摸移动方向需要转换
以拖拽为例,拖拽的业务逻辑为fnTotal.mouseMove(),当背景框架中产生拖拽事件时,会先对此时图片的旋转角度进行一个归类分析,旋转角度即param.curImgRotate,假如此时背景框架旋转了顺时针旋转了90度,param.curImgRotate=90,如下图所示,此时鼠标若向上拖拽,对背景图来说实际上应该向左移动,所以此时背景的位置应该为背景图此时的x坐标param.backPosX加上鼠标在Y轴上改变的距离changeY,即bgX=changeY+param.backPosX,其它情况以此类推。

mouseMove: function (e) {
     
                    if (param.mouseFlag) {
                        var bgY = 0;
                        var bgX = 0;
                        var changeX = e.clientX - param.mouseIniX;
                        var changeY = e.clientY - param.mouseIniY;
                        if (param.curImgRotate % 360 == 0) {
                            bgX = changeX + param.backPosX;
                            bgY = changeY + param.backPosY;
                        }
                        if (param.curImgRotate % 360 == 90 || param.curImgRotate % 360 == -270) {
                            bgY = -changeX + param.backPosY;
                            bgX = changeY + param.backPosX;
                        }
                        if (param.curImgRotate % 360 == 180 || param.curImgRotate % 360 == -180) {
                            bgX = -changeX + param.backPosX;
                            bgY = -changeY + param.backPosY;
                        }
                        if (param.curImgRotate % 360 == 270 || param.curImgRotate % 360 == -90) {
                            bgY = changeX + param.backPosY;
                            bgX = -changeY + param.backPosX;
                        }
                        this.setBackPos($imgBox, bgX, bgY);
                    }
                },

拿来就用,基于jq的pc+移动端头像上传插件_第4张图片
插件目前正在完善中,也试着兼容ie9,但是现在还有一点点小问题,兼容后会更新~
如果使用中发什么bug或疑问,欢迎随时与我联系~

你可能感兴趣的:(插件,插件,javascript,php)