<!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>
移动端图片上传裁切(版权归秒为所有,仅为搬运)
最新推荐文章于 2022-11-01 18:33:11 发布