手机端移动端的前端原生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裁剪图片上传相关推荐

  1. 如何上传图片到fileupload空间_如何用原生js写图片上传组件v2.0(还有新版本)?...

    js图片上传组件: 基本要求: 1.上传的图片可预览,可删除,可被覆盖更新 2.要求图片格式为jpg和png,大小不能超过2M 新加需求: 1.模拟回显,可用本地存储(实际上的回显是通过后台传过来的u ...

  2. 原生js实现图片上传功能

    在项目中用到了原生的上传功能,html5代码如下 <div class="uploadimg"><div v-for="(item, index) in ...

  3. cupload怎么保存图片_原生js的图片上传插件cupload

    插件描述:支持图片预览.像素限制.大小限制.多图上传.更新模式下页面初始化加载图片 更新时间:2020-09-25 00:23:49 更新说明:添加  删除时,同时删除服务器图片的功能,文档提供php ...

  4. 前端js实现图片上传

    前端js实现图片上传的原理是通过input标签的type=file属性将input标签定义为上传文件,对input进行onchange事件的监听,当input的value值改变时代表用户已经上传了图片 ...

  5. LocalResizeIMG前端HTML5本地压缩图片上传,兼容移动设备IOS,android

    LocalResizeIMG前端HTML5本地压缩图片上传,兼容移动设备IOS,android jincon 发表于 2015-02-26 18:31:01 发表在: php开发 localresiz ...

  6. alert()的功能_前端实现简单的图片上传小图预览功能

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...

  7. 如何实现上传多个图片并依次展示_js前端实现多图图片上传预览的两个方法(推荐)...

    一.将图片转成icon码的实现方式 html代码: js代码 //图片预览功能 function previewImage(file,imgNum) { var MAXWIDTH = 200; var ...

  8. js实现图片上传预览及进度条

    js实现图片上传预览及进度条 原文js实现图片上传预览及进度条 最近在做图片上传的时候,由于产品设计的比较fashion,上网找了比较久还没有现成的,因此自己做了一个,实现的功能如下: 1:去除浏览器 ...

  9. js实现图片上传预览功能

    js实现图片上传预览功能 很多业务场景下,我们需要在用户上传图片前,先预览待上传的图片 <body><input type="file"><img s ...

最新文章

  1. Repeater控件的分页问题
  2. MySQL 用户与授权管理详解
  3. java按钮监听休眠_java-休眠监控解决方案
  4. 后台开发经典书籍--构建高性能WEB站点
  5. oracle 安装及工具简介,oracle安装及简介
  6. mybatis --入门 单表增删改查-curd
  7. cocos2d-x中的尺寸之一
  8. google authenticator python_Google Authenticator TOTP原理详解(以Python为例)
  9. Pandownload作者被抓后,我决定用docker搭建一款私有网盘
  10. Linux的vi命令使用详解
  11. 干货! IT信息资产分类与信息分级管理规定
  12. 全球及中国工业互联网产业运行态势与布局状况调研报告2022-2028年
  13. vs括号对齐和vs设置背景图片
  14. tf.flags.DEFINE解释
  15. 耿建超英语语法---非谓语动词作同位语和定语
  16. Java面试问题集锦
  17. OpenFOAM-v2112安装——很详细
  18. Android Studio 实现九宫格
  19. 现在Web前端工程师年薪区间是多少?
  20. 有了花呗还需要办信用卡吗?

热门文章

  1. 玩转Atlas200DK(九)ATC模型转换
  2. Android Gson在Kotlin data class中的使用
  3. 系统攻击技术之木马(课程笔记)
  4. 收银服务器维修,POS机坏了怎么维修?看看这些对症下药
  5. 按键精灵移动端系列一滑块本地识别源码参考例子
  6. 个人商务邮箱怎么注册,如何申请收费邮箱
  7. Excel 2010 VBA 入门 006 设置宏安全性
  8. 设置Firefox(火狐)浏览器的中文菜单/界面
  9. 生物信息学|新颖的深度学习模型,更准确地预测药物-药物相互作用
  10. 根据车辆品牌获取品牌所属公司,车标logo,创建年份等基本信息