手机端移动端的前端原生js裁剪图片上传
手机端移动端的前端原生js裁剪图片上传
选择头像时裁剪上传,确保图片是个正方形,不会出现压扁拉伸的现象
效果图
原理很简单,其实就是用canvas截图出来而已,只是要对比例做一下处理。
<!--首先咱得先有一个文件选择触发和一个canvas标签-->
<input onchange="iconChange()" type="file" id="imageFile" accept="image/*" style="display:none">
<canvas id="captureCanvas" style="display: none;"></canvas>
//定义几个会用到的变量
let captureImage,c,ctx,orginImgRate,x,y;
function iconChange(){let file = document.getElementById("imageFile").files && document.getElementById("imageFile").files[0];handleImage(file,async (f)=>{choose(f)});}
//对文件处理,转成可预览的base64,顺便封装个formData
async function handleImage(file,fn){if(file.size>5*1024*1024){layer.msg("图片大小不能超过5M!",{type:1});return;}let orginFile = {};var filereader = new FileReader();var formData = new FormData();filereader.readAsDataURL(file);filereader.onload=function (e) {formData.append("file",file);orginFile = {base64:e.target.result,formData};fn(orginFile);}
}//这里调用的layer的弹出层,没有用layer的话也可以用别的代替
async function choose(data){let content = `<div style="position: relative;"><img id="captureImage" src="${data.base64}" style="width: 100%;" /><div ontouchend="touchCaptureEnd(event)" ontouchmove="touchCaptureMove(event)" ontouchstart="touchCapture(event)" id="capture" style="width: 100px;height: 100px;position: absolute;border: 1px dashed white;background: rgb(185 185 185 / 50%);left: 0;right: 0;top: 0;box-sizing: border-box;"></div></div>`const layerIndex = layer.open({skin:"center-open",area:'90%',offset:"50%",title:'确定使用这张图片作为你的头像吗?',content,btn: ['确定','取消'],//在弹出成功之后运行success这个方法success(){setTimeout(async ()=>{c=document.getElementById("captureCanvas");ctx=c.getContext("2d");captureImage = document.getElementById("captureImage");const capture = document.getElementById("capture");//如果是横着的图片,裁剪框默认撑满图片高度if(captureImage.width>captureImage.height){capture.style.height = captureImage.height+"px"capture.style.width = captureImage.height+"px"}else{//如果是竖着的图片,裁剪框默认撑满图片宽度capture.style.width = captureImage.width+"px"capture.style.height = captureImage.width+"px"}const imgInfo = await loadImg(data.base64);//计算画布大小与图片分辨率之间的比例orginImgRate = imgInfo.h/captureImage.heightc.width = capture.offsetWidthc.height = capture.offsetHeight//渲染画布drawCanvas(captureImage,ctx,capture.offsetLeft*orginImgRate,capture.offsetTop*orginImgRate,capture.offsetWidth*orginImgRate,capture.offsetWidth*orginImgRate,0,0,capture.offsetWidth,capture.offsetWidth)})},//当点击确定时触发yes: async function(){//将裁剪完的画布转成base64const src = c.toDataURL("image/png");const blob = base64ToBlob(src);const file = blobToFile(blob, data.origin.name);const tempFormData = new FormData()tempFormData.append("file",file)//拿到装好File的tempFormData,该干嘛干嘛//todo 上传文件 修改头像}});
}
//获取图片的宽和高
function loadImg(el){return new Promise((resolve)=>{var img =new Image();img.src = el;img.onload = function(){resolve({h:img.height,w:img.width});}})
}
//触屏结束触发,把body变为可滚动状态
function touchCaptureEnd(){body.style.overflow="scroll"
}
function drawCanvas(captureImage,ctx,left,top,width,height,tw,th,sw,sh){ctx.drawImage(captureImage,left,top,width,height,tw,th,sw,sh);
}
//当手指碰到屏幕那一刻,获取手指碰到的在选择框内的相对横坐标和纵坐标,用来移动裁剪框
function touchCapture(e){x = e.changedTouches[0].clientX-e.target.offsetLefty = e.changedTouches[0].clientY-e.target.offsetTop
}
//在手指在屏幕上舞动时,把body变成hidden不给滚动
function touchCaptureMove(e){const target = e.changedTouches[0];if(!body.style.overflow || body.style.overflow=="scroll"){body.style.overflow="hidden"}//移动x方向和y方向e.target.style.left = target.clientX-x+"px";e.target.style.top = target.clientY-y+"px";if(target.clientX-x<=0){e.target.style.left = "0px"console.log("到最左边了")}else if(e.target.offsetLeft+e.target.offsetWidth>captureImage.width){console.log("到最右边边了")e.target.style.left = captureImage.width-e.target.offsetWidth+"px"}if(target.clientY-y<0){e.target.style.top = "0px" console.log("到最上了")}else if(e.target.offsetTop+e.target.offsetHeight>captureImage.height){e.target.style.top = captureImage.height-e.target.offsetHeight+"px"console.log("到最下了了")}//实时更新canvas的图像drawCanvas(captureImage,ctx,e.target.offsetLeft*orginImgRate,e.target.offsetTop*orginImgRate,e.target.offsetWidth*orginImgRate,e.target.offsetWidth*orginImgRate,0,0,e.target.offsetWidth,e.target.offsetWidth)function drawCanvas(captureImage,ctx,left,top,width,height,tw,th,sw,sh){ctx.drawImage(captureImage,left,top,width,height,tw,th,sw,sh);}
}// base64转blob
const base64ToBlob = function(base64Data) {let arr = base64Data.split(','),fileType = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),l = bstr.length,u8Arr = new Uint8Array(l);while (l--) {u8Arr[l] = bstr.charCodeAt(l);}return new Blob([u8Arr], {type: fileType});
};
// blob转file
const blobToFile = function(newBlob, fileName) {newBlob.lastModifiedDate = new Date();newBlob.name = fileName;return newBlob;
};
手机端移动端的前端原生js裁剪图片上传相关推荐
- 如何上传图片到fileupload空间_如何用原生js写图片上传组件v2.0(还有新版本)?...
js图片上传组件: 基本要求: 1.上传的图片可预览,可删除,可被覆盖更新 2.要求图片格式为jpg和png,大小不能超过2M 新加需求: 1.模拟回显,可用本地存储(实际上的回显是通过后台传过来的u ...
- 原生js实现图片上传功能
在项目中用到了原生的上传功能,html5代码如下 <div class="uploadimg"><div v-for="(item, index) in ...
- cupload怎么保存图片_原生js的图片上传插件cupload
插件描述:支持图片预览.像素限制.大小限制.多图上传.更新模式下页面初始化加载图片 更新时间:2020-09-25 00:23:49 更新说明:添加 删除时,同时删除服务器图片的功能,文档提供php ...
- 前端js实现图片上传
前端js实现图片上传的原理是通过input标签的type=file属性将input标签定义为上传文件,对input进行onchange事件的监听,当input的value值改变时代表用户已经上传了图片 ...
- LocalResizeIMG前端HTML5本地压缩图片上传,兼容移动设备IOS,android
LocalResizeIMG前端HTML5本地压缩图片上传,兼容移动设备IOS,android jincon 发表于 2015-02-26 18:31:01 发表在: php开发 localresiz ...
- alert()的功能_前端实现简单的图片上传小图预览功能
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...
- 如何实现上传多个图片并依次展示_js前端实现多图图片上传预览的两个方法(推荐)...
一.将图片转成icon码的实现方式 html代码: js代码 //图片预览功能 function previewImage(file,imgNum) { var MAXWIDTH = 200; var ...
- js实现图片上传预览及进度条
js实现图片上传预览及进度条 原文js实现图片上传预览及进度条 最近在做图片上传的时候,由于产品设计的比较fashion,上网找了比较久还没有现成的,因此自己做了一个,实现的功能如下: 1:去除浏览器 ...
- js实现图片上传预览功能
js实现图片上传预览功能 很多业务场景下,我们需要在用户上传图片前,先预览待上传的图片 <body><input type="file"><img s ...
最新文章
- Repeater控件的分页问题
- MySQL 用户与授权管理详解
- java按钮监听休眠_java-休眠监控解决方案
- 后台开发经典书籍--构建高性能WEB站点
- oracle 安装及工具简介,oracle安装及简介
- mybatis --入门 单表增删改查-curd
- cocos2d-x中的尺寸之一
- google authenticator python_Google Authenticator TOTP原理详解(以Python为例)
- Pandownload作者被抓后,我决定用docker搭建一款私有网盘
- Linux的vi命令使用详解
- 干货! IT信息资产分类与信息分级管理规定
- 全球及中国工业互联网产业运行态势与布局状况调研报告2022-2028年
- vs括号对齐和vs设置背景图片
- tf.flags.DEFINE解释
- 耿建超英语语法---非谓语动词作同位语和定语
- Java面试问题集锦
- OpenFOAM-v2112安装——很详细
- Android Studio 实现九宫格
- 现在Web前端工程师年薪区间是多少?
- 有了花呗还需要办信用卡吗?