
效果图
原理很简单,其实就是用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的d出层,没有用layer的话也可以用别的代替
async function choose(data){
let content = `
${data.base64}" />
`
const layerIndex = layer.open({
skin:"center-open",
area:'90%',
offset:"50%",
title:'确定使用这张图片作为你的头像吗?',
content,
btn: ['确定','取消'],
//在d出成功之后运行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.height
c.width = capture.offsetWidth
c.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(){
//将裁剪完的画布转成base64
const 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.offsetLeft
y = 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;
};
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)