移动端图片上传裁切(版权归秒为所有,仅为搬运)
<!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. 生成dataUrl5. 把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>
移动端图片上传裁切(版权归秒为所有,仅为搬运)相关推荐
- php jquery ajax裁剪图照片,php+jquery+ajax无刷新图片上传裁切,模拟flash头像上传实例...
这几天自己在写一个cms.之前在用到图片上传裁切的时候总是用的flash的,或者是swfupload之类的.用的还不熟练,所以今天就用ajax做一个图片上传裁切的实例.个人感觉还不错,现在就分享出来. ...
- 移动端图片上传后进行压缩功能
移动端图片上传后进行压缩功能 在进行讲解上传图片压缩之前,我们先来了解下HTML5中的文件上传的基本知识点. 一: FileList对象与file对象. FileList对象表示用户选择的文件列表.在 ...
- vue移动端图片上传
一.服务端环境准备 本文服务端主要为nodejs,利用multer中间件完成图片上传功能.服务端安装express框架和multer. npm install express --save npm i ...
- php 图片压缩旋转,移动端图片上传旋转、压缩问题的解决方案
本篇文章就给大家带来移动端图片上传旋转.压缩问题的解决方案.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. 前言 在手机上通过网页 input 标签拍照上传图片,有一些手机会出现图片 ...
- JavaScript移动端图片上传方法
移动端图片上传方法 实现效果 文件下载 http://files.cnblogs.com/files/sntetwt/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%9B%BE%E7%8 ...
- php flash 图片上传,php+jquery+ajax无刷新图片上传裁切,模拟flash头像上传实例
这几天自己在写一个cms.之前在用到图片上传裁切的时候总是用的flash的,或者是swfupload之类的.用的还不熟练,所以今天就用ajax做一个图片上传裁切的实例.个人感觉还不错,现在就分享出来. ...
- 移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传
现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动端你不能去限制图片大小,让用户先处理图片再上传,这样不现实.所以理解的解决方案就是在上传先进行图片 ...
- 优化篇-“移动端”图片上传架构的变迁
做互联网应用少不了图片的支撑,图片的上传.浏览速度很大程度上决定着用户的体验,甚至用户去留,就因为其重要,所以,在任何时候,图片的架构和优化都在进行,不敢丝毫放松. 在以后几个章节,会从后端图片存储. ...
- Js 之移动端图片上传插件mbUploadify
一.下载 https://pan.baidu.com/s/1NEL4tkHoK4ydqdMi_hgWcw 提取码:vx7e 二.Demo示例 <div class="weui_uplo ...
最新文章
- linux下的CPU频率管理器
- Identity Mappings in Deep Residual Networks
- openwrt多wan限上下行速脚本,基于qosv4,imq模块替换成ifb模块[ZT]
- ERROR 1045 (28000): Access denied for user'root'@'localhost'(using password:YES)
- 2020牛客国庆集训派对day3 Leftbest
- 微信小程序蓝牙模块BLE开发说明基础知识
- 【Elasticsearch】Elasticsearch的IndexSorting:一种查询性能优化利器
- Mongo db 与mysql 语法比较
- 在Word 2007中轻松插入或创建表格
- 【PMP】PMBOK 笔记 第6章 项目时间管理
- ARP协议及欺骗原理
- 概率运算中C(k,n)是怎么算的啊? 比如C(6,3)等于几?怎么来的.
- linux下挂载光驱方法,Linux下光驱挂载技巧
- c语言编译产生随机数为什么,C语言 怎样产生随机数
- FLStudio 四分音符八分音符 四四拍四二拍
- 颜色混合BlendFunc用法实例总结
- judgement_mna_2016
- win10怎么找工作组计算机,win10无法查看工作组的解决方法|win10系统怎么找工作组...
- 多域名SSL证书是什么意思?
- linux riot密码,《lol手游》Riot拳头账号密码介绍 Ri...
热门文章
- tkinter treeview加入滚动条
- 《一条狗的回家路》观后感
- 用canvas画一个水滴形状的渐变进度条、控制条
- python抓取微信群消息怎么屏蔽_在微信好友信息抓取这一块,这才是最好的python分析技巧!...
- qq私聊顺序回复_如何利QQ群被动引精准流量?最快2小时成交变现?
- 干货|一文从0到1掌握用户画像知识体系
- hrbust2300 下雪了(hash)
- LeetCode784.字母大小写全排列 个人纪录2022.10.30
- class java.time.LocalDateTime cannot be cast to class java.util.Date
- 主设备号--驱动模块与设备节点联系的纽带