基于HTML5+JS实现本地图片裁剪并上传功能
前端之家收集整理的这篇文章主要介绍了
基于HTML5+JS实现本地图片裁剪并上传功能,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
最近做了一个项目,这个项目中需要实现的一个功能是:用户自定义头像(用户在本地选择一张图片,在本地将图片裁剪成满足系统要求尺寸的大小)。这个功能的需求是:头像最初剪切为一个正方形。如果选择的图片小于规定的头像要求尺寸,那么这整张图片都会作为头像。如果大于规定的尺寸,那么用户可以选择要裁剪的区域。用户点击确定按钮,就将裁剪得到的图片数据发送到服务器,在后端将图片数据保存成一个文件。
要完成上述功能,涉及到的知识有:ajax,canvas和html5中的files接口。我将实现这个功能的代码封装到了4个模块中,分别是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。
我从这个项目中抽离出了这个功能。下面是这个功能的详细代码。
<div class="thum col-2 col">
预览
2.CSS代码
有了css和html的运行结果如下:
customerImg.js
自定义头像
* @constructor
*/
function CustomerImg() {
this.isSupport = null;
this.preview
Box = null;
this.warp = null;
}
/**
* 入口
* @param warp 操作区域 jquery节点
*/
CustomerImg.prototype.start = function (warp) {
var info,me,warp
Box;
me = this;
this.isSupport = this.__isSupport();
if(!this.isSupport) {
info = $('
你的浏览器不支持自定义头像,可更换高版本的浏览器自定义头像
');
$('body').html(info);
return this;
}
//判断操作区域示范存在
if(warp && warp.length > 0){
this.warp = warp;
}else{
return this;
}
//预览
preview.start(warp,shear.start.bind(shear,warp));
this.preview
Box = warp.find('#preview');
//确定
warp
.find('#submit')
.unbind('click')
.on('click',me.__submit.bind(me));
};
/**
* 提交
* @private
*/
CustomerImg.prototype.__submit = function () {
var cvsMove,data,fd;
cvsMove = this.preview
Box.find('#cvsMove');
data = cvsMove[0].toDataURL('image/jpg',1);
fd = {
'customerImg':data
};
ajax.upload(fd);
};
/**
* 判断是否
支持自定义头像
* @returns {boolean}
* @private
*/
CustomerImg.prototype.__isSupport = function () {
var canvas,context;
canvas= document.createElement('canvas');
if(typeof FileReader === 'function'&& canvas.getContext && canvas.toDataURL){
return true;
}else{
return false;
}
};
var customerImg = new CustomerImg();
module.exports = customerImg;
preview.js
BoxElem = null;
this.callback = null;
this.type = null;
}
/**
* 入口
* @param
BoxElem 操作区域
* @param callback 预览结束的回调
函数
*/
Preview.prototype.start = function (
BoxElem,callback) {
var chooseFile,me;
me = this;
if(!
BoxElem ||
BoxElem.length <= 0) return this;
this.
BoxElem =
BoxElem;
if(typeof callback === 'function'){
this.callback = callback;
}
if(this.__isSupport()){
chooseFile =
BoxElem.find('input[type="file"]');
chooseFile
.on('change',me.fileChange.bind(me))
}
};
/**
* 选择
图片的事件处理程序
* @param event
*/
Preview.prototype.fileChange = function (event) {
var target,reader,file,type;
target = event.target;
me = this;
file = target.files[0];
type = file.type;
this.type = type;
if(type !== 'image/png' && type !== 'image/jpg' && type !== 'image/jpeg'){
alert('
文件格式不正确');
return this;
}
reader = new FileReader();
if(file){
reader.readAsDataURL(file);
}
reader.onload = function () {
me.show(reader);
}
};
/**
*
显示从本地选择的
图片
* @param reader fileReader对象
*/
Preview.prototype.show = function (reader) {
var preView,img,me;
preView = this.
BoxElem.find('#preview');
img = preView.find('#preImg');
me = this;
if(img.length <= 0){
preView.append($('
图片加载完成后再执行回调
img.on('load',function () {
if(me.callback){
me.callback(me.type);
}
});
img.attr('src',reader.result);
};
/**
* 是否
支持预览
* @returns {boolean}
* @private
*/
Preview.prototype.__isSupport = function () {
return typeof FileReader === 'function';
};
var preview = new Preview();
module.exports = preview;
shear.js
Box = null;
this.cvsMove = null;
this.maxW = 200;
this.maxH = 200;
this.thum = null;
this.fileType = 'image/jpeg';
}
/**
* 入口
* @param preview
Box 预览元素的父元素
* @param fileType 裁剪的
图片的类型 如:'image/jpg'
* @returns {Shear}
*/
Shear.prototype.start = function (preview
Box,fileType) {
if(!arguments.length) return this;
var me = this;
this.preview
Box = preview
Box;
if(fileType){
this.fileType = fileType;
}
this.thum = this.preview
Box.find('#thum');
this.cvsMove = this.preview
Box.find('#cvsMove');
this.showCanvas();
return this;
};
/**
- 显示出canvas
/
Shear.prototype.showCanvas = function () {
var preImg,h,w,cvsH,cvsW,rateH,rateW,naturalH,naturalW,preview;
me = this;
preImg = this.previewBox.find('#preImg');
preview = this.previewBox.find('#preview');
naturalH = preImg[0].naturalHeight;
naturalW = preImg[0].naturalWidth;
//将canvas显示出来
this.cvsMove.show();
//将canvas置于(0,0)
this.cvsMove
.css({
"left":'0','top':'0'
});
h = preImg.height();
w = preImg.width();
//规定裁剪出的图片尺寸为200px200px
//要保证裁剪的图片不变形
if(h < this.maxH || w < this.maxW){
this.cvsMove[0].width = cvsW = Math.min(h,w);
this.cvsMove[0].height = cvsH = Math.min(h,w);
}else{
this.cvsMove[0].width= cvsW = this.maxW;
this.cvsMove[0].height= cvsH = this.maxH;
}
rateH = h/naturalH;
rateW = w/naturalW;
this.__drawImg(preImg,cvsW/rateW,cvsH/rateH,cvsH);
//使用jquery-ui中的功能使canvas可以移动
this.cvsMove.draggable(
{
containment: "parent",drag:function (event,ui) {
var left,top;
left = ui.position.left;
top = ui.position.top;
//canvas每次移动都有从新绘制图案
me.__drawImg(preImg,left/rateW,top/rateH,cvsH);
}
}
)
};
/**
- 在canvas上显示图片
- @param myImg 要显示的图片节点
- @param sx 图片的起点在原图片上的x坐标
- @param sy 图片的起点在原图上的y坐标
- @param sW 在原图上的宽度
- @param sH 在原图上的高度
- @param dx 起点在canvas上的x坐标
- @param dy 起点在canvas上的y坐标
- @param dW 在canvas上的宽度
- @param dH 在canvas上的高度
- @private
*/
Shear.prototype.__drawImg = function (myImg,sx,sy,sW,sH,dx,dy,dW,dH) {
var cxt,thum,me;
me = this;
cxt = this.cvsMove[0].getContext('2d');
cxt.drawImage(myImg[0],dH);
thum = this.thum;
//将canvas上的图案显示到右侧
thum
.attr('src',this.cvsMove[0].toDataURL(me.fileType,1))
.width(this.maxW)
.height(this.maxH)
};
var shear = new Shear();
module.exports = shear;
ajax.js
}
/**
- 上传图片数据
*/
Ajax.prototype.upload = function (data) {
$.ajax({
type:'POST',data:data,dataType:'json',url:'/test/PHP/upload.PHP',success:function (result) {
if(result.status){
location.reload();
}else{
alert(result.msg);
}
}
});
};
var ajax = new Ajax();
module.exports = ajax;
最后在另一个文件中,调用customerImg对象的start方法
webpack的配置文件如下:
效果:
4.PHP代码
PHP;">
if(!empty($_POST) && isset($_POST['customerImg'])){
$img = $_POST['customerImg'];
$imgdata = explode(',',$img);
$uniName = md5 ( uniqid ( microtime ( true ),true ) );
$a = file_put_contents('./../uploads/'.$uniName.'.jpg',base64_decode($imgdata[1]));
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。
原文链接:https://www.f2er.com/js/40488.html