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

来源:互联网 发布:黑龙江网络作家协会 编辑:程序博客网 时间:2024/06/16 05:40

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

 <script>        $('#mic-img-main').melonImageCrop({            selectBtn: '#upload-file', //选择图片的按钮            cropImgBox: '#mic-crop-box', //剪切预览显示图片的容器            cropImgBtn: '#mic-crop-btn', //剪切预览图片的按钮            zoomBigBtn: '#mic-zoom-big', //放大按钮            zoomSmaBtn: '#mic-zoom-sma',            zoomRatio: 1.3, //缩小放大的倍率  touchRatio:1,//移动端双指缩放系数,            rotLeftBtn: '#mic-rot-left',            rotRightBtn: '#mic-rot-right',            imgUpBtn:'#mic-up-btn',            imgBoxSize:200//剪切的圆形部分尺寸,切勿超过主框的大小        });
</script>

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

控制层中绑定事件调用方法
这里写图片描述

而对于插件中使用到的参数,定义为melonTouchConfig。
这里写图片描述
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('<div class=""><img src="' + imageData + '" "></div>');                        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);                    }                },

这里写图片描述
插件目前正在完善中,也试着兼容ie9,但是现在还有一点点小问题,兼容后会更新~
如果使用中发什么bug或疑问,欢迎随时与我联系~

0 0
原创粉丝点击