移动端图片上传裁切(版权归秒为所有,仅为搬运)

xiaoxiao2021-02-28  116

<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width,user-scalable=no" /> <meta name="description" content="本次公开课节选自《妙味移动端原生技法精粹揭秘》远程课程,想要了解详情的同学可以访问:http://www.miaov.com/index.php/news/newsDetail/nid/155 查看课程详情。三周的系统课程,带你玩转原生H5移动端web开发"> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> body { margin: 0; } html, body { height: 100%; } .wrap { position: relative; height: 100%; overflow: hidden; } .page { position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: #ccc; } .pageHide { -webkit-transform: translateY(100%); transform: translateY(100%); } .fileBtn { position: absolute; left: 50%; top: 50%; width: 200px; height: 50px; font: 20px/50px "宋体"; text-align: center; border: 1px solid #179e16; border-radius: 5px; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); background: #1aad19; color: #fff; } #file { display: none; } #select { position: absolute; left: 0; top: 0; width: 200px; height: 200px; border: 2px solid #6f0; background: rgba(255, 255, 255, .1); } .left-top { position: absolute; left: -4px; top: -4px; width: 40px; height: 40px; border-left: 4px solid #6f0; border-top: 4px solid #6f0; } .right-top { position: absolute; right: -4px; top: -4px; width: 40px; height: 40px; border-right: 4px solid #6f0; border-top: 4px solid #6f0; } .left-bottom { position: absolute; left: -4px; bottom: -4px; width: 40px; height: 40px; border-left: 4px solid #6f0; border-bottom: 4px solid #6f0; } .right-bottom { position: absolute; right: -4px; bottom: -4px; width: 40px; height: 40px; border-right: 4px solid #6f0; border-bottom: 4px solid #6f0; } #mask { position: absolute; left: 0; width: 100%; bottom: 0; height: 30px; background: rgba(0, 0, 0, 0.5); text-align: center; font: 20px/30px "宋体"; } #mask a { color: #fff; } #img { position: absolute; display: none; } </style> </head> <body> <div class="wrap"> <div class="page"> <label class="fileBtn"> 点击上传图片 <input type="file" id="file" accept="image/*" name=""> </label> </div> <div class="page pageHide"> <canvas id="c"></canvas> <div id="select"> <div class="left-top"></div> <div class="right-top"></div> <div class="left-bottom"></div> <div class="right-bottom"></div> </div> <div id="mask"> <a href="javascript:;" id="saveBtn">保存</a> </div> <img src="" id="img"> </div> </div> <!-- 本次公开课节选自《妙味移动端原生技法精粹揭秘》远程课程,想要了解详情的同学可以访问:http://www.miaov.com/index.php/news/newsDetail/nid/155 查看课程详情。三周的系统课程,带你玩转原生H5移动端web开发 --> <script type="text/javascript" src="MTween.js"></script> <script type="text/javascript"> console.log('本次公开课节选自《妙味移动端原生技法精粹揭秘》远程课程,想要了解详情的同学可以访问:http://www.miaov.com/index.php/news/newsDetail/nid/155 查看课程详情。三周的系统课程,带你玩转原生H5移动端web开发'); /* 答应大家的 https://github.com/motao314/mScroll 移动端滑屏组件 移动端图片上传裁切: 1. 图片上传 2. 文件大小限制 3. 图片读取 4. 把读取过后图片显示在canvas中 5. 封装多指操作函数 6. 多值操作canvas中的图缩放 未实现的功能: 1. 单指拖拽封装 2. 单指拖拽canvas中的画面移动 3. 单指拖拽选框中,移动选框 4. 单指拖拽选框的周边,改变选框的大小 5. canvas的图片裁切 */ (function(){ var file = document.querySelector('#file'); var page = document.querySelectorAll('.page'); var c = document.querySelector('#c'); var cxt = c.getContext("2d"); var maxSize = 10*1024*1024; page[1].addEventListener('touchstart', function(e) { e.preventDefault(); }); c.width = document.documentElement.clientWidth; c.height = document.documentElement.clientHeight; file.onchange = function(){ //console.log(this.files[0]); if(this.files[0].size > maxSize){ alert("对不起,您传的文件有点太大了"); return; } var reader = new FileReader(); reader.onload = function(e){ //console.log(e.target.result); var img = new Image(); img.src = e.target.result; img.onload = function(){ var imgW = img.width; var imgH = img.height; var scale = 1; var scaleW = 1; var scaleH = 1; var x = 0; var y = 0; var startLeft = 0;//按下时手指坐标 var startTop = 0;//按下时手指坐标 var startW = 0;//按下时图片宽度 var satrtH = 0;//按下时图片高度 var isDrag = true; var isSelectDrag = true; var minW = 100; var minH = 100; /* 如果图片较大 超出了我一屏的大小 */ if(imgW > c.width||imgH > c.height){ scaleW = c.width/imgW; scaleH = c.height/imgH; //计算一个缩放比例 scale = Math.min(scaleW,scaleH); } imgW *= scale; imgH *= scale; x = (c.width - imgW)/2; y = (c.height - imgH)/2; //缩放整张图片的尺寸,并且把图片居中显示了 cxt.drawImage(img,x,y,imgW,imgH); /* 双指缩放图片 */ gesture({ el:page[1], start: function(){ startLeft = x; startTop = y; startW = imgW; startH = imgH; isDrag = false; isSelectDrag = false; }, change: function(e){ //根据手指缩放比例重新计算图片尺寸 imgW = startW*e.scale; imgH = startH*e.scale; //根据新的图片尺寸重新计算图片位置 x = startLeft + (startW -imgW)/2; y = startTop + (startH -imgH)/2; /* cxt.clearRect(x,y,width,height); 清除canvas原先的画面 */ cxt.clearRect(0,0,c.width,c.height); cxt.drawImage(img,x,y,imgW,imgH); } }); /* 单指拖拽图片移动 */ drag({ el: c, start: function(){ isDrag = true; startLeft = x; startTop = y; }, move: function(e){ if(isDrag){ x = startLeft + e.disPoint.x; y = startTop + e.disPoint.y; cxt.clearRect(0,0,c.width,c.height); cxt.drawImage(img,x,y,imgW,imgH); } }, end: function(e){ } }); /* 单指拖拽选框移动 */ var select = document.querySelector('#select'); css(select,"translateX",(page[1].clientWidth - select.offsetWidth)/2); css(select,"translateY",(page[1].clientHeight - select.offsetHeight)/2); var startSelect = {}; var isResize = false; drag({ el:select, start: function(){ if(isResize){ isSelectDrag = false; return; } isSelectDrag = true; startSelect = { x: css(this, "translateX"), y: css(this, "translateY") } }, move: function(e){ if(!isSelectDrag){ return; } css(this, "translateX",startSelect.x + e.disPoint.x); css(this, "translateY",startSelect.y + e.disPoint.y); }, end: function(){ } }); /* 单指拖拽选框周边,改变选框的大小 */ /* 左上角拖拽 1. 拿到手指移动的距离 2. 元素start时的宽高 - 手指移动距离 = 元素当前的宽高 3. 元素当前的位置 4. 最一个最小值限制 */ var leftTop = document.querySelector('.left-top'); drag({ el:leftTop, start: function(){ isResize = true; startSelect = { x: css(select,"translateX"), y: css(select,"translateY"), w: css(select,"width"), h: css(select,"height") }; }, move: function(e){ var width = startSelect.w - e.disPoint.x; var height = startSelect.h - e.disPoint.y; if(width > minW){ css(select,"width",width); css(select,"translateX",startSelect.x + e.disPoint.x); } if(height > minH){ css(select,"height",height); css(select,"translateY",startSelect.y + e.disPoint.y); } }, end: function(){ isResize = false; } }); /* 右上角 */ var rightTop = document.querySelector('.right-top'); drag({ el:rightTop, start: function(){ isResize = true; startSelect = { y: css(select,"translateY"), w: css(select,"width"), h: css(select,"height") }; }, move: function(e){ var width = startSelect.w + e.disPoint.x; var height = startSelect.h - e.disPoint.y; if(width > minW){ css(select,"width",width); } if(height > minH){ css(select,"height",height); css(select,"translateY",startSelect.y + e.disPoint.y); } }, end: function(){ isResize = false; } }); /* 右下角 */ var rightBottom = document.querySelector('.right-bottom'); drag({ el:rightBottom, start: function(){ isResize = true; startSelect = { w: css(select,"width"), h: css(select,"height") }; }, move: function(e){ var width = startSelect.w + e.disPoint.x; var height = startSelect.h + e.disPoint.y; if(width > minW){ css(select,"width",width); } if(height > minH){ css(select,"height",height); } }, end: function(){ isResize = false; } }); /* 左下角 */ var leftBottom = document.querySelector('.left-bottom'); drag({ el:leftBottom, start: function(){ isResize = true; startSelect = { x: css(select,"translateX"), w: css(select,"width"), h: css(select,"height") }; }, move: function(e){ var width = startSelect.w - e.disPoint.x; var height = startSelect.h + e.disPoint.y; if(width > minW){ css(select,"width",width); css(select,"translateX",startSelect.x + e.disPoint.x); } if(height > minH){ css(select,"height",height); } }, end: function(){ isResize = false; } }); }; page[1].className = "page"; }; reader.readAsDataURL(this.files[0]);//把文件读取成dataURI }; /* 点击保存按钮 裁切图片 1. 获取到选框对应的canvas中的画面的坐标以及大小 2. 利用canvas中的 dataImage,把对应的画面截取出来 3. 清空canvas,把截取的画面重新放入canvas 4. 生成dataUrl 5. 把dataUrl添加到img中 */ var saveBtn = document.querySelector('#saveBtn'); saveBtn.addEventListener('touchstart', function(e) { var img = document.querySelector('#img'); var rect = select.getBoundingClientRect(); //getImageData(x,y,w,h) 获取canvas中的画面 var imgData = cxt.getImageData(rect.left,rect.top,rect.width,rect.height); cxt.clearRect(0,0,c.width,c.height); //putImageData(imgData,x,y);向canvas中添加画面 c.width = rect.width; c.height = rect.height; cxt.putImageData(imgData,0,0); var url = c.toDataURL("image/png"); img.src = url; img.style.display = "block"; c.style.display = "none"; mask.style.display = "none"; select.style.display = "none"; //console.log(); }); img.addEventListener('touchstart', function(e) { e.stopPropagation(); }); })(); function drag(init){ var el = init.el; var isDrag = false; var startPoint = {};//手指按下时在页面中坐标 el.addEventListener('touchstart', function(e) { if(e.touches.length < 2){ isDrag = true; startPoint = { x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY }; init.start&&init.start.call(el,e); } }); el.addEventListener('touchmove', function(e) { if(e.touches.length < 2&&isDrag){ var nowPoint = { x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY }; e.disPoint = { x: nowPoint.x - startPoint.x, y: nowPoint.y - startPoint.y }; init.move&&init.move.call(el,e); } }); el.addEventListener('touchend', function(e) { if(isDrag){ isDrag = false; init.end&&init.end.call(el,e); } }); } function gesture(init){ var isGesture = false;//判断用户是否在进行多指操作 var el = init.el; var start = []; el.addEventListener('touchstart', function(e) { //e.touches 当前屏幕上手指列表 当手指个数>=2时认定用户在进行多指操作 if(e.touches.length >= 2){ isGesture = true; start[0] = { x:e.touches[0].pageX, y:e.touches[0].pageY }; start[1] = { x:e.touches[1].pageX, y:e.touches[1].pageY } init.start&&init.start.call(el,e); } }); el.addEventListener('touchmove', function(e) { //e.touches 当前屏幕上手指列表 if(e.touches.length >= 2&&isGesture){ var startDis = getDis(start[0],start[1]);//手指按下时两根手指之间的距离 var now = []; now[0] = { x:e.touches[0].pageX, y:e.touches[0].pageY }; now[1] = { x:e.touches[1].pageX, y:e.touches[1].pageY }; var nowDis = getDis(now[0],now[1]); e.scale = nowDis/startDis; init.change&&init.change.call(el,e); } }); el.addEventListener('touchend', function(e) { //e.touches 当前屏幕上手指列表 if(isGesture){ init.end&&init.end.call(el,e); } }); } //alert(Math.sqrt(100*100+100*100)); //计算两个坐标点之间的距离 function getDis(point,point2){ var x = point.x - point2.x; var y = point.y - point2.y; return Math.sqrt((x*x + y*y)); } </script> </body> </html>
转载请注明原文地址: https://www.6miu.com/read-56637.html

最新回复(0)